次のようなシェルスクリプトがあります。
#!/bin/bash
# Here is where I set a bunch of environment variables that are
# used by the process invoked below...
# Now I want to invoke the process in the background and redirect
# all of the output to a log file.
Nohup name-of-executable > logfile.out 2>&1 &
# Finally, I record the PID of the process before the script exits.
echo $! > proc.pid
ユースケースは、定期的に、誰かがこのマシンにsshでログインし、このプロセスを開始して、マシンからログアウトすることです。プロセスの実行中に発生した問題をデバッグできるように、ログファイルを作成する必要があります。
上記のスクリプトを使用すると、プロセスは正しく実行され、ログファイルが作成されますが、ログファイルに出力が書き込まれることはありません。長さゼロのファイルを取得します。
コマンドNohup name-of-executable > logfile.out 2>&1 &
をコマンドラインから直接実行すると、プロセスが実行され、期待どおりにデータが記録されます。シェルスクリプトの一部としてこれを行う方法がわかりません。
Nohupの代わりにscreenを使用するのはどうですか?このようなバックグラウンド処理を行うことができます
screen -d -m /bin/bash 'name-of-executable > logfile.out 2>&1'
バックグラウンドジョブで何が行われているかを確認できるため、Nohup
よりも優れています。 screen -ls
を発行してすべてのジョブのリストを表示し、次にscreen -r screen_identifier
を発行してそのバックグラウンドジョブの対話型シェルに直接ジャンプできます。詳細については、man screen
と入力してください。
コメントで言われたことに基づいて、これはあなたが必要とすることをするかもしれません:
#!/bin/sh
Nohup sh -c "sleep 5 && ls /proc/1/fd /proc/$$ >/tmp/log 2>/tmp/log.err" &
echo $$ >>/tmp/pid_log
wait
echo done
出力は次のようになります。
$ grep . /tmp/log{,.err}
/tmp/log:uid_map
/tmp/log:wchan
/tmp/log.err:ls: cannot open directory /proc/1/fd: Permission denied