外壳脚本:转义参数列表,包括哈希符号 (#)



我为自己编写了一个自定义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...

我已经查看了手册页并进行了一些 SO 搜索,但我找不到有关转义 # 符号作为参数的特定问题的任何内容。

这可能吗?

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

有两种规范的方法可以做到这一点:

  • 只需要引用。每个接受命令行参数的Unix工具都需要这样做。
  • 让程序从 stdin 读取提交,而不是使用 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)

只是玩了一下

脚本

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
➜  ~ 

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

最新更新