Bir komutun çalıştığını veya kullanıcı girdisini beklediğini nasıl anlarım?


14

Komut satırına bir komut yazdım ve enter tuşuna bastım. Hiçbir şey çıkarmaz. Çalışıyor ve henüz çıktı almıyor mu, yoksa kullanıcı girişi mi istediğini nasıl anlarım?


Eğer bekliyorsanız, PS1istem almazsınız .
Prvt_Yadav

1. Lütfen hangi programın (sessiz) olduğunu söyleyin, size ne bekleyebileceğiniz ve nasıl kontrol edeceğiniz konusunda daha kesin tavsiyeler verebiliriz; 2. Program sonunda giriş istediğinde veya bittiğinde (terminal penceresine bir şey yazılması için) bir uyarı almak ister misiniz?
sudodus

beklenen bir giriş varsa, önünde giriş isteyen bir mesaj ile bir istem alırsınız varsayalım.
Rinzwind

5
@Rinzwind - Bu zayıf bir varsayım. İlk akla gelen örnek catkomut. Sadece catkendi başına yazın ve stdin'den girdi bekler, ancak hiçbir istem vermez. Diğer birçok komut benzer şekilde davranır çünkü stdin veya dosyadan girdi beklerler, ancak farklı giriş kaynakları (etkileşimli terminal, kanal, dosya ...) arasında ayrım yapmazlar.
Dave Sherohman

Yanıtlar:


15

Birkaç yaklaşım var:

  1. Giriş sonu sinyalini vermeyi deneyin : Süper kullanıcı ayrıcalıkları olmadan, kaputun altında neler olup bittiğini bilmek zor. Yapılması gereken Ctrl+ tuşuna basmaktır d. Standart moddaki terminaller ve yardımcı programlar, read()bu tuş kombinasyonuna bağlı EOT sinyali alındığında mevcut tüm metni sistem çağrısına gönderir ve giriş yoksa, read()çoğu yardımcı programın çıkmak için sinyal olarak kabul ettiği negatif çıkış durumunu döndürür. Bu nedenle, bir yardımcı program giriş bekliyorsa, tuş bileşimini aldıktan sonra çıkacaktır. Aksi takdirde, yardımcı program görevleri çalıştırıyor veya düzgün yazılmamış.

  2. Sistem çağrılarını gözetleme : Süper kullanıcı ayrıcalığına sahipseniz strace, şu anda ne yapıldığını görmek için başka bir terminalde çalışabilirsiniz . Bunun için programın PID'sini bulmanız gerekir. Örneğin, başka bir terminal sekmesinde pgrep -f firefox, örneğin 1234 ve daha sonra çalışabilir sudo strace -f -p 1234. Gördüğünüz çıkış read()sistem çağrısına yapışmışsa , komutun muhtemelen girişi beklediği anlamına gelir. Aksi takdirde, sistem çağrılarının çalıştığını görürseniz, komut başka bir şey yapıyor demektir. Uzun süren komutun çıkıp çıkmadığını da anlamak için ilgili soruya bakın strace.

  3. Komutun kendi yöntemlerini kullanın : Diğer şeylerin yanı sıra, ddkullanım sinyalleri gibi yardımcı programlar . Örneğin, kill -USR1 1234(burada 1234 çalışmakta olan ddkomutun PID'sini) kullanırsanız, o anda işlenen bayt miktarını belirlemek için yazdırılır. Tabii ki, bu ilk başta komutun bu tür davranışları hakkında bilgi sahibi olmayı gerektirir. Yukarıdaki iki yöntem daha geneldir ve her komutun davranışı hakkında derin bilgi gerektirmez (aslında ne yürüttüğünüzü bilmek her zaman en iyisidir - aksi takdirde hasar verebilecek bir komutu çalıştırma riskiniz vardır).


+1. straceYöntem için teşekkürler :-) Ancak daha basit yöntemler de yararlıdır (her program için genel veya spesifik). Bazıları süper kullanıcı ayrıcalıkları olmadan çalışır. Örnekler: bir ddşey yapıp yapmadığını ve neden grep --color asdfsessizce beklediğini kontrol edin .
sudodus

@sudodus Ah, ddbunu ekleyeceğim hakkında iyi bir hatırlatma .
Sergiy Kolodyazhnyy

Kullanıcının sahip olduğu bir işlemde hata ayıklamak için süper kullanıcı ayrıcalıklarına ihtiyacınız yoktur. Eh, değil sürece uygun sistem kurmak .
Ruslan

