tmux 내부에서 nohup을 "재구현"하려고 합니다(따라서 나를 차단하지 않고 작업을 전달한 다음 nohup 역할을 하는 tmux 명령을 종료합니다). 내 시도는 여기에 있습니다(처음에 설명한 대로 몇 가지 문제가 있지만 작동하지 않습니다.이건 별개의 질문이에요, 이 질문은 스크립트의 마지막 부분에 관한 것입니다). 이제 내 주요 문제는 백그라운드에서 실행 중인 실제 Python 스크립트가 완료되면 tmux 세션을 종료하고 싶다는 것입니다. 내 완전한 시도는 다음과 같습니다.
# - get a job id for this tmux session
export SLURM_JOBID=$(python -c "import random;print(random.randint(0, 1_000_000))")
echo SLURM_JOBID = $SLURM_JOBID
export OUT_FILE=$PWD/main.sh.o$SLURM_JOBID
export ERR_FILE=$PWD/main.sh.e$SLURM_JOBID
# - CAREFUL, if a job is already running it could do damage to it, rm reauth process, qian doesn't do it so skip it
# top -u brando9
# pkill -9 reauth -u brando9
# - start tmux,
https://unix.stackexchange.com/questions/724877/custom-kerberos-tmux-doesnt-let-me-name-my-sessions-help-forcing-it
tmux new -s $SLURM_JOBID
# /afs/cs/software/bin/krbtmux new -s $SLURM_JOBID
# cat /afs/cs/software/bin/krbtmux
# - reauth
# /afs/cs/software/bin/reauth
echo $SU_PASSWORD | /afs/cs/software/bin/reauth
# echo 'Secret' | /afs/cs/software/bin/reauth
# echo 'totally secret password' | kinit [email protected]
# to see reauth running
# top -u brando9
# - expt python script
python expts.py &
python -u ~/diversity-for-predictive-success-of-meta-learning/div_src/diversity_src/experiment_mains/main_sl_with_ddp.py --manual_loads_name sl_hdb1_5cnn_adam_cl_filter_size --filter_size 4 > $OUT_FILE 2> $ERR_FILE &
export JOB_PID=$!
echo JOB_PID = $JOB_PID
# - Echo tmux id, should be jobid
tmux display-message -p '#S'
echo SLURM_JOBID = $SLURM_JOBID
# - detach current tmux session
tmux detach &
# - wait for pid from python to be done, if done kill this tmux sess
wait $JOB_PID
tmux ls
tmux kill-session -t $SLURM_JOBID
# check it was killed
tmux ls
# - Done
echo "Done with bash script (experiment or dispatched daemon experiments). "
그러나 위의 내용은 작동하지 않습니다. Python 스크립트가 실행되고 예약되면 &
내가 원하는 것은 해당 작업이 완료된 후 tmux 세션을 종료하는 것입니다. 마침내 시도해 보았지만 효과가 있을지 의문이었습니다. 일단 실행되면 tmux detach &
tmux 세션을 종료하고 wait ...
tmux 외부에서 명령을 실행하고 기본 터미널을 차단하기 때문에 작동하지 않는 것 같습니다 . 대신, 내가 원하는 것은 tmux 내에서 wait 명령을 실행하고(나를 차단하지 않도록) Python 스크립트가 완료되면 tmux 세션을 완전히 종료하는 것입니다. 하지만 이는 내 스크립트의 마지막 부분에 컨텍스트를 추가하는 것뿐입니다.
어떻게 작동하게 할 수 있나요?
답변1
;
연산자를 사용하여 명령을 연결하고 &
연산자를 사용하여 백그라운드로 보낼 수 있습니다. 전체 그룹을 백그라운드로 보내려면 명령을 괄호로 묶습니다. 다음은 데모입니다:
tmux new -s test
(sleep 15 ; tmux kill-session -t test) &
tmux detach
while true ; do
if ! tmux ls 2> /dev/null | grep 'test:' ; then
echo tmux test disconnected
break
fi
sleep 1 # limit polling rate
done
답변2
프로세스 간의 부모-자식 관계가 필요하기 wait
때문에 이 특별한 방식으로 사용할 수 없습니다 . also를 wait
사용하면 ;
이는 명령 구분 기호일 뿐이므로 작동하지 않습니다. 즉, 프롬프트가 반환될 때까지 명령을 완료해야 합니다.
대신, 나는 당신이 찾고 있는 것이 단순히 다음 예와 비슷한 것이라고 믿습니다.
### Random SLURM_JOBID value
export SLURM_JOBID=$(python3 -c "import random;print(random.randint(0, 1_000_000))")
### Init tmux session
tmux new -s "$SLURM_JOBID"
### --- tmux session ---
### Test command: runs in the background of a detached tmux session
### and once finished will self-destruct that same detached tmux session
(for i in $(seq 1 30); do sleep 1 ; done && tmux kill-session -t "$SLURM_JOBID" ) & tmux detach
위 명령을 실행하면 즉시 tmux에서 시작된 쉘로 돌아갑니다.
실행 - 루프의 30초 런타임 내에 다음 명령은 tmux
실제로 여전히 백그라운드에 존재하는지 확인합니다(다음을 tmux attach
사용하여 여전히 다시 연결할 수도 있음).
> ps aux | grep tmux
user 12579 0.0 0.0 5880 3928 ? Ss 10:26 0:00 tmux
user 12613 0.0 0.0 3876 1836 pts/0 S+ 10:27 0:00 grep --color=auto tmux
> tmux list-sessions
683635: 1 windows (created Wed Nov 30 10:26:02 2022)
30초 후에 동일한 명령을 실행하면 상위 tmux
세션이 더 이상 존재하지 않는 것으로 확인됩니다.
> ps aux | grep tmux
user 12706 0.0 0.0 3876 1836 pts/0 S+ 10:30 0:00 grep --color=auto tmux
> tmux list-sessions
no server running on /tmp/tmux-0/default
명령 구문 설명
(for i in $(seq 1 30); do sleep 1 ; done && tmux kill-session ) & tmux detach
위 명령에는 몇 가지 독특한 측면이 있으며 하나씩 논의해 보겠습니다.
- 1 부:
[CMD1] && [CMD2]
위 명령의 맥락에서 이는 다음과 [CMD1]
같습니다 [CMD2]
.
[CMD1] =for i in $(seq 1 30); do sleep 1 ; done
[CMD2] =tmux kill-session -t "$SLURM_JOBID"
두 개의 서로 다른 명령 사이에 이중 앰퍼샌드를 사용하면 쉘이 성공적으로 완료된 경우에만 if AND를 [CMD1] && [CMD2]
기다리고 실행하게 됩니다 .[CMD2]
[CMD1]
즉, 우리 명령의 맥락에서 쉘은 루프를 시작하고 30회 반복 동안 실행 sleep 1
한 다음 루프가 완료되면 실행하라는 지시를 받습니다 tmux kill-session
.
세션 내에서 다음 명령 조합을 실행하여 tmux
이 동작을 직접 테스트 할 수 있습니다.
for i in $(seq 1 10); do sleep 1 ; done && tmux kill-session
루프는 프롬프트를 유지하면서 전경에서 시작되고 실행됩니다.
10초 동안 실행하고 완료하면 tmux kill-session
나머지 부분을 실행 &&
하고 자체 tmux
세션을 삭제하여 이전 셸로 돌아갑니다.
반면 CTRL+를 보내고 z실행 도중 루프를 종료 하면 쉘이 SIGINT를 실패로 등록 하고 오른쪽의 SIGINT 실행을 허용 하지 않기 tmux
때문에 세션이 하루 동안 계속 유지됩니다 .[CMD1]
[CMD2]
&&
- 2 부:
( [CMD1] && [CMD2] )
여러 명령 주위에 괄호를 사용하면 명령을 그룹화하고 격리할 수 있으므로 수학 연산 순서와 유사한 동작을 수행할 수 있습니다.
- 3부:
( [CMD1] && [CMD2] ) &
대괄호 뒤에 "&"를 추가하면 &
백그라운드에서 대괄호 안의 모든 항목을 실행할 수 있습니다.
을 사용하지 않으면 백그라운드에서 여러 명령을 실행하는 것이 더 지루하고 복잡해집니다. 예를 들어 단순히 또는 를 (...)
사용할 수 없기 때문입니다.[CMD1] & && [CMD2]
[CMD1] && & [CMD2]
반면에 (...)
이를 사용하면 다음과 같은 복잡한 작업도 수행할 수 있습니다.
((for i in $(seq 1 5); do sleep 1 ; done && echo "first loop finished" ) && ( for i in $(seq 1 5); do sleep 1; done && echo "second loop finished" ) && sleep 5 && tmux kill-session ) &
첫 번째 루프를 실행하고 완료되면 상태를 보고한 다음 두 번째 루프를 시작하고 완료되면 상태도 보고되며 5초 sleep
지연 후 세션이 자체적으로 삭제됩니다.
- 4부:
([CMD1] && [CMD2]) & tmux detach
마지막 추가 사항은 세션을 시작한 셸로 tmux detach
돌아갈 수 있도록 하는 것 입니다. tmux
두 개의 개별 라인에서 다음 두 명령을 실행하여 동일한 동작을 얻을 수도 있다는 점은 언급할 가치가 있습니다.
(for i in $(seq 1 30); do sleep 1 ; done && tmux kill-session -t "$SLURM_JOBID" ) &
tmux detach
&
싱글이 우리 싱글 라인의 왼쪽에 속하기 때문에 차례로 .