Bagaimana saya tahu jika suatu perintah sedang berjalan atau menunggu input pengguna?

14

Pada baris perintah, saya mengetik perintah dan tekan enter. Itu tidak menghasilkan apa-apa. Bagaimana saya tahu apakah itu berjalan dan belum menghasilkan, atau meminta input pengguna?

Gqqnbig
sumber
Jika sedang menunggu maka Anda tidak akan mendapatkan PS1prompt.
Prvt_Yadav
1. Tolong beri tahu kami program mana (diam), dan kami dapat memberi Anda saran yang lebih tepat tentang apa yang diharapkan dan bagaimana memeriksanya; 2. Apakah Anda ingin mendapat peringatan, ketika program akhirnya meminta input atau telah selesai (sehingga ada sesuatu yang ditulis ke jendela terminal?
sudodus
jika ada input yang diharapkan saya akan berasumsi Anda mendapatkan prompt dengan pesan di depannya meminta input.
Rinzwind
5
@Rinzwind - Itu anggapan yang buruk. Contoh tandingan pertama yang ada dalam pikiran adalah catperintah. Cukup ketik catsendiri dan akan menunggu input dari stdin, tetapi tidak memberikan prompt. Banyak perintah lain berperilaku serupa karena mereka mengharapkan input baik dari stdin atau file, tetapi tidak membedakan antara sumber input yang berbeda (terminal interaktif, pipa, file ...).
Dave Sherohman

Jawaban:

15

Ada beberapa pendekatan:

  1. Coba beri tanda akhir input : Tanpa hak superuser, sulit untuk mengetahui apa yang terjadi di balik tudung. Yang bisa dilakukan adalah menekan Ctrl+ d. Terminal dan utilitas dalam mode kanonik mengirim semua teks yang tersedia ke read()syscall setelah menerima sinyal EOT terikat pada kombinasi tombol ini, dan jika tidak ada input - read()mengembalikan status keluar negatif yang sebagian besar utilitas menerima sebagai sinyal untuk keluar. Oleh karena itu, jika sebuah utilitas menunggu input, ia akan keluar setelah menerima kombinasi tombol. Jika tidak, utilitas dapat menjalankan tugas atau tidak ditulis dengan benar.

  2. Memata-matai syscalls : Jika Anda memiliki hak pengguna super, Anda dapat menjalankan stracedi terminal lain untuk melihat apa yang sedang dilakukan. Untuk itu Anda perlu mengetahui PID dari program tersebut. Misalnya, dalam tab terminal lain pgrep -f firefoxyang menjalankan 1234 sebagai contoh lalu sudo strace -f -p 1234. Jika output yang Anda lihat macet di read()syscall, itu berarti perintah mungkin sedang menunggu input. Jika tidak, jika Anda melihat syscalls berjalan, maka perintah melakukan sesuatu yang lain. Lihat pertanyaan terkait untuk penggunaan straceuntuk juga mencari tahu apakah perintah lama telah keluar.

  3. Gunakan metode perintah sendiri : Antara lain, utilitas seperti ddsinyal penggunaan. Misalnya, jika Anda menggunakan kill -USR1 1234(di mana 1234 adalah PID dari ddperintah yang sedang berjalan ), itu akan mencetak untuk stdout jumlah byte yang sedang diproses. Tentu saja, ini membutuhkan pengetahuan tentang perilaku perintah seperti itu di tempat pertama. Dua metode di atas lebih umum, dan tidak memerlukan pengetahuan mendalam tentang perilaku masing-masing perintah (meskipun itu selalu terbaik untuk mengetahui apa yang sebenarnya Anda jalankan - jika tidak, Anda berisiko menjalankan perintah yang dapat merusak).

Sergiy Kolodyazhnyy
sumber
+1. Terima kasih untuk stracemetodenya :-) Tetapi metode yang lebih sederhana juga berguna (umum atau spesifik untuk setiap program). Beberapa dari mereka bekerja tanpa hak pengguna super. Contoh: periksa apakah ddmelakukan sesuatu dan periksa mengapa grep --color asdfmenunggu diam-diam.
sudodus
@sudodus Ah, pengingat yang baik tentang ddsaya akan menambahkan yang itu.
Sergiy Kolodyazhnyy
Anda tidak perlu hak superuser untuk men-debug proses yang dimiliki oleh pengguna Anda. Nah, kecuali Anda belum mengatur sistem dengan tepat .
Ruslan
6

Bagaimana cara mengetahui apakah suatu program sedang berjalan atau menginginkan input pengguna

Itu tergantung pada program dan bagaimana Anda memintanya.

  • Seringkali tetapi tidak selalu akan ada prompt, yang menunjukkan bahwa program meminta masukan.

  • Jika Anda tidak yakin, Anda dapat memeriksa apakah proses program sedang sibuk

    • menggunakan CPU - use topatauhtop

    • membaca atau menulis - gunakan sudo iotop -o

  • Dan ketika program telah selesai, Anda akan melihat prompt shell.

Shellscript running

Saya memiliki shellscript yang memeriksa apakah suatu program sedang berjalan, dan sekarang saya telah menambahkan opsi -suntuk membuatnya berjalan sudo strace -f -p <PID>(sesuai dengan jawaban Sergiy Kolodyazhnyy) ketika sebuah ... ditemukan.

Shellscript menggunakan

  • ps -ef untuk menemukan sebagian besar program
  • systemctl is-active --quiet untuk menemukan beberapa program
  • dan jika Anda ingin stracedi xtermjendela.

    Instal xtermjika Anda ingin menggunakan straceuntuk menonton aktivitas suatu program.

Pemakaian

$ ./running
Usage:    ./running <program-name>
          ./running <part of program name>
Examples: ./running firefox
          ./running term                     # part of program name
          ./running dbus
          ./running 'dbus-daemon --session'  # words with quotes
          ./running -v term                  # verbose output
          ./running -s term                  # strace checks activity

Anda dapat menginstal shellscript runningke direktori PATHjika Anda ingin akses mudah ke sana.

Kode shellscript

#!/bin/bash

# date        sign     comment
# 2019-02-14  sudodus  version 1.0

verbose=false
strace=false
if [ "$1" == "-v" ]
then
 verbose=true
 shift
fi
if [ "$1" == "-s" ]
then
 strace=true
 shift
fi

