Bash

Bash腳本:避免將單引號添加到字元串

  • November 18, 2021

我正在嘗試獲取一個函式的輸出並將其傳遞給另一個函式。

set -x
OUTPUT=$(git diff --name-only --diff-filter=AM develop... | sed 's/.*/"&"/')
./bin/phpcs $OUTPUT

我的主要問題是第一個函式返回文件列表,文件可能包含空格。所以我將它們用雙引號括起來,但是當我將它傳遞給我的其他函式時,會添加其他單引號。

輸出:

++ git diff --name-only --diff-filter=AM develop...
++ sed 's/.*/"&"/'
+ OUTPUT='"test file.php"
"testfile.php"'
+ ./bin/phpcs '"test' 'file.php"' '"testfile.php"'

呼叫的主要最終目標等於:

./bin/phpcs "test file.php" "testfile.php"

您的問題是您在 . 輸出的文本中添加雙引號git diff。這會破壞路徑名並使正確解析文件列表變得更加困難,尤其是在任何路徑名恰好包含引號的情況下。

您在跟踪輸出中看到的單引號只是添加了 by bash,以便更容易查看字元串是如何分隔的(例如,顯示"testfile.php""testfile.php"是三個單獨的參數)。請記住,shell 的跟踪輸出是調試輸出,旨在為您提供 shell 正在做什麼的提示,通常不是 shell 執行的實際程式碼。


要安全地使用git diff --name-only輸出的路徑名,請考慮使用該-z選項。這會導致git將路徑名輸出為以空分隔的列表。然後,您可以使用xargs -0對該列表的元素執行任何命令:

git diff --name-only -z --diff-filter=AM develop... |
xargs -0 ./bin/phpcs

您還可以將文件列表讀入數組。例如,在bash外殼中:

readarray -d '' -t names < <( git diff --name-only -z --diff-filter=AM develop... )

./bin/phpcs "${names[@]}"

這顯然依賴於git diff不輸出太多名稱

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