【问题标题】:Shell script: escaping list of parameters including hash symbol (#)Shell 脚本:转义参数列表,包括井号 (#)
【发布时间】:2016-07-06 21:51:18
【问题描述】:

我为自己编写了一个自定义的 shell 脚本,让我更容易将代码提交到 Github。

最近,我想开始使用 Github 的功能,通过在提交消息中包含问题的编号来自动关闭问题:

# Would automatically close #1 on push
git add .
git commit -m "Closes issue #1 ..."
git push

但是,我的脚本的设置方式是,它使用 $* 获取所有参数,但这会自动删除 # 符号之后的任何内容,因为这是 shell 脚本中的注释。

commit() {
  # Print out commands for user to see
  echo "=> git add ."
  echo "=> git commit -m '$*'"
  echo "=> git push --set-upstream origin $current_branch"

  # Actually execute commands
  git add .
  git commit -m "$*"
  git push --set-upstream origin $current_branch
}

现在我可以在 commit 'Closes issue #1 ...' 中加上引号,但这有点烦人……我专门设置了我的脚本,这样我就可以轻松编写:commit Whatever message I want to put in here...

我查看了手册页并进行了一些搜索,但我找不到任何关于将 # 符号作为参数转义的具体问题。

这可能吗?

【问题讨论】:

  • 是否使用$@ 代替$* 修复它?
  • @TomFenech:很遗憾,没有,我也试过了,但它仍然将# 之后的所有内容视为评论。
  • 它适用于我 "$*" : set -- 'This' 'message' 'contains' '#2' 'and' 'more'; git commit -m "$*"

标签: bash shell parameters escaping


【解决方案1】:

# 之后的任何内容都被 shell 解释为注释,因此它不会传递给函数。这发生在函数执行之前。该功能无法防止这种情况发生。

有两种规范的方法:

  • 只需要引用。每个接受命令行参数的 Unix 工具都需要这个。
  • 让程序从标准输入读取提交,而不是使用read -r input。然后,您可以只运行 commit 并输入消息。

这些都是很好的解决方案,因为它们是简单、熟悉、透明、健壮、惯用的 Unix,可以直接推理。 与 Unix 合作总是比反对它更好。

但是,如果您更喜欢复杂、不熟悉、不透明、易碎的特殊情况,您可以使用神奇的别名和历史记录:

commit() {
  echo "You wrote: $(HISTTIMEFORMAT= history 1 | cut -d ' ' -f 2-)"
}
alias commit="commit # "

这是一个例子:

$ commit This is text with #comments and mismatched 'quotes and * and $(expansions)
You wrote: commit This is text with #comments and mismatched 'quotes and * and $(expansions)

【讨论】:

  • 其实我什至没有考虑过使用read input。我可以把它变成一个功能齐全的迷你脚本,而不是触发一次性命令。
【解决方案2】:

只是玩了一下

脚本

commit() {
  echo "$*"
}

脚本的使用和输出

➜  ~ commit "whatever you want #1 for some reason" 
whatever you want #1 for some reason
➜  ~ commit 'whatever you want #1 for some reason'
whatever you want #1 for some reason
➜  ~ commit whatever you want \#1 for some reason 
whatever you want #1 for some reason
➜  ~ commit whatever you want #1 for some reason 
whatever you want
➜  ~ 

因此,如果您不想引用消息,则需要使用 \(反斜杠)转义哈希,这实际上是一个常规转义字符

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多