6

Bir programın çalışıp çalışmadığını veya kullanıcı girişi isteyip istemediğini belirleme

Programa ve onu nasıl çağırdığınıza bağlıdır.

  • Genellikle ancak her zaman değil, programın giriş istediğini belirten bir istem olacaktır.

  • Emin değilseniz, programın işleminin meşgul olup olmadığını kontrol edebilirsiniz

    • CPU kullanıyor - topveyahtop

    • okur veya yazar - kullan sudo iotop -o

  • Ve program bittiğinde, kabuğun istemini göreceksiniz.

shellscript running

Bir program çalışıp çalışmadığını kontrol eden bir shellscript vardı ve şimdi bir ... bulunduğunda (Sergiy Kolodyazhnyy'nin cevabına göre) -sçalıştırmak için seçeneği ekledim sudo strace -f -p <PID>.

Shellscript kullanır

  • ps -ef programların çoğunu bulmak
  • systemctl is-active --quiet bazı programları bulmak için
  • ve stracebir xtermpencerede isterseniz .

    Bir programın etkinliğini izlemek xtermiçin kullanmak istiyorsanız yükleyin strace.

kullanım

$ ./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

Eğer kolay erişim istiyorsanız shellscript'i runningbir dizine kurabilirsiniz PATH.

Shellscript kodu

#!/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"

gösteri

Lubuntu'daki terminal pencerelerini kontrol etme (LXTerminal olarak başlatıldı x-terminal-emulatorve özel gnome-terminalpencereler),

$ 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

Orada bir sürü imleç terminal penceresinde olduğu gibi aktivitenin en kısa sürede.

resim açıklamasını buraya girin

Başlangıç grep(giriş bekleniyor /dev/stdin)

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

Kontrol ediliyor

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

Çok fazla aktivite yok ve neler olduğunu tanımlayabilirsiniz.

resim açıklamasını buraya girin


İşlemden iotopmeşgulse CPU kullanımı mutlaka bir gösterge olmayabilir. C ile yazılmış ve optimize edilmiş bir program minimum CPU kullanıyor olabilir. Python'da yazdığım bazı göstergeler çalıştırmak için tekrarlanan bir görev zamanlar, bu nedenle gösterge menüsünü kısa bir süre güncellemek için CPU'yu kullanabilir ve sadece orada oturur.
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy, Evet, bu konuda haklısın. straceYöntem belki gerekli değildir ya mevcut değil daha iyi, ama.
sudodus

Kabul. Ubuntu ile önceden kurulmuş olarak geldiğini düşünmüyorum ve aşırıya kaçmış olabilir.
Sergiy Kolodyazhnyy

1

Hala buna ihtiyacınız olup olmadığından emin değilsiniz, ancak hala bilmek için yararlı bir hile: program herhangi bir çıktı olmadan çıkmış gibi görünüyorsa, çalıştırarak arka planda çalışıp çalışmadığını kontrol edebilirsiniz

ps -efa | grep "program_name"

Şerefe!


1

Kabuğu bir terminalde, örneğin bir terminal emülatöründe veya tipik bir ssh oturumunda çalıştırıyorsanız, kabuğunuz neredeyse kesinlikle iş denetimini etkinleştirmiştir. Bu, çoğu durumda sorunuzun yanıtını süper kolay hale getirir.

Tür Ctrl+Zardından süreci askıya ve bgbu programın bir sinyal durdurdu olmadığını kontrol edeceğiz öyleyse, arka planda devam kabuğuna boş bir satır yazın.

İşlem terminalden okumaya çalışıyorsa, hemen bir SIGTTINsinyal alacak ve askıya alınacaktır. (İş kontrolü etkinleştirildiğinde, sistem terminalden her seferinde sadece bir işleme izin verir.) Kabuk bunu bildirir. Daha sonra fgişleme ön planda devam etmek için yazabilir ve ardından program tarafından normal olarak okunacak girdiyi yazabilirsiniz.

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

Editörler gibi bazı programlar, Ctrl+Zterminal tarafından üretilen sinyali yakalar veya yoksayar veya terminali kontrol karakterlerinin sinyal üretmediği bir moda sokar. Böyle kullanılması gibi bu durumda daha gelişmiş teknikleri kullanmak gerekir stracesüreç performans gösterip göstermediğini görmek için read, select, pollvb

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.