tmux와 상호작용(예: nohup 작업 전달) 없이 tmux를 사용하여 백그라운드에서 작업을 실행하려면 어떻게 해야 합니까?

tmux와 상호작용(예: nohup 작업 전달) 없이 tmux를 사용하여 백그라운드에서 작업을 실행하려면 어떻게 해야 합니까?

Kerberos를 사용하여 재인증해야 하므로 tmux에서 장기 프로세스를 실행해야 합니다. 나는 작동할 것이라고 생각하는 스크립트를 작성했지만 작동하지 않았습니다. 문제는 tmux 세션을 실행한 후 tmux 내부에서 다음 명령을 실행하는 대신 tmux 세션에 들어가고 분리한 후에만 나머지 명령을 실행한다는 것입니다. 하지만 원할 때 tmux 세션 외부에서 실행됩니다. 실행하는 것~에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 세션을 완전히 종료하는 것입니다. 하지만 이는 내 스크립트의 마지막 부분에 컨텍스트를 추가하는 것뿐입니다.

관련된:비밀번호가 필요한 명령을 사용하여 Linux에서 인증하는 방법은 무엇입니까?

답변1

Tmux는 마술처럼 스크립트 흐름을 변경하지 않습니다.

tmux 세션을 실행한 후 tmux 내에서 다음 명령을 실행하는 대신 tmux 세션에 들어가고 분리한 후에만 나머지 명령이 실행됩니다.

쉘 스크립트는 터미널 입력을 위한 명령 세트가 아닙니다. 쉘이 특정 작업을 수행하기 위한 일련의 지침입니다. 따라서 지침 중 하나가

tmux new   # i.e. tmux new-session

그런 다음 셸은 tmux명령이 종료될 때까지 백그라운드에서 실행되고 다음 명령으로 진행됩니다. 이 명령은 tmux 클라이언트를 시작합니다(필요한 경우 tmux 서버를 백그라운드에서 시작할 수 있음). tmux 클라이언트에 의해 시작된 쉘은 스크립트를 해석하는 쉘과 아무 관련이 없습니다. 확실히 스크립트에서 명령을 읽지 않습니다.

마찬가지로 ssh user@server, 스크립트 내에서 실행되면 결국 새로운(원격) 셸이 시작되어 스크립트 실행을 "인계"하지 않습니다. 더 간단한 예는 입니다 cat. 쉘 스크립트 내에서 싱글을 실행 하면 cat나머지 스크립트는 사용되지 않습니다. 해석된 쉘은 스크립트 실행을 계속하기 전에 기다리거나 cat종료 됩니다. 셸의 관점에서 볼 때 새 셸을 시작 하거나 시작한다는 사실은 관련이 없습니다.sshtmuxtmuxssh

귀하의 경우 tmux new해석 쉘이 기다리는 동안 분리될 때까지(또는 tmux 클라이언트를 종료하거나 중지할 때까지) 스크립트의 나머지 부분을 실행하지 않습니다.


tmux 내부에서 뭔가 실행하기

tmux 세션 외부에서 실행되는 반면 tmux 세션 내부에서 실행되기를 원합니다.

tmux 내에서 무언가를 실행하려면 tmux 클라이언트에 무엇을 실행할지 알려주세요:

tmux new-session -d 'shell code here; I mean the job you want'

감사해요-d클라이언트는 새 세션을 시작하지만(작업 디스패치) 새 세션을 터미널에 연결하지는 않습니다. 클라이언트는 세션에 들어가는 것을 허용하지 않으며 거의 ​​즉시 종료되므로 쉘이 스크립트를 계속 해석할 수 있습니다.

세션에서 더 많은 작업을 실행하려면 tmux 명령이 셸 코드를 인수로 사용할 new-window수도 있다는 점을 기억하세요.split-window

물론 스크립트의 나머지 부분에는 셸 코드가 작업으로 포함되어서는 안 됩니다. tmux에서 실행하려는 것은 에 전달하는 것입니다 tmux …. 스크립트 라인으로 직접 작성한 스크립트를 해석하는 쉘에 의해 실행되기를 원하는 것은 입니다 tmux …. 내 요점은 tmux에서 실행하려는 작업에 대한 인수인 쉘 코드가 tmux쉘이 직접 실행하는 것을 해석하는 대신 인수가 되어야 한다는 것입니다.


tmux 세션 종료

내가 원하는 것은 해당 작업이 완료된 후 tmux 세션을 종료하는 것입니다

기본 설정*에서는 다음과 같은 일이 발생합니다.

  • tmux의 창은 할당된 프로세스가 종료되자마자 삭제됩니다.
  • tmux의 창은 더 이상 창을 포함하지 않으면 삭제됩니다(참고: 여러 창으로 분할되지 않은 창에는 창 하나만 포함됩니다).
  • tmux의 세션에 더 이상 창이 포함되어 있지 않으면 세션이 삭제됩니다.
  • tmux 서버에 더 이상 세션이 포함되어 있지 않으면 파기됩니다.

즉, 걱정할 것이 없을 가능성이 높습니다. 위에서 설명한 대로 tmux에서 올바른 방법으로 작업을 시작하고 세션에 추가 창이나 창을 만들지 않으면 작업이 완료될 때 세션이 자동으로 종료됩니다. 비교하다내 다른 답변.


추가 통찰력

바라보다이 문제. 이는 특정 명령을 실행한 후 스크립트의 명령이 tmuxtmux의 셸에 도달할 것이라고 생각한 사용자(당신과 같은)에게서 나온 것입니다. 내 대답은 당신에게 더 많은 통찰력을 줄 수 있습니다.


다음 스크립트를 실행합니다.

#!/bin/sh
tmux new-session -d -s myloop 'while sleep 1; do date; done'
echo "Job dispatched. The script will now terminate."

작업을 디스패치하고 즉시 종료합니다. 확인하다 tmux ls. 몇 초 정도 기다리면 tmux attach -t myloop그 이후로 작업이 계속 실행되고 있음을 알 수 있습니다. 연결되면 루프를 종료합니다( Ctrl+ 사용 c). 세션(및 tmux 서버도 가능)이 자동으로 종료됩니다*. tmux ls다시 확인하여 확인하세요.


*행동 변경 옵션:remain-on-exit,exit-empty.

관련 정보