【问题标题】:Shell script > double quote a parameter, ONLY if it existsShell脚本>双引号参数,仅当它存在时
【发布时间】:2017-02-15 07:13:01
【问题描述】:

背景:我们目前有一个项目,需要将多个git 存储库克隆到一个父文件夹中。我正在尝试编写一个脚本,以便我可以在所有子目录中运行git 操作,以使其更易于管理(例如./gitall.sh status / add / reset / commit -m "Foobar" / push /等等。

脚本对所有操作都运行良好,直到我尝试执行 ./gitall.sh push

我收到每个目录的错误fatal: remote part of refspec is not a valid name in,因为有效的命令是git -C somedir push "" "" "" ""git 结尾的双引号)。 注意参数需要双引号,以便捕获带有空格的参数。

gitall.sh

find ./repo-* -type d -depth 0 -exec bash -c "git -C {} \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"" \;

是否有双引号参数,仅当它存在时? (或者无论如何告诉git 忽略尾随双引号?)

【问题讨论】:

  • 如果你有这么多 git 存储库,需要自动与它们交互,你可能需要重新考虑你的存储库结构。 Consider submodules.
  • 如果你发现自己需要同时提交多个仓库,那么你使用 Git 是错误的。如果您在多个存储库中进行了更改,并且它们在语义上属于一起,因此您希望将它们一起提交,那么它们首先不应位于不同的存储库中。如果您有单独的存储库,它们应该独立地工作,不需要另一个存储库来了解它的历史。
  • 谢谢大家!这就是我最终使用的。 gist.github.com/nickgrealy/…

标签: git bash shell


【解决方案1】:

在 bash 中传递未知数量参数的正确方法是使用"$@"。此外,您不需要显式调用bash,因为它会使您需要引用参数的方式复杂化。

这将自动引用所有参数:

#!/bin/bash
find ./repo-* -type d -depth 0 -exec git -C {} "$@" ';'

再上一步,如果您只需要当前级别的目录条目,则无需调用find。匹配模式末尾的/ 将只选择目录:

#!/bin/bash
for d in repo-*/; do
    [ -d "$d" ] && git -C "$d" "$@"
done

(请注意,如果您没有任何与该模式匹配的目录,则循环将使用文字参数 repo-*/ 执行一次;[ -d "$d" ] 将防止在这种情况下调用 git)。

最后,您可能需要考虑使用Google's repo tool 而不是您自己的解决方案来管理多个 git 存储库。它非常强大且易于使用。

【讨论】:

  • 如果没有匹配到repo-*/,它将运行git -C repo-*/。也许是存在检查?
  • @Schwern 确实会;为了完整起见,我添加了-d 防范,并澄清了注释。
【解决方案2】:

问题是您将额外的参数传递给git push。每个"" 都由shell 传递给git,后者认为它有7 个参数,但最后4 个是空字符串。

您要查找的是"$@""$@" 等价于"$1" "$2" ...

不需要所有额外的引用,也不需要bash -c"$@" 将在 shell 脚本中展开。

另请注意,调用 find 不适用于 GNU find,因此请使用 BSD find 的完整路径。

#/bin/sh

/usr/bin/find ./repo-* -type d -depth 0 -exec git -C {} "$@" \;

【讨论】:

  • Never parse the output of ls。它会例如当目录名称包含空格时会出错。
  • @SirAthos 好的,谢谢。必须有一种更简单的方法来遍历 shell 中的目录。
【解决方案3】:

您正在关注"$@",并且有更好的方法来做您正在做的事情:

find -name .git -prune -execdir git "$@" \;

您可以添加-maxdepth 1 或其他任何内容来进一步限制 find 命令的探索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-31
    • 2011-03-26
    • 2011-10-22
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多