はじめに

こんにちは!今回はunsetコマンドについて解説します。

unsetは、設定した変数や関数を削除するコマンドです。「この変数もう使わない」って時に、きれいに片付けられます。

unsetコマンドとは

unsetは、シェル変数や関数を削除する組み込みコマンドです。

変数を空にするのとは違って、完全に削除します。メモリの節約やセキュリティ的な理由で、不要になった変数は削除しておくと良いです。

基本構文

1
unset [オプション] 変数名または関数名

主なオプション

オプション 説明
-v 変数を削除(デフォルト)
-f 関数を削除

使用例

例1: 基本的な変数の削除

1
2
3
4
5
NAME="Taro"
echo $NAME

unset NAME
echo $NAME

実行結果:

1
2
Taro
(空行)

変数を削除すると、値が空になります。

例2: 環境変数の削除

1
2
3
4
5
export MY_VAR="test"
echo $MY_VAR

unset MY_VAR
echo $MY_VAR

実行結果:

1
2
test
(空行)

環境変数も普通に削除できます。

例3: 複数の変数を一度に削除

1
2
3
4
5
6
7
NAME="Taro"
AGE=25
CITY="Tokyo"

unset NAME AGE CITY

echo "Name: $NAME, Age: $AGE, City: $CITY"

実行結果:

1
Name: , Age: , City:

スペース区切りで複数指定できます。

例4: 配列の削除

1
2
3
4
5
declare -a fruits=("apple" "banana" "orange")
echo ${fruits[@]}

unset fruits
echo ${fruits[@]}

実行結果:

1
2
apple banana orange
(空行)

配列全体を削除できます。

例5: 配列の特定要素を削除

1
2
3
4
5
declare -a fruits=("apple" "banana" "orange")
echo ${fruits[@]}

unset fruits[1]  # bananaを削除
echo ${fruits[@]}

実行結果:

1
2
apple banana orange
apple orange

配列のインデックスを指定すると、その要素だけ削除されます。

例6: 連想配列の削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
declare -A user
user[name]="Taro"
user[age]=25

echo ${user[name]}

unset user[name]  # 特定のキーを削除
echo ${user[name]}

unset user  # 配列全体を削除

実行結果:

1
2
Taro
(空行)

連想配列も同様に削除できます。

例7: 関数の削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 関数を定義
greet() {
  echo "Hello!"
}

# 関数を実行
greet

# 関数を削除
unset -f greet

# 削除後に実行しようとするとエラー
greet

実行結果:

1
2
Hello!
bash: greet: コマンドが見つかりません

-fオプションで関数を削除できます。

例8: 変数が削除されたか確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
NAME="Taro"

if [ -v NAME ]; then
  echo "変数NAMEは存在します"
fi

unset NAME

if [ -v NAME ]; then
  echo "変数NAMEは存在します"
else
  echo "変数NAMEは削除されました"
fi

実行結果:

1
2
変数NAMEは存在します
変数NAMEは削除されました

-vオプション(testコマンドの)で変数の存在確認ができます。

空文字列との違い

変数を空にするのと削除するのは違います。

1
2
3
4
5
6
7
# 空文字列を代入
NAME=""
echo "Name: ${NAME:-未設定}"

# 変数を削除
unset NAME
echo "Name: ${NAME:-未設定}"

実行結果:

1
2
Name:
Name: 未設定
  • 空文字列: 変数は存在するが値が空
  • unset: 変数自体が存在しない

Tips・注意点

  • 読み取り専用変数は削除できない: declare -rで作った変数は削除不可

    1
    2
    
    declare -r PI=3.14
    unset PI  # エラーになる
    
  • 特殊変数は削除できない: $?, $#, $$などは削除不可

    1
    
    unset ?  # エラー
    
  • PATH削除に注意: うっかりPATHを削除すると、ほとんどのコマンドが使えなくなる

    1
    2
    
    unset PATH  # 危険!
    # ls, cd などが使えなくなる
    
  • 関数と変数の同名: 同じ名前の関数と変数がある場合、-f-vで明示する

    1
    2
    3
    4
    5
    
    test="変数"
    test() { echo "関数"; }
    
    unset -v test  # 変数を削除
    unset -f test  # 関数を削除
    
  • サブシェルでの削除: サブシェルで削除しても親には影響なし

    1
    2
    3
    
    NAME="Taro"
    (unset NAME; echo $NAME)  # 空
    echo $NAME  # Taro(元のまま)
    

実践的な使い方

一時変数のクリーンアップ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

# 一時的な変数を使う
TEMP_DIR="/tmp/myapp_$$"
mkdir -p "$TEMP_DIR"

# 処理を実行
cp file.txt "$TEMP_DIR/"

# 処理が終わったら変数を削除
unset TEMP_DIR

使い終わった変数は削除してメモリをクリアします。

機密情報の削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/bash

# パスワードを読み込む
read -sp "Password: " PASSWORD
echo

# パスワードを使って処理
authenticate "$PASSWORD"

# 処理が終わったらすぐ削除
unset PASSWORD

パスワードなどの機密情報は、使い終わったらすぐ削除します。

設定のリセット

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash

# デフォルト設定
DEFAULT_PORT=8080

# ユーザー設定を読み込む
if [ -f ~/.myapp.conf ]; then
  source ~/.myapp.conf
fi

# PORT変数が設定されてなかったらデフォルトを使う
PORT=${PORT:-$DEFAULT_PORT}

# 処理後にクリーンアップ
unset DEFAULT_PORT

ループ内の変数クリーンアップ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#!/bin/bash

for file in *.txt; do
  # ファイルごとに処理
  CONTENT=$(cat "$file")

  # 何か処理
  echo "Processing: $file"

  # ループの最後でクリーンアップ
  unset CONTENT
done

関数の動的な削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

# テストモードかどうかで関数を切り替え
if [ "$TEST_MODE" = "true" ]; then
  log() { echo "[TEST] $*"; }
else
  log() { echo "[PROD] $*"; }
fi

log "Application started"

# 処理が終わったら関数を削除
unset -f log

環境変数の一時的な設定と削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

# バックアップ
OLD_PATH="$PATH"

# 一時的にPATHを変更
export PATH="/custom/bin:$PATH"

# 処理を実行
custom_command

# 元に戻す(または削除)
export PATH="$OLD_PATH"
unset OLD_PATH

配列要素の選択的削除

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash

declare -a tasks=("task1" "task2" "task3" "task4")

# task2を削除
for i in "${!tasks[@]}"; do
  if [ "${tasks[$i]}" = "task2" ]; then
    unset tasks[$i]
  fi
done

# 再インデックス(必要なら)
tasks=("${tasks[@]}")

echo "残りのタスク: ${tasks[@]}"

まとめ

今回はunsetコマンドについて解説しました。

ポイント:

  • unsetで変数や関数を完全に削除できる
  • 空文字列を代入するのとは違い、変数自体が消える
  • -vで変数、-fで関数を削除
  • 配列の特定要素も削除可能
  • 機密情報は使用後すぐに削除すべき
  • 読み取り専用変数や特殊変数は削除できない

不要になった変数や機密情報は、unsetできれいに片付けましょう。特にパスワードやAPIキーなどは、使い終わったら必ず削除することをおすすめします。

次回もLinuxコマンドの学習を続けていきましょう!