Sejauh yang saya mengerti jika saya mengetik berikut ...
python -i
... python-interpreter sekarang akan membaca dari stdin, berperilaku (jelas) seperti ini:
>>> print "Hello"
Hello
Saya berharap itu melakukan hal yang sama jika saya melakukan ini:
echo 'print "Hello"' > /proc/$(pidof python)/fd/0
Tapi ini outputnya (dengan garis kosong yang sebenarnya):
>>> print "Hello"
<empyline>
Bagi saya ini terlihat seperti, hanya butuh print "Hello"\n
dan menulisnya stdout
, tetapi tidak menafsirkannya. Mengapa itu tidak berhasil dan apa yang harus saya lakukan untuk membuatnya bekerja?
proc
file-descriptors
Sheppy
sumber
sumber
Jawaban:
Mengirim masukan ke shell / juru bahasa dengan cara ini sangat rawan masalah dan sangat sulit untuk bekerja dengan cara yang dapat diandalkan.
Cara yang tepat adalah dengan menggunakan soket, ini sebabnya mereka diciptakan, Anda dapat melakukan ini di command line menggunakan
ncat
nc
atausocat
untuk mengikat proses python ke soket sederhana. Atau tulis aplikasi python sederhana yang mengikat ke port dan mendengarkan perintah untuk menafsirkan pada soket.soket bisa lokal dan tidak terpapar ke antarmuka web apa pun.
Masalahnya adalah bahwa jika Anda mulai
python
dari baris perintah, biasanya dilampirkan ke shell Anda yang terpasang ke terminal, pada kenyataannya kita bisa melihatjadi ketika Anda menulis ke
stdin
python, Anda sebenarnya menulis kepty
terminal psuedo, yang merupakan perangkat kernel, bukan file sederhana. Ini menggunakanioctl
tidakread
danwrite
, jadi Anda akan melihat output di layar Anda, tetapi tidak akan dikirim ke proses spawned (python
)Salah satu cara untuk meniru apa yang Anda coba adalah dengan
fifo
ataunamed pipe
.Anda juga dapat menggunakan
screen
input sajasumber
sleep 300 > python_i.pipe &
) sisi lain tidak akan menutup danpython
akan terus menerima perintah di bawah pipa. Tidak ada EOF yang dikirim olehecho
.|
pipa, benar?echo something > fifo
akan menyebabkannya mendapatkan EOF yang akan menghentikan banyak aplikasi. Thesleep infinity > fifo
solusi tidak menyeberangi pertengahan saya meskipun, terima kasih!python -i <> fifo
yang juga akan mencegah EOFMengakses tidak mengakses file deskriptor 0 dari proses PID , itu mengakses file yang PID telah dibuka pada file deskriptor 0. Ini adalah perbedaan yang halus, tetapi itu penting. Deskriptor file adalah koneksi yang dimiliki suatu proses ke file. Menulis ke deskriptor file menulis ke file terlepas dari bagaimana file telah dibuka.
/proc/PID/fd/0
Jika ini file biasa, menulis padanya memodifikasi file. Data belum tentu proses apa yang akan dibaca selanjutnya: itu tergantung pada posisi terlampir pada deskriptor file yang digunakan proses untuk membaca file. Ketika suatu proses terbuka , itu mendapatkan file yang sama dengan proses lainnya, tetapi posisi file independen.
/proc/PID/fd/0
/proc/PID/fd/0
Jika merupakan pipa, maka menulis ke dalamnya menambahkan data ke buffer pipa. Dalam hal ini, proses yang membaca dari pipa akan membaca data.
/proc/PID/fd/0
Jika adalah terminal, maka menulis kepadanya output data pada terminal. File terminal adalah dua arah: menulis kepadanya menghasilkan data, yaitu terminal menampilkan teks; membaca dari terminal input data, yaitu terminal mentransmisikan input pengguna.
/proc/PID/fd/0
Python membaca dan menulis ke terminal. Ketika Anda menjalankan
echo 'print "Hello"' > /proc/$(pidof python)/fd/0
, Anda sedang menulisprint "Hello"
ke terminal. Terminal ditampilkanprint "Hello"
sesuai instruksi. Proses python tidak melihat apa-apa, masih menunggu input.Jika Anda ingin memasukkan input ke proses Python, Anda harus meminta terminal untuk melakukannya. Lihat jawaban crasic untuk cara melakukan itu.
sumber
Membangun dari apa yang dikatakan Gilles , jika kita ingin menulis ke stdin proses yang melekat pada terminal, kita benar-benar perlu mengirim informasi ke terminal. Namun, karena terminal berfungsi sebagai bentuk input dan juga output, saat menulis ke terminal, tidak ada cara untuk mengetahui bahwa Anda ingin menulis ke proses yang berjalan di dalamnya daripada "layar".
Namun Linux memiliki cara non-posix untuk mensimulasikan input pengguna melalui permintaan ioctl yang disebut
TIOCSTI
(Terminal I / O Control - Simulasi Terminal Input) yang memungkinkan kita untuk mengirim karakter ke terminal seolah-olah mereka diketik oleh pengguna.Saya hanya secara dangkal menyadari bagaimana ini bekerja, tetapi berdasarkan jawaban ini , harus mungkin untuk melakukan ini dengan sesuatu di sepanjang garis
Beberapa sumber daya eksternal:
http://man7.org/linux/man-pages/man2/ioctl.2.html
http://man7.org/linux/man-pages/man2/ioctl_tty.2.html
sumber