我正在尝试实现这个 helper 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'
有没有一个明智的方法来做到这一点?
答案1
在类似 Korn/POSIX 的 shell 中,当"$@"
扩展为所有位置参数时,分开(在列表上下文中),如果未设置或则"$*"
扩展为位置参数与第一个字符(某些 shell 中的字节)$IFS
或 SPC 的串联$IFS
没有任何 if$IFS
设置为空字符串。
在ksh
// zsh
/ (具有数组支持的类似 Bournebash
的shell)中, vsyash
也是如此。"${array[@]}"
"${array[*]}"
在zsh
,中与 /"$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}"
在此处使用。
为了完整起见,在 中bash
,要连接具有任意字符串的数组(相当于 zsh 的joined=${(ps[$sep])array}
),您可以执行以下操作:
IFS=
joined="${array[*]/#/$sep}"
joined=${joined#"$sep"}
(假设在区域设置中是有效文本;如果不是,则当 的内容与其余部分连接时最终形成有效文本时,$sep
第二步可能会失败)。$sep
1 作为历史记录,在 Bourne shell 中,它们与 SPC 结合在一起,无论$IFS
答案2
实际上这似乎有效,但我不知道为什么:
git commit -am "${args}" || { echo; }