使用 execdir 查找,管道重定向评估太早(引用问题?)

使用 execdir 查找,管道重定向评估太早(引用问题?)

我在工作中使用多个 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',或者只是将命令拆分为多个文件,这通常是引用的简单解决方法问题。

相关内容