루프 내에서 복잡한 명령 세트를 실행하는 장기 실행 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
내가 얻은 답변 중 일부에 반례를 추가합니다.
cmdline
under 사용과 관련하여/proc/PID
: 적어도 내 시나리오에서는 작동하지 않습니다. 간단한 예는 다음과 같습니다.$ echo $$ 8909 $ while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
다른 쉘에서:
$ cat /proc/8909/cmdline bash
또한 쓸모가 없습니다
ps -p PID --noheaders -o cmd
:$ ps -p 8909 --no-headers -o cmd bash
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
즉, 원시 명령줄에는 출력이 없습니다. 이는 바로 제가 찾고 있는 것입니다
while true ; do echo 1 ; echo 2>/dev/null ; sleep 30 ; done
. 즉 .
답변1
나는 내가 지푸라기라도 잡고 있다는 것을 알고 있지만 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
향후 재사용을 용이하게 하기 위해 다음과 같이 작성했습니다.배쉬 스크립트, 프로세스를 자동화합니다.
답변2
명령이 화면에서 계속 실행 중이므로 해당 상위 bash는 아직 기록을 다시 읽지 않았습니다. 따라서 다음과 같습니다.
- 화면에 다시 연결
^Z
그런 다음 누르세요up arrow
- 보너스: 명령을 작은따옴표로 묶으십시오(
^A^A
-를 사용하십시오. 왜냐하면 screen(1) - 및^E
)를 탐색하고 에코 + 파일로 리디렉션하기 때문입니다. fg
명령 실행 추구
몇 가지 주의 사항이 있지만 대부분의 경우 이는 충분히 유용합니다.
답변3
나는 당신이 자신의 답을 찾았다는 것을 알고 있지만 이것을 할 수 없는 이유가 있습니까?
(set -x; for f in 1 2 3 4 ; do echo "$f"; sleep $f; done)
어쩌면 실제 작업의 출력과 현재 실행된 라인을 보여주는 bash 출력을 혼합할 수 없을 수도 있습니다.
또한 FWIW, 자세한 내용을 좋아한다면 set -o xtrace
.