Kirim perintah ke layar terpisah dan dapatkan hasilnya


12

Saya telah mencari untuk menemukan cara untuk mengirim perintah ke sesi layar terpisah. Sejauh ini baik. Inilah yang saya buat:

$ screen -S test -p 0 -X stuff 'command\n'

Perintah ini berfungsi sebagaimana mestinya. Tapi, saya juga ingin output dari itu, bergema langsung di depan mata saya (tidak perlu .logfile atau sesuatu, saya hanya ingin output).

Menggunakan screen -Lperintah, bukan opsi.


Kenapa harus begitu screen? Bukankah ini proses anak dibuat untuk apa?
Anko

Jawaban:


10

Gunakan pipa pertama keluar pertama:

mkfifo /tmp/test

Gunakan operator pengalihan. Redirect output perintah ke / tmp / test misalnya seperti ini:

screen -S test -p 0 -X stuff 'command >/tmp/test\n'

Kemudian di shell lain

tail -f /tmp/test.

Catatan Anda mungkin juga ingin mengarahkan ulang pesan kesalahan menggunakan operator 2> & 1 .

Contoh

Seperti yang diminta dalam komentar, mari kita asumsikan kita memiliki skrip php yang menerima input pengguna dan mencetak beban server pada input "status":

# cat test.php
<?php
  $fp=fopen("php://stdin","r");
  while($line=stream_get_line($fp,65535,"\n")) 
  {
    if ($line=="status") {echo "load is stub";} 
  } 
  fclose($fp);
?>

Anda membuat dua fifos:

 # mkfifo /tmp/fifoin /tmp/fifoout

Anda memanggil layar:

screen

Di konsol lain, sebut saja konsol 2 Anda mengetahui nama layar Anda:

# screen -ls
There is a screen on:
        8023.pts-3.tweedleburg  (Attached)
1 Socket in /var/run/screens/S-root.

Di konsol 2 Anda mengirim perintah ke layar:

 # screen -S 8023.pts-3.tweedleburg -p 0 -X stuff 'php test.php </tmp/fifoin >/tmp/fifoout\n'

Anda melihat perintah muncul di layar. Sekarang di konsol 2 Anda dapat mengirim perintah ke proses php Anda:

echo "status" >/tmp/fifoin

dan baca darinya:

# cat /tmp/fifoout
load is stub

1
Maaf, tapi ini tidak berhasil. Jika saya mengirim perintah ke creen seperti 'command> / tmp / test' prosesnya harus mendukung sintaks> / tmp / test ... Dan tidak.
Robin

Bagi saya ini berfungsi, harap dicatat bahwa saya meletakkan "test" sebagai nama layar Anda. Anda dapat mengetahui nama layar Anda dengan layar perintah -l. Juga, "perintah" harus diganti dengan perintah Anda yang sebenarnya, saya diuji dengan perintah ls. Juga, saya diuji dengan shell bash.
Thorsten Staerk

Saya tahu itu. Dan itu tidak berhasil. Misalnya, mulai skrip PHP di jendela layar, yang, misalnya, merespons perintah "status", yang mengembalikan beban server saat ini misalnya. Itulah yang saya coba lakukan.
Robin

maka Anda akan membutuhkan pipa dua arah, saya menambahkan ini ke jawaban saya
Thorsten Staerk

6

Saya memiliki skrip python yang melacak banyak sesi layar terpisah dan menangkap output dari masing-masing (ketika perintah pemanfaatan seperti gratis, -bn2 atas, iostat secara berkala dikirim melalui 'barang').

Alih-alih mengarahkan ke file dan, dengan demikian, mengelola setidaknya satu file per sesi layar terpisah ... Saya hanya mengarahkan ke tty / pts apa pun yang digunakan sesi orang tua saya.

Langkah # 1: Mulai sesi layar baru (dengan nama yang dapat dibaca manusia) dalam mode terpisah.

$ screen -dmS chad 

Langkah # 2: Kirim perintah Anda (saya akan menggunakan perintah 'free -g' bersama dengan 'uname -r') melalui barang. Penting untuk menentukan jendela yang ingin Anda gunakan (dalam kasus kami, jendela pertama dan satu-satunya) dengan -p.

$ screen -r chad -p0 -X stuff "free -g; uname -r" 

Langkah # 3: Langkah di atas hanya mengirim teks perintah. Kita juga perlu mengirim carriage return ke sesi layar terpisah ini agar shell menjalankan perintah kita. Karakter ASCII 015 adalah carriage return pada kebanyakan sistem * nix.

$ screen -r chad -p0 -X eval "stuff \015"

Langkah # 4: Mengarahkan output sesi layar terpisah kami ke tty / pts kami saat ini:

$ screen -r chad -p0 -X hardcopy $(tty)

Output dari Langkah # 4 akan terlihat seperti ini:

$ free -g; uname -r
             total       used       free     shared    buffers     cached
Mem:             7          1          6          0          0          0
-/+ buffers/cache:          0          7
Swap:            1          0          1
2.6.32-358.el6.x86_64

Meskipun ini tampaknya sedikit terlibat, prosesnya mudah skrip. Dengan python, saya dapat mengurai output dari Langkah # 4 dan hanya menangkap data yang saya pedulikan.

Memilih skenario sederhana seperti mengambil detail IP, saya menulis contoh skrip untuk menunjukkan konsep di atas. Jangan ragu untuk mengganti dan mengotak-atik sesuai keinginan Anda.

Contoh skrip python untuk mendapatkan detail IP dari sesi layar terpisah:

#!/usr/bin/python

import pexpect, time

#spawn a new bash session
session = pexpect.spawn('/bin/bash')
#send screen commands
session.sendline('screen -dmS netIP')
session.sendline('screen -r netIP -p0 -X stuff "ifconfig eth0 | grep -v eth0 | head -1"')
session.sendline('screen -r netIP -p0 -X eval "stuff \\015"')
#give the command a chance to execute before reading the output of our detached screen
time.sleep(0.1)

#use the output of the uname command as our string to expect
session.sendline('screen -r netIP -p0 -X hardcopy $(tty); $(uname)')
session.expect('Linux')

#parse the output - only concerned with the 'inet' line
output = session.before.split('\n')
for o in output:
    if 'inet' in o:
        print o

#kill the screen
session.sendline('screen -r netIP -p0 -X quit')
time.sleep(0.1)

session.close()

Skrip di atas beraksi:

$ python screen-output-test.py 
      inet addr:192.168.1.201  Bcast:192.168.1.255  Mask:255.255.255.0

Saya suka jawaban ini jauh lebih baik daripada yang diterima, karena tidak bergantung pada layar berada dalam keadaan "shell prompt", tetapi bekerja dengan apa pun yang berjalan di layar itu juga.
Guntram Blohm mendukung Monica

Namun, itu membutuhkan output agar pas di layar. Saya menemukan screen -X logfile /tmp/something; screen -X log on; screen -X stuff "command param"; screen -X log offuntuk bekerja lebih baik dalam skenario itu.
Guntram Blohm mendukung Monica

-1
screen -S myscreen

screen -R myscreen -X exec command

Contoh:

screen -R myscreen -X exec top
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.