Як переглянути результат запущеного процесу в іншому сеансі bash?


199

Я залишив сценарій, який працює на віддаленій машині, коли я працював на ньому. Я можу підключити SSH до машини як той самий користувач і побачити, як працює сценарій ps.

$ ps aux | grep ipcheck
myuser  18386  0.0  0.0  18460  3476 pts/0    S+   Dec14   1:11 /bin/bash ./ipchecker.sh

Це просто вихід на stdout на локальному сеансі (я запустив ./ipchecker.shформу вікна локального терміналу, немає перенаправлення, не використовуюсь screenтощо).

Чи все-таки з сеансу SSH я можу переглянути результат цієї запущеної команди (не зупиняючи її)?

Поки найкраще, що я знайшов, - це використовувати, strace -p 18386але я отримую орди тексту, що летить вгору по екрану, його занадто детально. Я можу зупинитися, straceа потім просіяти висновок і знайти текст, надрукований у stdout, але його дуже довгий і заплутаний, і, очевидно, поки він зупинений, я можу щось пропустити. Я хотів би знайти спосіб бачити вихідний сценарій в прямому ефірі так, ніби працюю на локальному рівні.

Чи може хтось покращити це? Очевидна відповідь - перезапустити скрипт з перенаправленням або на screenсеансі тощо. Це не критичний сценарій, тому я міг би це зробити. Швидше за все, я бачу це як втіху для навчання.


Чи працює ваш процес у віртуальній консолі чи в оточенні GUI / xterm?
джиппі

4
Ви можете обмежити вихід страйсу на один syscall:strace -p 4232 -e write
otokan

@jippie У машині працює повний графічний інтерфейс (Linux Mynt 13, робочий стіл XFCE), я запустив gnome-термінал.
jwbensley

3
На цьому сайті є щонайменше десяток подібних питань. Шукайте тут рептирій, щоб знайти декілька з них (і відповідь).
Стефан Шазелас

Відповіді:


180

Якщо ви хочете лише шпигувати за існуючим процесом, ви можете використовувати strace -p1234 -s9999 -e writeтам, де 1234 - ідентифікатор процесу. ( -s9999Позбавляє від рядка вкорочені до 32 символів, а writeсистемний виклик , який виробляє висновок.) Якщо ви хочете , щоб переглянути тільки дані , записані на певному дескриптора файлу, ви можете використовувати що - то подобається , strace -p1234 -e trace= -e write=3щоб бачити тільки дані , записані в файл з дескриптором 3 ( -e trace=дозволяє системі дзвінки з реєстрації). Це не дасть тобі вже виробленого результату.

Якщо висновок прокручується занадто швидко, ви можете lessпередати його в пейджер, наприклад , або надіслати його у файл strace -o trace.log ….

З багатьма програмами ви можете переадресувати наступний висновок за допомогою хакера ptrace, або до вашого поточного терміналу, або до нового екранного сеансу. Див. Як я можу відмовитись від запущеного процесу та пов’язати його з новою оболонкою екрана? та інші пов'язані нитки.

Зауважте, що залежно від налаштування вашої системи вам може знадобитися запустити всі ці straceкоманди як root, навіть якщо процес працює під користувачем без зайвих привілеїв. (Якщо процес працює як інший користувач або встановлений або встановлено жорсткість, вам потрібно буде запустити straceяк root.) Більшість дистрибутивів дозволяють лише процесу відстежувати своїх дітей (це забезпечує помірну перевагу для безпеки - це запобігає деякому прямому введенню зловмисного програмного забезпечення, але не перешкоджає непрямому введенню шляхом зміни файлів). Це контролюється kernel.yama.ptrace_scomesysctl.


18
Я не думаю, що існує спосіб звузити вихід до стандартного виходу ?
Йона

3
Чи можете ви пояснити всі аргументи?
Користувач

6
У великій кількості результатів, які я отримував від nodejs, було багато зворотних нахилів та цифр; Будь-які висновки щодо того, в якому кодуванні вони можуть бути? Було також багато простого тексту, який був усім, що мені було потрібно.
ThorSummoner

3
"Чи можете ви пояснити всі аргументи?" @User:man strace
Пістос

3
@RafaelMoni Програма для виконання того, що ви просите, називається налагоджувачем.
Жиль

139

Ви можете отримати доступ до виводу через procфайлову систему.

tail -f /proc/<pid>/fd/1

1= stdout, 2= stderr


7
Це дає мені: "не вдається відкрити / proc / <мій pid> / fd / 1 для читання: немає такого пристрою чи адреси".
Ярослав Нікітенко

18
так <мій pid> має бути ваш ідентифікатор процесу
tvlooy

29
Це не спрацює, якщо вихід збирається в tty (або переспрямований на /dev/null) - він працюватиме лише у випадку, якщо вихід буде переспрямований у файл.
mattdm

1
Тестовано на Ubuntu 16.04, і він не працює. У сеансі я роблю: ping google.esа в іншому як root: tail -f /proc/`pgrep ping`/fd/2і нічого не відображається.
david.perez

1
ти правий. Оскільки fd 1 і 2 є посиланнями на пристрій / dev / pts. Ви не можете встановити хвостовий пристрій -fa pts. Сплануйте свою команду ping як cronjob, а потім зробіть те ж саме. хвіст -f тоді працюватиме
tvlooy

9

У BSD ви можете використовувати, watchякі відслідковують заданий tty, наприклад

watch /dev/pts/0

У Linux це буде неможливо, якщо процес не запускався під мультиплексором до такого, як screenабо tmux. Дивіться також: Reptyr : приєднайте запущений процес до нового терміналу

