これは奇妙な質問のように思えるかもしれませんが、次のようなファイルに出力が書き込まれるスクリプトがあるとしましょう。
myscript.sh >> /path/to/some/file
実際に何も書かずに出力ファイルの修正時間を更新できるように標準出力を「タッチ」することは可能ですか?
明らかに、パスがスクリプトに直接渡された場合は、コマンドを使用してこれを簡単に実行できますが、touch
ここではそうではありません。代わりに、標準出力をファイルにリダイレクトします。
それでは、I / Oリダイレクトを使用するときにターゲットファイルに到達する賢い方法はありますか?それとも、内部的に、またはある種のラッパースクリプト内で出力パスを処理する必要がありますか?
答え1
少なくともLinuxにはファイルへの/dev/stdout
シンボリックリンクがあるので、次のように動作します。/proc/self/fd/1
touch /dev/stdout
user@host:~$ ( echo hi; stat -c '%y' /tmp/foo >&2; for i in 0 1 2; do sleep 2; touch /dev/stdout; stat -c '%y' /tmp/foo >&2; done ) >> /tmp/foo
2017-11-03 07:02:59.595622835 -0400
2017-11-03 07:03:01.599680859 -0400
2017-11-03 07:03:03.603738883 -0400
2017-11-03 07:03:05.611797023 -0400
Linuxでは、stdoutがファイルでない場合、成功したり何もしません。たとえば、匿名パイプには./myscript.sh | less
実際にはmtimeがありますが、ソケットのmtimeは常に0です。 stdoutが開いていない場合(まれですが可能です)、診断メッセージ(「コンピュータにファイルまたはディレクトリがありません」)が生成されます。 stdoutが書き込み不可能なファイルであっても同様です。
まったく移植性がありませんが、最悪の場合は診断を生成し、何も実行しない可能性があります(少なくとも書き込めないルートではないユーザーの場合/dev
)。
実際の目標によっては、より良い方法があるかもしれません。たとえば、ファイル名をスクリプトに渡すと、直接touch
使用するのが簡単な場合があります。あるいは、「生きている!」と言うためにこれを行う場合は、別のファイルが必要になることがあります(またはプロセスマネージャおよび/またはpidファイルを使用)。
答え2
futimes()
コール/futimens()
システムコールが必要です。
を使用すると、perl
次のように呼び出すことができます。
perl -e 'utime undef, undef, *STDOUT'