web-dev-qa-db-ja.com

ワンライナーをバッシュして、ファイルが存在しない場合にアトミックに作成します

ファイルが存在しない場合に自動的にファイルを作成するBashワンライナーが必要です。つまり、「ファイルが存在しない場合は作成する」ということですが、ifを実行してからファイルを作成するまでの間に、他のユーザーが小さなスペースでファイルを作成できないようにします。

9
Ram Rachum

答えを盗む さまざまなコメントと[SO]へのリンクから。 POSIX準拠の方法 があるようですmkdirは関与しません

set -o noclobber # or set -C
{ > file ; } &> /dev/null

fileへのこのリダイレクトは、0を返すか、失敗して、ファイルがすでに存在する場合はゼロ以外を返します。


元の答え

mkdirを使用する必要があります。これはアトミックです。ディレクトリが作成されて続行できるか、作成されないため、適切なアクションを実行できます。

もちろん、mkdirはファイルを作成しませんが、ディレクトリへの排他的アクセス権があることがわかったら、必要なファイルをそのディレクトリに作成できます。

ワンライナーについて-それはあなたにお任せします。個人的には、保守しやすくなるように、数行で記述します。

6
user9517

ファイル名を気にしない場合は、このタスクをユーティリティ(たとえば、mktemp)に委任できます。

Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive `X's in last component.
If TEMPLATE is not spec‐ified, use tmp.XXXXXXXXXX, and --tmpdir is 
implied.  Files are created u+rw, and directories u+rwx, minus umask
restrictions.

呼び出し:

filename=$(mktemp)
0
asdmin

これを試してみてください。 lnは、テストと設定の機能を提供します。

touch lock.$$.tmp
if ln lock.$$.tmp lock.dat 2>/dev/null
then
    echo "File is mine"
else
    echo "Test and set failed"
fi
rm -f lock.$$.tmp
0
roaima

それはファイルまたはディレクトリですか?ファイルの場合、単純なコマンドtouchを使用できます。ファイルが存在する場合は、最終アクセス時刻を変更するだけです。ファイルが存在しない場合は作成されます。

0