Как я могу увидеть точную командную строку, выполняемую внутри некоторого экземпляра bash?

У меня длинный экземпляр bash (внутри screen), который выполняет сложный набор команд внутри цикла (каждый цикл делает трубы, перенаправляет и т. д.).

Длинная командная строка была написана внутри терминала - она ​​не находится внутри какого-либо скрипта. Теперь я знаю идентификатор процесса bash, и у меня есть root-доступ - как я могу видеть, что точная командная строка выполняется внутри этого bash?

Пример
bash$ echo $$
1234
bash$ while true ; do \
    someThing | somethingElse 2>/foo/bar | \
    yetAnother ; sleep 600 ; done

И в другом экземпляре оболочки я хочу видеть, что командная строка выполняется внутри PID 1234:

bash$ echo $$
5678
bash$ su -
sh# cd /proc/1234
sh# # Do something here that will display the string  \
   'while true ; do someThing | somethingElse 2>/foo/bar | \
    yetAnother ; sleep 600 ; done'

Возможно ли это?

EDIT # 1

Добавление встречных примеров для некоторых ответов, которые у меня есть.

  1. Об использовании cmdline в разделе /proc/PID: это не работает, по крайней мере, не в моем сценарии. Вот простой пример:

    $ echo $$
    8909
    
    $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
    

    В другой оболочке:

    $ cat /proc/8909/cmdline
    bash
    
  2. Использование ps -p PID --noheaders -o cmd так же бесполезно:

    $ ps -p 8909 --no-headers -o cmd
    bash
    
  3. ps -eaf также не помогает:

    $ ps -eaf | grep 8909
    ttsiod    8909  8905  0 10:09 pts/0    00:00:00 bash
    ttsiod   30697  8909  0 10:22 pts/0    00:00:00 sleep 30
    ttsiod   31292 13928  0 10:23 pts/12   00:00:00 grep --color=auto 8909
    

    То есть, нет вывода командной строки ORIGINAL, что я и ищу - т.е. while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done.

28 голосов | спросил ttsiodras 3 +04002014-10-03T10:58:30+04:00312014bEurope/MoscowFri, 03 Oct 2014 10:58:30 +0400 2014, 10:58:30

3 ответа


39

Я знал, что хватаюсь за соломинку, но UNIX никогда не терпит неудачу!

Вот как мне это удалось:

bash$ gdb --pid 8909
...
Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libnss_files.so.2
0xb76e7424 in __kernel_vsyscall ()

Затем в приглашении (gdb) я запустил команду, call write_history("/tmp/foo"), который будет записывать эту историю в файл /tmp/foo.

(gdb) call write_history("/tmp/foo")
$1 = 0

Затем я отсоединяюсь от процесса.

(gdb) detach
Detaching from program: /bin/bash, process 8909

И закройте gdb.

(gdb) q

И конечно же ...

bash$ tail -1 /tmp/foo
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done

Для облегчения повторного использования в будущем я написал сценарий bash , автоматизируя процесс.

ответил ttsiodras 3 +04002014-10-03T12:13:09+04:00312014bEurope/MoscowFri, 03 Oct 2014 12:13:09 +0400 2014, 12:13:09
5

Поскольку команда все еще запущена на экране, ее родительский bash не перечитывал любую историю, поэтому:

  • повторное подключение к экрану
  • нажмите ^Z, затем up arrow
  • bonus: оберните команду в одинарные кавычки (перемещаясь с помощью ^A^A), потому что экран (1) - и ^E) и echo + перенаправить в файл
  • fg продолжить выполнение команды

Есть предостережения, но это довольно полезно в большинстве случаев.

ответил Lloeki 4 +04002014-10-04T12:55:18+04:00312014bEurope/MoscowSat, 04 Oct 2014 12:55:18 +0400 2014, 12:55:18
0

Я знаю, что вы нашли свой собственный ответ, но есть причина, по которой вы не можете сделать что-то вроде этого:

(set -x; for f in 1 2 3 4 ; do  echo "$f"; sleep $f; done)

Возможно, вы не можете согласовать вывод фактического задания и вывод из bash, показывающий текущую строку выполнения.

Кроме того, FWIW, если вы предпочитаете многословие, set -o xtrace.

ответил eggo 8 +04002014-10-08T00:27:16+04:00312014bEurope/MoscowWed, 08 Oct 2014 00:27:16 +0400 2014, 00:27:16

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132