プログラムを起動して、その出力をログファイルに書き込むにはどうすればよいですか。ログファイルの名前にはPIDが含まれています。私は試した
program_a > log_$!
$以降は機能しません!は最後のプログラムのPIDであり、ログファイルの作成時に `program_a 'は終了していません。
あなたがスクリプトについて話しているなら、私はこれがあなたが求めているものだと思います...
#!/bin/bash
exec 1>test_$$.txt
echo "Hello \$\$ == $$"
ps
この出力を与えた
$ cat test_20000.txt
Hello $$ == 20000
PID TTY TIME CMD
18651 ttys000 0:00.06 -bash
20000 ttys000 0:00.00 /bin/bash ./execredir.sh
プログラムが呼び出される前にコマンドラインが作成されるため、シェルからそのように行うことはできません。基本的に2つのオプションがあります。
1)ファイル名を作成し、プログラム内から書き込みます(シェルスクリプトの場合は簡単です)
2)名前付きパイプを作成し、プロセスをバックグラウンドで実行してから、パイプをファイルにリダイレクトします。お気に入り
mkfifo "tmp.log"
program_a > "tmp.log" &
cat "tmp.log" > "log_$!"
これは質問に直接答えることはありませんが、名前にpid
が含まれるファイルが必要な理由については疑問があります。探しているのが単に一意のファイル名である場合は、これを行うためのより堅牢な方法があります。ほとんどのユニスにはmktemp
コマンドがあります(残念ながら、これはPOSIXではありません)。 GNU mktemp
を使用すると、次のことができます。
tmp_file=$(mktemp --tmpdir=. log_XXXXXXXXXX)
program_a >"$tmp_file"
後日ファイルにアクセスする必要がある場合は、ファイル名に日付/時刻を含めると便利な場合があります。
log_file=$(mktemp --tmpdir=. log_"$(date +%F_%T)".XXX)
program_a >"$log_file"
特定のプロセスのインスタンスが1つだけ実行されていることを確認したい場合は、Linuxでflock
を使用できます。
(
flock -n 9 || { echo "program_a already running"; exit 1; }
program_a
) 9>/var/lock/program_a
それ以外の場合、実行中に別のプログラムにprogram_a
の出力を読み取らせたい場合は、ファイルを使用することが確実に最後の手段です。 orionの答え に従って、パイプまたは名前付きパイプを使用する方がはるかに優れています。
プロセスが開始されるまで、PIDを知ることはできません。したがって、最初にプロセスを開始し、次にログファイルを作成してから、実行するプログラムを実行する必要があります(exec
は、呼び出し元のシェルを指定されたプログラムに置き換えます。新しいプロセスをフォークしません)。
sh -c 'exec program_a >log_$$'
$!
は、バックグラウンドで開始された最後のプログラムのPIDであり、ここでは役に立ちません。
または、一時的な名前でログファイルを作成し、プログラムを起動してから、ログファイルの名前を変更することもできますが、それは不必要に複雑です。