命令替换作为 I/O 重定向的目标

命令替换作为 I/O 重定向的目标

我试图将命令的输出作为重定向的目标,如下所示:

echo .envrc >> $(git config --global core.excludesfile)

但我却收到此错误,.~/.gitignore_global的输出在哪里git config --global core.excludesfile

bash: ~/.gitignore_global: No such file or directory

我能够使用以下方法让它工作eval

eval "echo .envrc >> $(git config --global core.excludesfile)"

为什么以前不起作用,有更好的方法吗?

答案1

问题是全局 git 配置包含一个文字~(波形符),当作为命令替换的结果发出时,shell 不会解释该文字。您的全局 git 配置可能包含以下内容:

[core]
    excludesfile = ~/.gitignore_global

您的第一个命令相当于以下构造,它使用单引号来防止 shell 解释该~字符:

echo .envrc >> '~/.gitignore_global'

使用eval修复了这个问题,因为它会导致(重新)解释其字符串参数(在本例中,是上面的行),包括波形符扩展,这会产生预期的命令:

echo .envrc >> /home/your_user/.gitignore_global

解决此问题的另一种方法是确保全局 git 配置中的值是完整路径:

git config --global core.excludesfile ~/.gitignore_global

在这种情况下,shell 将扩展~/home/your_user,因此全局 git 配置文件的内容将如下所示:

[core]
    excludesfile = /home/your_user/.gitignore_global

答案2

最好不要在交互式 shell 之外使用这样的 tildas。 (Shell脚本通常使用$HOME环境变量)。如果必须,更好的方法是安全地进行扩展,但这并不容易:https://stackoverflow.com/questions/3963716/how-to-manually-expand-a-special-variable-ex-tilde-in-bash/29310477#29310477

如果它只是一个一次性命令,并且您知道git config --global core.excludesfile评估结果是什么并且评估它是安全的,那么您的解决方案就很好。

相关内容