Help us understand the problem. What is going on with this article?

trapがどんどん上書きされてしまう

More than 1 year has passed since last update.

受け取ったシグナルに合わせて、指定した処理を実行してくれるtrap、とても便利ですよね(´・ω・`) 個人的には「作成した一時ファイルを終了後に必ず破棄する」という処理を実装する際によく利用しています。

path=$(mktemp)
trap "rm -f ${path}" EXIT

ひとつのシグナルに対する処理はそのスクリプト内において1回しか定義できない、つまりtrapを呼び出すたびにどんどん上書きされてしまうことに注意する必要があります。たとえば「複数の一時ファイルを作成し、処理終了後にそれらをすべて破棄する」とき、ついつい次のようなコードを書きがちです。

trap_test.sh
#!/bin/bash

set -x

path1=$(mktemp)
path2=$(mktemp)
path3=$(mktemp)

for path in ${path1} ${path2} ${path3}; do
  trap "rm -f ${path}" EXIT
done

# === do_something ===

exit 0

これを実行した結果が以下の通りになります。trapを3回呼び出して、作成した3つの一時ファイルを処理終了後に削除することを意図していますが、rmは一度しか呼ばれていません。また少しわかりづらいのですが、trapにより呼ばれたrmpath3を削除しています。つまりtrapは呼び出すごとに指定した処理を上書きしているとわかります。

$ bash trap_test.sh
++ mktemp
+ path1=/tmp/tmp.0dzHkNQP8n
++ mktemp
+ path2=/tmp/tmp.CtuP5ZdxyW
++ mktemp
+ path3=/tmp/tmp.8TZD5DRKKI
+ for path in '${path1}' '${path2}' '${path3}'
+ trap 'rm -f /tmp/tmp.0dzHkNQP8n' EXIT
+ for path in '${path1}' '${path2}' '${path3}'
+ trap 'rm -f /tmp/tmp.CtuP5ZdxyW' EXIT
+ for path in '${path1}' '${path2}' '${path3}'
+ trap 'rm -f /tmp/tmp.8TZD5DRKKI' EXIT
+ exit 0
+ rm -f /tmp/tmp.8TZD5DRKKI

したがって意図通りにするためには、trap_test.shを次のように修正する必要があります。

trap_test.sh
#!/bin/bash

set -x

path1=$(mktemp)
path2=$(mktemp)
path3=$(mktemp)
trap "rm -f ${path1} ${path2} ${path3}" EXIT

# === do_something ===

exit 0

この実行結果は以下の通りです。作成した3つの一時ファイルがrmの対象になっていることが確認できます(´・ω・`)

$ bash trap_test.sh
++ mktemp
+ path1=/tmp/tmp.vrVWvDvk9P
++ mktemp
+ path2=/tmp/tmp.i2aLRF3WMr
++ mktemp
+ path3=/tmp/tmp.Y6LOH2QYnw
+ trap 'rm -f /tmp/tmp.vrVWvDvk9P /tmp/tmp.i2aLRF3WMr /tmp/tmp.Y6LOH2QYnw' EXIT
+ exit 0
+ rm -f /tmp/tmp.vrVWvDvk9P /tmp/tmp.i2aLRF3WMr /tmp/tmp.Y6LOH2QYnw
neko_the_shadow
IT業界の片隅でひっそり生きるシステムエンジニアです(´・ω・`)
https://nekotheshadow.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away