if [ $# -ne 1 ]
then
 echo "Usage:    $0 <program-name>
          $0 <part of program name>
Examples: $0 firefox
          $0 term                     # part of program name
          $0 dbus
          $0 'dbus-daemon --session'  # words with quotes
          $0 -v term                  # verbose output
          $0 -s term                  # strace checks activity"
 exit
fi

inversvid="\0033[7m"
resetvid="\0033[0m"
redback="\0033[1;37;41m"
greenback="\0033[1;37;42m"
blueback="\0033[1;37;44m"

runn=false
#tmpfil=$(mktemp)
tmpdir=$(mktemp -d)
tmpfil="$tmpdir/tmpfil"
vtfile="$tmpdir/vtfile"
vthead="$tmpdir/vthead"

# check by systemctl

systemctl is-active --quiet "$1"
if [ $? -eq 0 ]
then
 echo "systemctl is-active:"
 runn=true
fi

# check by ps

ps -ef | tr -s ' ' ' ' | cut -d ' ' -f 8- | grep "$1" | grep -vE -e "$0 *$1" -e "$0 *.* *$1" -e "grep $1" | sort -u > "$tmpfil"
#cat "$tmpfil"
if $verbose || $strace
then
 ps -ef |head -n1 > "$vthead"
 ps -ef | grep "$1" | grep -vE -e "$0 *.* *$1" -e "grep $1" | sort -u > "$vtfile"
fi

tmpstr=$(head -n1 "$tmpfil")
#echo "tmpstr=$tmpstr"
tmpess=$(grep -om1 "$1" "$tmpfil")
#echo "tmpess=$tmpess"
if [ "$tmpstr" == "$1" ] || [ "${tmpstr##*/}" == "$1" ] || [ "${1##*/}" == "${0##*/}" ] || [ "$tmpess" == "$1" ]
then
 echo "ps -ef: active:"
 runn=true
 if $verbose
 then
  cat "$vthead" "$vtfile"
 fi
elif test -s "$tmpfil"
then
 if $runn
 then
  echo "----- consider also ------------------------------------------------------------"
  if $verbose
  then
   cat "$vthead" "$vtfile"
  else
   cat "$tmpfil"
  fi
  echo "--------------------------------------------------------------------------------"
 else
  echo "----- try with: ----------------------------------------------------------------"
  if $verbose
  then
   cat "$vthead" "$vtfile"
  else
   cat "$tmpfil"
  fi
  echo "--------------------------------------------------------------------------------"
 fi
fi

if $runn
then
 echo -en "$greenback '$1"
 if [ "$tmpstr" != "$tmpess" ]
 then
  echo -n " ..."
 fi
 echo -e "' is running $resetvid"

 if $strace
 then
  which xterm
  if [ $? -eq 0 ]
  then
   pid=$(head -n1 "$vtfile" | sed 's/^ *//' | tr -s ' ' '\t' | cut -f 2)
   echo "checking pid=$pid; quit with 'ctrl + c' in the xterm window"
   xterm -title "'strace' checks '$1'" 2> /dev/null -e sudo strace -f -p $pid
  else
   echo "Please install 'xterm' for this function to work"
   exit
  fi
 fi
else
 inpath=$(which "$1")
 if [ "$inpath" == "" ]
 then
  echo -e "$redback no path found to '$1' $resetvid"
 else
  echo -e "$blueback '$1' is not running $resetvid"
 fi
fi
rm -r "$tmpdir"

Demo

Memeriksa terminal windows di Lubuntu (LXTerminal dimulai sebagai x-terminal-emulatordan custom gnome-terminalwindows),

$ running -v -s term 
----- try with: ----------------------------------------------------------------
UID        PID  PPID  C STIME TTY          TIME CMD
sudodus   2087  1384  0 13:33 ?        00:00:00 x-terminal-emulator
sudodus   2108  1269  0 13:33 ?        00:00:17 /usr/lib/gnome-terminal/gnome-terminal-server
--------------------------------------------------------------------------------
 no path found to 'term' 

$ running -v -s x-terminal-emulator
ps -ef: active:
UID        PID  PPID  C STIME TTY          TIME CMD
sudodus   2087  1384  0 13:33 ?        00:00:00 x-terminal-emulator
 'x-terminal-emulator' is running 
/usr/bin/xterm
checking pid=2087; quit with 'ctrl + c' in the xterm window

Ada banyak aktivitas segera setelah kursor berada di jendela terminal.

masukkan deskripsi gambar di sini

Mulai grep(menunggu input dari /dev/stdin)

$ grep -i --color 'hello'
asdf
Hello World    
Hello World

Memeriksanya

$ running -s grep
ps -ef: active:
 'grep ...' is running 
/usr/bin/xterm
checking pid=14982; quit with 'ctrl + c' in the xterm window

Tidak banyak kegiatan, dan Anda dapat mengidentifikasi apa yang terjadi.

masukkan deskripsi gambar di sini

sudodus
sumber
Disebutkan dengan baik iotop, meskipun penggunaan CPU mungkin tidak selalu menjadi indikator jika suatu proses sedang sibuk. Program yang ditulis dalam C dan dioptimalkan mungkin menggunakan CPU minimal. Beberapa indikator yang saya tulis dengan Python menjadwalkan tugas yang berulang untuk dijalankan, jadi mungkin menggunakan CPU untuk memperbarui menu indikator untuk sesaat dan kemudian hanya duduk di sana.
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy, Ya, Anda benar tentang itu. The stracemetode adalah lebih baik, tapi mungkin tidak diperlukan atau tidak tersedia.
sudodus
Sepakat. Saya tidak berpikir itu sudah diinstal dengan Ubuntu, dan mungkin berlebihan.
Sergiy Kolodyazhnyy
1

Tidak yakin apakah Anda masih membutuhkan ini, tetapi masih ada trik yang berguna untuk diketahui: jika program tampaknya keluar tanpa output apa pun, Anda dapat memeriksa apakah program berjalan di latar belakang dengan menjalankan

ps -efa | grep "program_name"

Bersulang!

Marcel Ferrari
sumber
1

Jika Anda menjalankan shell di terminal, misalnya emulator terminal atau sesi ssh biasa, shell Anda hampir pasti telah mengaktifkan kontrol pekerjaan. Ini membuat mendapatkan jawaban untuk pertanyaan Anda sangat mudah dalam banyak kasus.

Ketik Ctrl+Zuntuk menunda proses dan kemudian bgmelanjutkannya di latar belakang, kemudian ketik baris kosong ke shell sehingga akan memeriksa apakah program dihentikan oleh sinyal.

Jika proses mencoba membaca dari terminal, ia akan segera mendapatkan SIGTTINsinyal dan akan ditangguhkan. (Ketika kontrol pekerjaan diaktifkan, sistem hanya memungkinkan satu proses pada satu waktu untuk membaca dari terminal.) Shell akan melaporkan ini. Anda kemudian dapat mengetik fguntuk melanjutkan proses di latar depan, dan kemudian ketik input untuk dibaca oleh program seperti biasa.

mp@ubuntu:~$ sleep 30 # a program that is not reading from the terminal
^Z
[1]+  Stopped                 sleep 30
mp@ubuntu:~$ bg
[1]+ sleep 30 &
mp@ubuntu:~$ 
mp@ubuntu:~$ 


mp@ubuntu:~$ cat - # a program that is reading from the terminal
^Z
[1]+  Stopped                 cat -
mp@ubuntu:~$ bg
[1]+ cat - &
mp@ubuntu:~$ 
[1]+  Stopped                 cat -
mp@ubuntu:~$ jobs -l
[1]+  3503 Stopped (tty input)     cat -
mp@ubuntu:~$ fg
cat -
hi
hi

Beberapa program, seperti editor, akan menjebak atau mengabaikan sinyal yang dihasilkan oleh Ctrl+Zatau menempatkan terminal ke mode di mana karakter kontrol bahkan tidak menghasilkan sinyal. Anda harus menggunakan teknik yang lebih maju dalam hal ini, seperti menggunakan straceuntuk melihat apakah proses yang dilakukan read, select, poll, dll

Tandai Plotnick
sumber