変数が空であるか設定されていない場合、[ -d $dirname ]が一致するのはなぜですか?これがホームディレクトリの内容を削除するのはなぜですか?

変数が空であるか設定されていない場合、[ -d $dirname ]が一致するのはなぜですか?これがホームディレクトリの内容を削除するのはなぜですか?

わかりました。このコードがあります。

dirname=

if [ -d $dirname ];
 then
 cd $dirname && rm *
fi

ご覧のように、この空の変数があるので、単一の角かっこを含む空の変数を使用すると、すべてのユーザーのホームディレクトリファイルが削除される理由がわかります。

角かっこを使用すると、ユーザーのホームディレクトリファイルは削除されません。

このように

dirname=

if [[ -d $dirname ]];
 then
 cd $dirname && rm *
fi

単一の角かっこと二重角かっこを使用するときの構文の違いについて読みました。

なぜこれが起こるのかわかりますか?

答え1

引数が渡されない場合は、cdデフォルトディレクトリ(ほとんどの場合はユーザーのホームディレクトリ$HOME)に変更されます。

-dこの質問の興味深い部分は、bashや組み込みtest演算[子に何も渡さないときにbashが0で終わるように見えることです(私の考えでは予想外のことです)。

変数を空白に設定すると、dirname実際に次のコマンドが実行されます。

if [ -d ]; then
    cd && rm *
fi

私にとっては、そのブロック内のコードがif実行されることは驚くべきことですが、私のコンピュータでは実際に実行されていることを確認できます。上記の説明で説明したように、testこれは-d演算子として解釈されず、空ではない文字列なので、単にゼロを返します。この動作を防止する1つの方法は、変数を引用符で囲むことです。

if [ -d "$dirname" ]; then
    cd "$dirname" && rm *
fi

この場合、空の場合、ゼロ以外の終了コードを正しく計算する演算子を渡す$dirnameため、ブロック内のコードは実行されません。""-d

答え2

引用されていないコンテンツは$dirnameトークン化の影響を受けます。空の場合は分割されます。削除済み[ -d $dirname ]、合計には合計cd $dirnameのみが残ります。[ -d ]cd

最初は[パラメータが1つだけ表示されます([および間])。この場合のテストは、パラメータが空でない文字列であることを確認することです。-dはい、テストは本当です。 (これはnullを[ -z $var ]テストする方法と似ています$varが、[ -n $var ]まったく機能しません。)

の場合、cd通常のファイルがcdユーザーのホームディレクトリに変更されるため、ここでrm *これが発生します。


を使用すると、通常の命令とは異なり、特別なシェル構造であるため、[[ .. ]]単語の分離は発生しません。[[[

解決策は二重引用符で変数を拡張する、さまざまな理由で、ほとんどの状況でこれを実行したいと思います。このように:

if [ -d "$dirname" ]; then
    cd -- "$dirname" && rm ./*
fi

望むより:

関連情報