引数にアスタリスクを含むプログラムを呼び出す Bash スクリプト

引数にアスタリスクを含むプログラムを呼び出す Bash スクリプト

私はここ 1 時間ほど、非常に単純な bash スクリプトを書こうとしていましたが、こんなに自分が愚かだと感じたことはありませんでした。

つまり、アスタリスクを含む可能性のある文字列のリスト (パッケージ マネージャーのパッケージ セレクタ仕様) があります。これらのアスタリスクを保持するコマンド ラインを構築し、プログラムを呼び出す必要があります。これが私の素朴な試みです。

xs="foo/bar */*"

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

echo呼び出しは次のようになる必要があります

echo   -0 foo/bar    -0 '*/*' 

出力は次のようになります-0 foo/bar -0 */*

PS 実際には最初の行は少し複雑です: xs="$some foo/bar */* $(get_others)"


を含むディレクトリでこのスクリプトを実行するとa/b、代わりに が取得されます-0 foo/bar -0 a/b

最後の行を

echo "$xs_cmd"  # note the quotes

私は理解しましたが、まず第一にそれは私が望んで-0 foo/bar -0 a/b いることではありません。なぜなら今私はechoシングル議論、そしてさらにそれは、拡張がforループ内でより早く起こっている可能性が高いことを私に伝えます。

forでも、ラインを変えることはできない

for x in "$xs"; do  # note the quotes

ループは 1 回だけ繰り返されます: -0 foo/bar */*( は 1 つだけあります-0)。したがって、これらの引用符を追加することは確実にオプションではありません。

ここで元のスクリプトに戻って最初の行を

xs="foo/bar '*/*'"  # note additional single quotes

わかりました-0 foo/bar -0 '*/*'(一重引用符はそこにあってはならない)。

引用符とアスタリスクのバックスラッシュエスケープのあらゆる組み合わせを試したようですが、今何をすればいいのか全くわかりません。

答え1

私はあなたのオリジナルのスクリプトを使用しましたが、最初の行(のみ)に一重引用符を付けて、あなたが望むとおりに動作しました(-0各ファイル パスの前):-

xs='foo/bar */*'

xs_cmd=""
for x in $xs; do
  xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd

ファイル パスに空白が埋め込まれている場合、使用時に問題が発生する可能性があります。その場合は、ループ内のコマンドを次のように変更します。

  xs_cmd="$xs_cmd  -0 \"$x\" "

答え2

何を達成しようとしているかに応じて、以下を引用する必要があります*/*:

xs="foo/bar '*/*'" #!

xs_cmd=""
for x in $xs ; do
    xs_cmd="$xs_cmd  -0 $x "
done

echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"

または配列を使用するか、またはその両方を使用します。

xs=("foo/bar" "*/*") #!

xs_cmd=""
for x in "${xs[@]}"; do
    xs_cmd="$xs_cmd  -0 '$x' " #!
done

echo "$xs_cmd"
eval "echo $xs_cmd"

関連情報