web-dev-qa-db-ja.com

一時ディレクトリを作成する方法は?

tempfileを作成して削除し、ディレクトリとして再作成します。

tmpnam=`tempfile`
rm -f $tmpnam
mkdir "$tmpnam"

問題は、あるプロセスrm -f Xの後、mkdir Xの直前に誤ってtempfileを実行すると、別のプロセスが同じ名前Xを取得する可能性があることです。

207
Xiè Jìléi

mktemp -d を使用します。ランダムな名前で一時ディレクトリを作成し、ファイルが存在しないことを確認します。ただし、使用後にディレクトリを削除することを忘れないでください。

313
marcog

より堅牢なソリューションのために、次のようなものを使用します。これにより、スクリプトが終了した後、一時ディレクトリは常に削除されます。

クリーンアップ関数は、EXIT信号で実行されます。これにより、スクリプトがどこかで異常終了した場合でも、クリーンアップ関数が常に呼び出されることが保証されます。

#!/bin/bash    

# the directory of the script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# the temp directory used, within $DIR
# omit the -p parameter to create a temporal directory in the default location
WORK_DIR=`mktemp -d -p "$DIR"`

# check if tmp dir was created
if [[ ! "$WORK_DIR" || ! -d "$WORK_DIR" ]]; then
  echo "Could not create temp dir"
  exit 1
fi

# deletes the temp directory
function cleanup {      
  rm -rf "$WORK_DIR"
  echo "Deleted temp working directory $WORK_DIR"
}

# register the cleanup function to be called on the EXIT signal
trap cleanup EXIT

# implementation of script starts here
...

here のbashスクリプトのディレクトリ。

Bash トラップ

64

私のお気に入りのワンライナーは

cd $(mktemp -d)
56
Emmett Butler

次のスニペットは、一時ディレクトリ(-d)を安全に作成し、その名前をTMPDIRに保存します。 (TMPDIR変数の使用例は、後で変更される可能性のある元のファイルの保存に使用されるコードで示されています。)

最初のtrap行は、指定された signals のいずれかが受信されたときにexit 1コマンドを実行します。 2番目のtrap行は、プログラムの終了時に(正常と異常の両方で)$TMPDIRを削除(クリーンアップ)します。 mkdir -dが成功したことを確認した後、これらのトラップを初期化して、不明な状態の$TMPDIRで誤って終了トラップを実行しないようにします。

#!/bin/bash

# Create a temporary directory and store its name in a variable ...
TMPDIR=$(mktemp -d)

# Bail out if the temp directory wasn't created successfully.
if [ ! -e $TMPDIR ]; then
    >&2 echo "Failed to create temp directory"
    exit 1
fi

# Make sure it gets removed even if the script exits abnormally.
trap "exit 1"           HUP INT PIPE QUIT TERM
trap 'rm -rf "$TMPDIR"' EXIT

# Example use of TMPDIR:
for f in *.csv; do
    cp "$f" "$TMPDIR"
    # remove duplicate lines but keep order
    Perl -ne 'print if ++$k{$_}==1' "$TMPDIR/$f" > "$f"
done
6
jreisinger