10

このようなことをbashスクリプトで実行したいと思います。私はを使用してbash 4.1.10います。

# rm -rf /some/path/{folder1,folder2,folder3}

シェル自体からうまく(そして期待どおりに)動作します。必要な3つのフォルダーが削除され、他のすべてのフォルダーは変更されません。

スクリプトに入れると、望ましくないことが起こります。たとえば、私のスクリプト:

#!/bin/bash
set -x
VAR="folder1,folder2,folder3"
rm -rf /some/path/{$VAR}

このスクリプトを実行しても、フォルダーは削除されません。

これは、不要な引用が発生しているためだと思います。を使用してスクリプトから出力#!/bin/bash -x

rm -rf '/some/path/{folder1,folder2,folder3}'

もちろん、'マークのために成功することはできません。

スクリプト内でこれを機能させるにはどうすればよいですか?

4

9 に答える 9

12

マニュアルページによると:

展開の順序は、ブレース展開、チルダ展開、パラメーター、変数および算術展開、およびコマンド置換(左から右に実行)、単語分割、およびパス名展開です。

したがって、これを回避するには、別のレベルの拡張を追加します。

eval "rm -rf /some/path/{$VAR}"
于 2011-07-01T14:13:45.963 に答える
5

evalスクリプトを書いているのですから、トリックを使って保守が難しいコードを書く必要はありません。

VAR="f1,f2,f3"
IFS=,
set -- $VAR
for f; do
  rm -r "/path/to/$f"
done

また

VAR=( f1 f2 f3 )
for f in "${VAR[@]}"; do 
  rm -r "/path/to/$f"
done
于 2011-07-01T14:55:00.463 に答える
2

コードを再配置できる場合はecho、bash でコマンド置換を使用できます。このようなもの:

#!/bin/bash
set -x
VAR=`echo /some/path/{folder1,folder2,folder3}`
rm -rf $VAR
于 2012-05-17T22:33:57.983 に答える
2

いいえ、パラメーター展開の前にブレース展開が発生するためです。など、これを行う別の方法を見つけてxargsください。

xargs -d , -I {} rm -rf /some/path/{} <<< "$VAR"
于 2011-07-01T14:12:40.157 に答える
1

ブレースエキスパンド フラグを有効にする必要があります。

#!/bin/bash
set -B
for i in /some/path/{folder1,folder2,folder3}
do
  rm -rf "$i"
done
于 2013-01-25T18:16:52.710 に答える
0

問題は、スクリプト モードで不要な引用が発生することではなく、フォルダー名を変数に入れ、中かっこの展開が完了した後に変数の内容が展開されることです。
本当にこのようにしたい場合は、次を使用する必要がありますeval

eval "rm -rf /some/path/{$VAR}"
于 2011-07-01T14:12:47.853 に答える
0

(危険な の代わりに)使用できる別のトリックは、サブシェル内のeval単純なものです。echoこれは、たとえば次のように機能します。

paths=`echo /some/path/{folder1,folder2,folder3}`
echo rm -rf $paths

出力:

rm -rf /some/path/folder1 /some/path/folder2 /some/path/folder3

望んだ通りに。(2 行目の "echo" を削除して、実際にrm.


重要な点は、bash はパラメーター展開の前にブレース展開を行うため、コンマ区切りのリスト (ブレースで囲まれているかどうかに関係なく) を変数に入れたくないということですeval。ただし、割り当ての前にサブシェルでブレース展開を行うことにより、スペースで区切られた文字列のリストを変数に入れることができます。

于 2013-02-08T05:42:31.353 に答える
-1

{$VAR}に置き換え${VAR}ます:-)

于 2011-07-01T14:13:49.580 に答える