2017-08-12 15 views
3

数日前、私のインターンのうちの1人が誤ってこのコードをコピーしてbashのnode.jsにコピーしようとすると、私のラボのサーバーが深刻な被害を受けました。中括弧拡張内のスペース

$ rm -rfv /usr/{bin/node,lib/node,share/man /*/node.*}; 

彼らは削除するディレクトリをリストアップするbrace expansionを試してみましたが、ディレクトリの区切り(/)間のスペースに注意してください。これにより、sudoが適用されたため、サーバー上のすべてのファイルが削除されました。 私はこのコマンドを自分の仮想マシンで試して、rm -rf /とほぼ同等であることを確認しました。

bashがこの声明を解釈する方法については混乱しています。似たようなことをする単純で非破壊的なコマンド(拡張のための区切りとして働くスペース)を作成しようとすると、私はそれを取り除くことができないようです。私は、最初のコマンドを試してみましたが、bashでforループで:

$ for f in /usr/{bin/node,lib/node,share/man /*/node.*}; do echo $f; done 

/にNode.jsの ディレクトリ内のいくつかの内容を列挙されています。これは、 rmの特別な機能ではないことを確認する必要があります。

しかし、私はこのような何かをしようとすると:

それは私が単一行の電子に、各文字を期待 echoの近くに構文エラーになり
$ for f in {a,b c,d e}; echo $f 

私はいくつかの調査をしましたが、この現象を説明するものは見つかりませんでした。 誰かが最初のコマンドで、bashはこのコマンドをどのように解釈しましたか教えてください。


p.s. zshに 'forループテスト'のバージョンが動作しないことがわかりました。本当の 'rmテスト'を試みたことはありません。怖いです。

あなたが \ -escapeあなたのブレース展開の一部であるすべてのスペース必要

答えて

4

$ printf '%s\n' {a,b\ c} 
a 
b c 

ブレース展開のみ作業:

  • 彼らはどちらもどちらもシングルだも二重引用(あなたはその部分を持っている)

  • 彼らは単一の単語シェルによって(トークン)(あなたの試みは及ばなかった場所それはだ)と認識している - 文字個々\とスペースの引用のために、したがって必要。あなたは何を意味するのか、このなし

bashブレークは複数引数にブレース展開されるように、とブレース展開は起こりません - 以下を参照してください。あなたが見ることができるように

$1=/usr/{bin/node,lib 
$2=/ 
$3=node,share 
$4=/ 
$5=man 
$6=/* 
$7=/ 
$8=node.*} 

    bash/usr/{bin/node,lib/node,share/man /*/node.*}を解析する方法については

    : 次はあなたに(より良い何が起こるかを証明するために省略実際のグロブで)結果の引数を伝えます

  • エスケープされていないスペースは、スペースで区切られた単語の分割を引き起こし、中括弧の意味を複数の引数。得られた引数/*

  • 一つは、残念ながら、ルートディレクトリ内のすべての(非隠された)アイテムと一致し、したがってsudo rmに渡されたときに大混乱を天下。