回答:
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
: ...
rm "$tmpfile"
ファイルのファイル記述子を開いて削除することにより、スクリプトの終了時に(キルやクラッシュを含む)ファイルが削除されることを確認できます。/proc/$PID/fd/$FD
ファイル記述子が開いている限り、ファイルは利用可能です(スクリプト用。実際には他のプロセス用ではありませんが、回避策です)。閉じられると(プロセスの終了時にカーネルが自動的に行います)、ファイルシステムはファイルを削除します。
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
exec 3>"$tmpfile"
rm "$tmpfile"
: ...
echo foo >&3
/proc
-それを持たないシステムを除く。
exec 3> "$tmpfile"
ますか?tmpfileがスタンドアロンスクリプトである場合にのみ有用ではありませんか?
cat <&3
与えBad file descriptor
ます。修正または削除していただければ幸いです。誤報はあまり役に立ちません。
mktemp
一時ファイルまたはディレクトリを作成するために使用します。
temp_file=$(mktemp)
またはディレクトリの場合:
temp_dir=$(mktemp -d)
スクリプトの最後で、一時ファイル/ディレクトリを削除する必要があります。
rm ${temp_file}
rm -R ${temp_dir}
mktempは、/tmp
ディレクトリまたは--tmpdir
引数で指定されたディレクトリにファイルを作成します。
trap "rm -f $temp_file" 0 2 3 15
ファイルを作成した直後に使用して、スクリプトが終了または停止しctrl-C
てもファイルが削除されるようにすることができます。
EXIT
唯一のフックである場合はどうなりtrap
ますか?
kill -9 $somepid
。その特定のキルシグナルは、他に何も起こらずにinsta-deathです。
bash -c 'echo $$; trap "echo foo" 0; sleep 5'
EXIT
で十分です。
mktempがあるシステムを使用している場合は、他の回答として使用する必要があります。
POSIXツールチェストの場合:
umask 0177
tmpfile=/tmp/"$0"."$$"."$(awk 'BEGIN {srand();printf "%d\n", rand() * 10^10}')"
trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT
: > "$tmpfile"
EXIT
唯一のフックである場合はどうなりtrap
ますか?
tmpfile
スクリプトが終了する前に削除されますが、スクリプトが他のシグナルを受信したときは削除されません。
That's not what happens
ですか?
mktemp
異なる構文を使用してHP / UXで作成されました。Todd C. Millerは、90年代半ばにOpenBSD用に別のものを作成し(FreeBSDとNetBSDによってコピー)、後にスタンドアロンユーティリティ(www.mktemp.org)としても利用できるようにしました。これはmktemp
、2007年に(ほとんど互換性のある)ユーティリティがGNU coreutilsに追加されるまでLinuxで一般的に使用されmktemp
ていたものです。実際に言うことができないのはGNUユーティリティです。
一部のシェルには機能が組み込まれています。
zsh
の=(...)
形式のプロセス置換は、一時ファイルを使用します。たとえば=(echo test)
、を含む一時ファイルのパスに展開しますtest\n
。
$ {cat $file; ls -l /dev/fd/3; echo test2 >&3; cat $file} 3<> ${file::==(echo test)}
test
lrwx------ 1 stephane stephane 64 Jan 30 11:19 /dev/fd/3 -> /tmp/zshMLbER0
test2
コマンドが終了すると、そのファイルは自動的に削除されます。
here-filesまたはhere-stringsはbash
、zsh
削除された一時ファイルとして実装されます。
あなたがそうするなら:
exec 3<<< test
ファイル記述子3は、を含む削除済み一時ファイルに接続されていますtest\n
。
次の方法でコンテンツを取得できます。
cat <&3
Linuxの場合は、次の方法でもそのファイルを読み書きできます。 /dev/fd/3
$ exec 3<<< test
$ cat <&3
test
$ echo foo > /dev/fd/3
$ cat /dev/fd/3
foo
(他のシェルはパイプを使用する/dev/null
か、here docが空の場合に使用する場合があります)。
mktemp
POSIXユーティリティはありません。ただし、POSIXはmkstemp(template)
C APIを指定し、m4
標準ユーティリティはそのAPIをmkstemp()
同じ名前のm4関数で公開します。
mkstemp()
関数が呼び出されたときに存在しないことが保証されたランダムな部分を含むファイル名を提供します。レース0の方法でアクセス許可0600のファイルを作成します。
だから、あなたはすることができます:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
ただし、終了時にクリーンアップを処理する必要があることに注意してください。ただし、ファイルの書き込みと読み取りを一定回数だけ行う必要がある場合は、here-doc / here-のように作成した直後にファイルを開いて削除できます。上記の文字列アプローチ:
tmpfile=$(
echo 'mkstemp(template)' |
m4 -D template="${TMPDIR:-/tmp}/baseXXXXXX"
) || exit
# open once for writing, twice for reading:
exec 3> "$tempfile" 4< "$tempfile" 5< "$tempfile"
rm -f -- "$tmpfile"
cmd >&3 # store something in the temp file
exec 3>&- # fd no longer needed
# read the content twice:
cat <&4
cat <&5
ファイルを1回読み取り用に開き、2回の読み取りの間に巻き戻すことができますが、その巻き戻し(lseek()
)を実行できるPOSIXユーティリティはないため、POSIXスクリプト(zsh
(sysseek
builtin)and ksh93
(<#((...))
operator)canしかしそれを行う)。
<()
=(...)
。
以下に、Hauke Lagingの行の回答を少し改善しました。
#!/bin/bash
tmpfile=$(mktemp) # Create a temporal file in the default temporal folder of the system
# Lets do some magic for the tmpfile to be removed when this script ends, even if it crashes
exec {FD_W}>"$tmpfile" # Create file descriptor for writing, using first number available
exec {FD_R}<"$tmpfile" # Create file descriptor for reading, using first number available
rm "$tmpfile" # Delete the file, but file descriptors keep available for this script
# Now it is possible to work with the temporal file
echo foo >&$FD_W
echo bar >&$FD_W # Note that file descriptor always concatenates, not overwrites
cat <&$FD_R
通常、一時ファイルを使用するワークフローは、テスト中のbashスクリプトが原因です。tee
それが機能していることを確認し、プロセスの次の反復のために出力を保存できるように、それを増やしたいと思います。というファイルを作成しましたtmp
#!/bin/bash
echo $(mktemp /tmp/$(date +"%Y-%m-%d_%T_XXXXXX"))
のようにそれを使用することができます
$ some_command --with --lots --of --stuff | tee $(tmp)
ランダム値の前にフォーマットされた日時が好きな理由は、簡単に作成したtmpファイルを見つけることができるため、次に名前を付けることを考える必要がありません(そして私のダンスクリプトを取得することに集中する必要はありません動作するように)。