Це , здається , єдиний спосіб для налагодження процесу (наприклад strace, dtrace/ dtruss, gdb, lldbі т.д.).

Оскільки ви використовували straceдля отримання будь-якого значущого виводу, вам потрібно відфільтрувати кваліфікований вираз (наприклад file), а потім проаналізувати вихід. Ось приклад:

strace -e trace=write -s1000 -fp 18386 2>&1 | grep -o '".\+[^"]"'

Що він робить, він друкує операцію запису процесу (довжина 1000), визначеного PID (використовуйте, pgrepщоб знайти його по імені), перенаправляє стандартну помилку у висновок (підлягає фільтруванню) та друкує рядок із подвійним цитуванням.

Якщо ви маєте справу з бінарним висновком, ви можете проаналізувати символи послідовності втечі, використовуючи read-r) і printf%b), наприклад

while read -r -t1 line; do printf "%b" $line; done

Перевірте help readнаявність параметрів (наприклад, -nдля друку після певної кількості символів, а не для нового рядка).

Ось більш повний приклад:

strace -e trace=write -s1000 -fp 18386 2>&1 \
| grep --line-buffered -o '".\+[^"]"' \
| grep --line-buffered -o '[^"]\+[^"]' \
| while read -r line; do
  printf "%b" $line;
done

Для прикладів, що використовують будь-який процес, будь ласка, перевірте: Як розібрати простір в оболонці до простого тексту? при stackoverflow


4
  1. Можливо, ви зможете зазирнути на віддалений екран, використовуючи те, ssh localhost 'DISPLAY=:0.0 xwd -root' | xwud -scaleде localhostйого слід замінити обліковими записами для входу на віддалений сервер та :0.0з номером відображення вашого графічного інтерфейсу.

  2. Використовуйте x11vnc, що є сервером VNC для вашого екранного X-сеансу.

  3. Під час роботи на одній із 6 віртуальних консолей спробуйте sudo setterm -dump 2 -file /dev/stdout, де ви замінили 2відповідний vc.


4

Я б радив зробити ім'я pipe ( mkfifo), а потім записати в цей файл. Потім читайте з нього. Ви завжди можете робити це з такими речами, як tailмінімізація виходу тощо. Щоразу, коли ви очищаєте трубу (читайте з неї), вона очищається, тому вихід не зберігається.

Іншим варіантом було б записати все у файл (подібно до логічного файлу), а потім проаналізувати його будь-коли. Це було б кращою дією, якщо ви хочете зберегти весь результат.


3

Ви завжди можете запустити процес, що не має ногу та &

nohup rsync source_file dest_file &

Тоді ви можете перевірити прогрес із будь-якого tty за допомогою:

tail -f nohup.out

Це добре працює для мене.


6
У цьому запитанні я розповів би про те, як переглянути результат запущеного сповіщення, а не як запустити процес у фоновому режимі, як підказує ваша відповідь
jwbensley

Насправді, ваше: nohup згадка просвіти мене! Дякую!
Нам Г ВУ

1

Дуже просто отримати результат - це захоплення вашого виводу у файл та введення цього файлу.

ЯКЩО РОБУ: ./ipcheck

ВСТАВИТИ ДО: ./ipcheck> [Замінити своє ім'я файла]

Це створило б вихідний файл, де знаходиться ваш сценарій. Тоді з будь-якої іншої оболонки bash ви можете просто зафіксувати файл:

хвостик [замінитиіменем вашого файла] -f


Перенаправлення файлів, як правило, використовує блокування на основі блоку за замовчуванням (див. setbuf(3)), Що може створити tailпроблему.
триг

5
Також це не допомагає в питанні, яке стосувалося перегляду результатів уже запущеного процесу, а не про те, як перенаправити stdout на новий процес.
jwbensley

1

Розбір виходу штриха:

Я використав верхню відповідь (з моїм ідентифікатором процесу 28223) ...

> sudo strace -p28223 -s9999 -e write
...
write(9, "Info\nI\nCare\nabout", 55) = 55
...

Щоб визначити, що мене хвилює write(9. (9 використовується нижче, це, мабуть, обробка файлів і може бути різною для вашого процесу.) Тоді я написав швидкий сценарій Ruby для розбору та їх відображення.

Вставте наступне в /usr/bin/parse_strace.rb

#!/usr/bin/ruby

num = ARGV[0]
STDIN.each { |line|
  if (line.match(/write\(#{ num },\s*"(.*?)"/)) then
    puts $1.split('\x').map { |s| s.to_i(16).chr }.join()
  end
}

Не забувайте chmod a+x /usr/bin/parse_strace.rb

Я викликаю strace -xx(виводить шістнадцятковий, тому регулярний вираз відповідає відповідним чином), трубопроводів (включаючи STDERR) до мого сценарію, 9як перший аргумент.

sudo sh -c 'strace -xx -p28223 -s9999 -e write 2>&1 | parse_strace.rb 9'

І, вуаля, він виводить оригінальний STDOUT процесу, нові рядки, колір та все!

Додавання до процесу STDOUT


0

ви не можете отримати ідентифікатор процесу та спілкуватися з ним з USR1,

$pgrep -l '^ipchecker.sh$'

який друкує PID вашого сценарію, потім використовуйте його

$ kill -USR1 PID

Я розумію, що USR1 - це "визначений користувачем" сигнал, тобто кожен, хто створив програму, може використовувати її для того, щоб означати "вимкнути" або "скинути свої журнали" або "надрукувати foo тисячу разів" або що завгодно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.