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セッションに入り、切り離した後にのみ残りのコマンドが実行されます。

シェルスクリプトは、端末入力用のコマンドセットではありません。シェルが特定のタスクを実行するための一連のガイドラインです。したがって、ガイドラインの1つ

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のウィンドウは、もはやウィンドウが含まれていない場合は削除されます(注:複数のウィンドウに分割されていないウィンドウには1つのウィンドウしか含まれません)。
  • 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-exitexit-empty

おすすめ記事