[unix] 일부 bash 인스턴스 내에서 정확한 명령 줄이 실행되고 있는지 어떻게 알 수 있습니까?

루프 내에서 복잡한 명령 집합을 실행 하는 오래 실행되는 bash인스턴스 ( screen세션 내부 )가 있습니다 (각 루프가 파이프, 리디렉션 등을 수행함).

긴 명령 줄은 터미널 안에 작성되었습니다. 스크립트 안에 없습니다. 이제 bash 프로세스 ID를 알고 있으며 루트 액세스 권한이 있습니다. 내에서 정확한 명령 행이 실행되는 것을 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'

이것이 가능한가?

편집 # 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. 즉, 내가 찾고있는 것 입니다.



답변

나는 빨대를 잡고 있다는 것을 알고 있었지만 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 스크립트를 작성했습니다 .


답변

명령이 여전히 화면에서 실행 중이므로 상위 bash는 히스토리를 다시 읽지 않았습니다.

  • 화면에 다시 부착
  • ^Z다음을 누르십시오up arrow
  • 보너스 : 명령을 작은 따옴표로 묶고 ( ^A^Ascreen-1 때문에-로 탐색 ^E) 파일에 echo + 리디렉션
  • fg 명령 실행을 추구

주의 사항이 있지만 이것은 대부분 유용합니다.


답변

나는 당신이 당신 자신의 대답을 찾았다는 것을 알고 있지만 다음과 같이 할 수없는 이유가 있습니다.

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

실제 작업의 출력과 현재 실행중인 행을 보여주는 bash의 출력을 함께 혼합 할 수는 없습니다.

또한 FWIW, 자세한 정보가 필요한 경우 set -o xtrace.


답변