空のシェル変数を使用するとエラーが発生します


22

時々$PROJECT_HOME/*、プロジェクト内のすべてのファイルを削除するために使用します。環境変数PROJECT_HOMEが設定されていない場合(私が設定suし、新しいユーザーがこの環境変数を設定していないため)、ルートフォルダーからすべてのファイルの削除が開始されます。これは終末論的です。

bashシェルで未定義の環境変数を使用する場合、エラーをスローするように構成するにはどうすればよいですか?


5
set -uあなたがしたいことをします。
クオンルム

あなたは答えとしてそれを作ることができますか?

2
もちろん、varsを空の文字列に初期化することはありません。[ -z "$VAR" ]未初期化でVARも動作します。初期化は、望ましくない動作を示すためだけでした-私のポイントは、あなたの変数が何らかの方法で空の文字列に初期化さrm -r "$PROJECT_HOME"/*set -u、誤って依存して実行すると、「黙示録的な」動作が得られることです。IHMO、お使いのコンピューターのコンテンツ全体を保護することに関しては、申し訳ないよりも安全である方が良いです。set -u安全ではありません。
PSkocik

3
「とても長い」?危険な操作を手動で実行する便利な方法を探してはいけません。代わりに、目的の処理を行う関数、エイリアス、またはスクリプトを作成する必要があります。この場合、@ PSkocikの推奨コマンドからエイリアスを作成することは安全便利です。
カイルストランド

1
ユーザーが設定したらどうなりますPROJECT_HOME=/etcか?空の値をチェックするだけでは、大変動を防ぐのに十分ではありません。ルートとして実行する場合、信頼できないユーザーの変数を使用しないでください。
バーマー

回答:


27

POSIXシェルでは、set -uを使用できます。

#!/bin/sh

set -u
: "${UNSET_VAR}"

またはパラメータ拡張を使用して:

: "${UNSET_VAR?Unset variable}"

あなたの場合、:?代わりに?を使用して、設定されているが空の変数でも失敗する必要があります:

rm -rf -- "${PROJECT_HOME:?PROJECT_HOME empty or unset}"/*

17
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/*

これは、PROJECT_HOME 設定されていても何も含まれていない場合もキャッチします。

例:

1)これにより、システムで削除できるほとんどすべてが削除されます(内部にドットファイル/がない場合(通常はありません))。

set -u
PROJECT_HOME=
rm -r "$PROJECT_HOME"/*

2)これは何もしません:

PROJECT_HOME=
[ -z "$PROJECT_HOME" ] || rm -r "$PROJECT_HOME"/* 

プロジェクトを完全に削除して再作成することも、別のオプションかもしれません(ドットファイルも削除したい場合):

#no apocalyptic threats in this scenario
rm -r "$PROJECT_HOME"
mkdir "$_" 

1
-zは大丈夫ですが$PROJECT_HOME、ディレクトリである-dはずなので、おそらくより良いでしょう。[[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME"
小次郎

2
PROJECT_HOMEが非ディレクトリに設定されている場合、それは致命的ではないエラーであり、タイプミスによる可能性があります。-dチェックは、そのエラーを非表示にします。私はそれが上に行けばそれが良いことだと思うrmし、rm大声でそれについて出て文句を言います。
PSkocik

2
PROJECT_HOMEが設定されているが、名前がディレクトリではない場合、[[ -d $PROJECT_HOME ]] && rm -r "$PROJECT_HOME"何も行わず、何もしません。ただし[[ -z $PROJECT_HOME ]] || rm -r "$PROJECT_HOME"、ディレクトリではないファイルであっても、「$ PROJECT_HOME」を静かに削除します。エラーメッセージの取得が問題になることはありませんif [[ -d $PROJECT_HOME ]]; then rm -r "$PROJECT_HOME"; else printf '%s is not a directory\n' "$PROJECT_HOME" >&2; fi
。– kojiro

1
今、「偶然」セットPROJECT_HOME="/."...
ハーゲン・フォン・Eitzen

1
@HagenvonEitzen PROJECT_HOMEがrootに設定されている場合、PROJECT_HOMEを空にするプロシージャはrootを空にします。それが期待される、完全に合理的な動作です。そして、あなたはその最後のドットさえ必要としません。
PSkocik

0

これを行う別の方法:

rm -r "${somevar:-/tmp/or_this_if_somevar_is_empty}"/*

多くの変数置換がありますが、上記のものは「somevar」が空の場合です(その場合、削除を試みます/tmp/or_this_if_somevar_is_empty/*


1
または:rm -fr ${ENV_VAR:?suitably caustic message here}/*が、まだ価値が簡単なテストを破壊するための多くの方法があることを指摘し、ルートディレクトリにマップされないことに価値があるかもしれないチェック:///../usr/who/../..、...
ジョナサン・レフラー

はい。あなたはパラメータ展開を使用するつもりなら、あなたにも使用することができ、実際にはエラーをスローすることを1
デジタルトラウマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.