Bash

如何使用帶空格的字元串插值在 bash 腳本中程序生成命令?

  • September 16, 2019

我正在嘗試創建一個簡單的腳本,它使用這樣的月份列表:

(一月二月)

要生成並執行此命令:

python ExpenseManager.py -p Inputs/Jan\ 2019\ Debit.CSV Inputs/Jan\ 2019\ Credit.CSV -p Inputs/Feb\ 2019\ Debit.CSV Inputs/Feb\ 2019\ Credit.CSV

這是我為此編寫的程序:

#!/usr/bin/env bash
clear
months=(Jan Feb)
args=()
for month in ${months[@]}; do
 args=(${args[@]} -p "Inputs/${month}\\ 2019\\ Debit.CSV" "Inputs/${month}\\ 2019\\ Credit.CSV")
done
python ExpenseManager.py "${args[@]}"
exit 0

這在理論上是有效的。當我回顯生成的命令時,我得到了我想要的確切命令:

python ExpenseManager.py -p Inputs/Jan\ 2019\ Debit.CSV Inputs/Jan\ 2019\ Credit.CSV -p Inputs/Feb\ 2019\ Debit.CSV Inputs/Feb\ 2019\ Credit.CSV

現在,當我複制/粘貼該程序創建的命令並執行它時,它工作正常。但是,當我讓 Bash 執行命令時,它包含了我用來在 Bash 中包含轉義反斜杠的反斜杠:

命名空間(文件對=

$$ [‘Inputs/Jan', ‘2019', ‘Debit.CSV’, ‘Inputs/Jan', ‘2019', ‘Credit.CSV’ $$,$$ ‘Inputs/Feb\ 2019
Debit.CSV’, ‘Inputs/Feb\ 2019\ Credit.CSV’ $$]

我已經嘗試了幾種解決方案來讓它工作:

  • 我嘗試將 args 設為單個字元串並以此為基礎
  • 我試過用單引號將 args 括起來,並在空格周圍使用雙引號,如下所示:

參數=( $ {args[@]} -p ‘Inputs/ $ {month}" “2019” “Debit.CSV “Inputs/${month}” “2019” “Credit.CSV”)

  • 我嘗試使用這樣的引號分隔需要空格的 arg 的每個部分:
  args=(${args[@]} -p "Inputs/${month}" "2019" "Debit.CSV" "Inputs/${month}\ 2019\ Credit.CSV")

我在這里和其他地方查看了其他解決方案,但似乎沒有任何效果。因此,與其繼續停留在這個問題上,我希望有人能告訴我讓 Bash 執行這個程序建構的內插命令的魔術嗎?

不要echo用來查看正在執行的命令。它在解析後列印命令,即在應用和刪除引號和轉義符之後);因此,如果輸出echo包含引號和/或轉義符,就像您希望在原始命令行中看到的那樣(即在解析之前),則表明存在嚴重錯誤。比較這兩個echo命令的輸出:

$ month=Jan
$ var="Inputs/${month}\\ 2019\\ Debit.CSV"
$ echo $var
Inputs/Jan\ 2019\ Debit.CSV
$ echo Inputs/Jan\ 2019\ Debit.CSV
Inputs/Jan 2019 Debit.CSV

首先,轉義被列印出來,表明它們沒有被解析、應用和刪除。在第二個中,它們消失了,表明它們已被解析、應用和刪除。

那麼,如何解決呢?兩條規則:1)不要在變數中加上引號或轉義符(除非在奇怪的情況下,字元串要經過額外級別的解析),2)相反,在所有變數引用周圍加上雙引號(包括${args[@]})(再次,有一些奇怪的例外)。此外,您可以使用array+=("new" "elements").

這是固定的腳本:

#!/usr/bin/env bash
clear
months=(Jan Feb)
args=()
for month in "${months[@]}"; do
 args+=(-p "Inputs/${month} 2019 Debit.CSV" "Inputs/${month} 2019 Credit.CSV")
done
python ExpenseManager.py "${args[@]}"
exit 0

引用自:https://unix.stackexchange.com/questions/541902