呼叫參數中帶有星號的程式的 Bash 腳本

呼叫參數中帶有星號的程式的 Bash 腳本

我花了大約一個小時嘗試編寫一個非常簡單的 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

只會使循環迭代一次:(-0 foo/bar */*有一個-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"

相關內容