Как я говорю, работает ли команда или ожидает ввода данных пользователем?

На командной строке я ввел команду и совершил нападки, входят. Это ничего не производит. Как я говорю, работает ли это и еще вывод, или это просит ввод данных пользователем?

14
задан 14 February 2019 в 01:27

5 ответов

Существует несколько подходов:

  1. Попробуйте сигнальный конец input:Without полномочий суперпользователя, трудно знать то, что продолжается под капотом. То, что может быть сделано, должно нажать Ctrl+d. Терминалы и утилиты в каноническом режиме отправляют весь доступный текст в read() syscall после получения сигнала EOT, связанного с этим сочетанием клавиш, и если нет никакого входа - read() отрицательный статус выхода возвратов, который большинство утилит принимает как сигнал выйти. Поэтому, если утилита будет ожидать входа, то это выйдет после получения сочетания клавиш. Иначе утилита является или выполняющимися задачами или не записана правильно.

  2. Шпионаж за syscalls:If, у Вас действительно есть полномочие суперпользователя, можно работать strace в другом терминале для наблюдения, что в настоящее время делается. Для этого необходимо узнать PID программы. Например, на другой терминальной выполненной вкладке pgrep -f firefox какой май 1234 как пример и затем sudo strace -f -p 1234. Если вывод, который Вы видите, застревает на read() syscall, это означает, что команда, вероятно, ожидает входа. Иначе, если Вы видите, что syscalls работает, затем управляете, делает что-то еще. Посмотрите связанный вопрос для использования strace также выяснять, вышла ли длительная команда.

  3. Используйте собственные методы команды: Среди прочего, такие утилиты как dd используйте сигналы. Например, если Вы используете kill -USR1 1234 (где 1234 является PID выполнения dd команда), это распечатает к stdout сумму байтов, в настоящее время обрабатываемых. Конечно, это требует знания о таком поведении команды во-первых. Вышеупомянутые два метода являются более общими, и не требуют глубоких знаний поведения каждой команды (хотя всегда лучше знать то, что Вы на самом деле выполняете - иначе Вы рискуете выполнять команду, которая может нанести ущерб).

15
ответ дан 23 November 2019 в 02:57

Как сказать, выполняет ли программа или желает ввод данных пользователем

Это зависит от программы и как Вы вызываете его.

  • Часто, но не всегда будет подсказка, которая указывает, что программа просит вход.

  • Если Вы не уверены, можно проверить, занят ли процесс программы

    • использование ЦП - использование top или htop

    • чтения или записи - использование sudo iotop -o

  • И когда программа закончилась, Вы будете видеть подсказку оболочки.

Сценарий оболочки running

У меня был сценарий оболочки, который проверяет, работает ли программа, и теперь я добавил опцию -s заставить его работать sudo strace -f -p <PID> (согласно ответу Sergiy Kolodyazhnyy), когда... найден.

Использование сценария оболочки

  • ps -ef найти большинство программ
  • systemctl is-active --quiet найти некоторые программы
  • и если Вы желаете strace в xterm окно.

    Установка xterm если Вы хотите использовать strace следить за действием программы.

Использование

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

Можно установить сценарий оболочки running в каталог в PATH если Вы хотите легкий доступ к нему.

Код сценария оболочки

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

Демонстрация

Проверка окон терминала в Lubuntu (LXTerminal, запущенный как x-terminal-emulator и пользовательский gnome-terminal окна),

$ 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

Существует большое действие, как только курсор находится в окне терминала.

enter image description here

Запуск grep (ожидающий входа от /dev/stdin)

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

Проверка его

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

Нет большого действия, и можно определить то, что происходит.

enter image description here

6
ответ дан 23 November 2019 в 02:57

Не уверенный, если Вам все еще нужно это, но все еще полезный прием для знания: если программа, кажется, выходит без вывода, можно проверить, работает ли это в фоне путем выполнения

ps -efa | grep "program_name"

Удачи!

1
ответ дан 23 November 2019 в 02:57

При выполнении оболочки в терминале, например, эмулятор терминала или типичная ssh сессия, оболочка почти наверняка включила управление заданиями. Это делает получение ответа на Ваш вопрос супер легким в большинстве случаев.

Введите Ctrl+Z для приостановки процесса и затем bg для продолжения его в фоновом режиме затем введите пустую строку к оболочке, таким образом, это проверит, зашли ли в программу сигнал.

Если процесс попытается читать из терминала, то это сразу получит a SIGTTIN предупредите и будет приостановлен. (Когда управление заданиями включено, система позволяет только одному процессу за один раз читать из терминала.) Оболочка сообщит об этом. Можно затем ввести fg продолжать процесс на переднем плане и затем вводить вход, который будет считан программой как нормальный.

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

Некоторые программы, такие как редакторы, или захватят или проигнорируют сигнал, сгенерированный Ctrl+Z или помещать терминал в режим, где управляющие символы даже не генерируют сигналы. Необходимо будет использовать более усовершенствованные методы в этом случае, такие как использование strace видеть, делает ли процесс read, select, poll, и т.д.

1
ответ дан 23 November 2019 в 02:57

Почему бы просто не посмотреть на столбец S (Состояние) верхней команды. Если ваша программа ожидает ввода, велика вероятность того, что она находится в спящем режиме и не работает, что означает, что top выведет S (на этот раз для Sleeping), а не R (для Running). Попробуйте эту команду в качестве примера:

top -b -n 1 | sed -n '7,12p' | awk '{printf "%6s %-10s %-4s %-s\n",$1,$2,$8,$NF}'

0
ответ дан 23 April 2020 в 10:13

Другие вопросы по тегам:

Похожие вопросы: