Bash

如何將“$@”或數組連接到一個字元串

  • August 4, 2021

我正在嘗試實現這個助手 bash 功能:

ores_simple_push(){(

 set -eo pipefail
 git add .
 git add -A

 args=("$@")

 if [[ ${#args[@]} -lt 1 ]]; then
     args+=('squash-this-commit')
 fi

 git commit -am "'${args[@]}'" || { echo; }
 git push

)}

with: git commit -am 'some stuff here',我真的不喜歡輸入引號,所以我想做:

ores_simple_push my git commit message here gets put into a single string

這樣就變成了:

git commit -am 'my git commit message here gets put into a single string'

有沒有一種理智的方法可以做到這一點?

在 Korn/POSIX-like shells 中,雖然"$@"擴展為所有位置參數,分隔(在列表上下文中),但"$*"擴展為位置參數與 ¹ 的第一個字元(帶有某些 shell 的字節)$IFS或 SPC 的串聯(如果$IFS未設置或如果$IFS設置為空字元串,則沒有任何內容。

而在ksh/// zsh(支持數組的類 Bourne 的 shell bashyash中,對於"${array[@]}"vs也是一樣的"${array[*]}"

in zsh,與/中的while"$array"相同,與 相同。在中,與 相同。"${array[*]}"``ksh``bash``"${array[0]}"``yash``"${array[@]}"

在中,您可以使用參數擴展標誌:加入zsh帶有任意分隔符的數組元素,例如加入空間。它不僅限於單個字元/字節字元串,您還可以使用參數擴展標誌來在分隔符規範中使用轉義序列或變數(例如加入 TAB 並加入 的內容)。另請參見加入換行符的快捷方式標誌(與 相同)。j``"${(j[ ])array}"``"${(j[ and ])array}"``p``"${(pj[\t])array}"``"${(pj[$var])array}"``$var``F``pj[\n]

所以在這裡:

ores_simple_push() (
 set -o errexit -o pipefail
 git add .
 git add -A

 args=("$@")

 if [[ ${#args[@]} -lt 1 ]]; then
     args+=('squash-this-commit')
 fi

 IFS=' '
 git commit -am "${args[*]}" || true
 git push
)

或者只是POSIXly:

ores_simple_push() (
 set -o errexit
 git add .
 git add -A

 [ "$#" -gt 0 ] || set square-this-commit

 IFS=' '
 git commit -am "$*" || true
 git push
)

對於某些 shell(包括 bash、ksh93、mksh 和 bosh,但不包括 dash、zsh 或 yash),您也可以"${*-square-this-commit}"在此處使用。

為了完整起見,在 in 中bash,要使用任意字元串連接數組(相當於 zsh’s joined=${(ps[$sep])array}),您可以執行以下操作:

IFS=
joined="${array[*]/#/$sep}"
joined=${joined#"$sep"}

(這是假設語言環境中的有效文本;如果不是,則如果 的內容在與其餘部分連接時最終形成有效文本,$sep則第二步可能會失敗)。$sep


¹ 作為歷史記錄,在 Bourne shell 中,無論$IFS

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