我在工作中使用多个 GitHub 帐户,因此我需要修改远程 url 以添加我的工作帐户。我已经弄清楚了递归 find -execdir 以及如何获取/sed/设置远程 url,但我无法将它们组合起来。
我使用 git st 测试了 find 命令,它工作正常:
find . -type d -name ".git" -execdir zsh -c "git st" \;
我测试了 git set 过程,并且工作正常:
git remote set-url origin $(git remote get-url origin | sed 's|https://github|https://my_work_username@github|g')" \
当我将它们组合起来时,效果不太好:
find . -type d -name ".git" -execdir zsh -c "git remote set-url origin $(git remote get-url origin | sed 's|https://github|https://my_work_username@github|g')" \;
我首先收到一个错误,没有 .git 文件夹,并且出现一堆 git 语法错误:
致命:不是 git 存储库(或任何父目录): .git 用法: git remote set-url [--push] [] 或: git remote set-url --add 或: git remote set-url --删除
如果我添加一个 echo,我发现我发出的 git 命令是:
git remote set-url origin
没有参数
我已经没有了解决问题的想法或搜索解决这个问题的术语。
答案1
find . ... -execdir zsh -c "git remote get-url origin $(git ...)" \;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在这里,命令替换位于双引号字符串内,因此在主 shell 中展开,前查找运行。然后它运行在错误的目录中,导致错误。如果启用set -x
并运行该命令,您应该在zsh -c
命令行中看到一个常量字符串。
就像这样:
$ set -x
$ find . -type d -execdir bash -c "echo $RANDOM" \;
+ find . -type d -execdir bash -c 'echo 22924' ';'
22924
22924
...
您需要使用单引号来保护扩展,以便内壳能够看到它们并开始处理它们。
$ find . -type d -execdir bash -c 'echo $RANDOM' \;
+ find . -type d -execdir bash -c 'echo $RANDOM' ';'
4397
21235
...
我认为您基本上可以在这里翻转单引号和双引号,因为 sed 命令不包含任何必须在单引号内的内容:
find . -type d -name ".git" -execdir \
zsh -c 'git remote set-url origin "$(
git remote get-url origin |
sed "s|https://github|https://my_work_username@github|g"
)"' \;
(为了完整起见,还要在命令替换周围加上双引号,以防止在内 shell 命令中进行单词分割。并不是说此处的 URL 可能包含空格或通配符,但这是一个很好的做法。)
如果 sed 命令$
中有类似的内容,并且您需要在单引号字符串中放置单引号,那么您将不得不进行更丑陋的转义,例如'it isn'\''t so'
,或者只是将命令拆分为多个文件,这通常是引用的简单解决方法问题。