【问题标题】:bash - how is * interpreted in aliases?bash - * 如何在别名中解释?
【发布时间】:2015-01-01 13:19:36
【问题描述】:

[注意 - 我使用 bash 函数解决了我遇到的问题,但我想了解为什么我最初的尝试没有奏效。]

我在 Windows 中运行 git,并使用 Git Bash 命令行应用程序来管理存储库。 我有几个存储库,我经常想一次全部提取。以前我只是通过在命令行中输入以下内容来做到这一点:

for i in *; do cd $i; git pull --rebase; cd ..; done;

为了节省时间,我决定为此创建一个别名。因此,我在主目录中创建了一个 .bashrc 文件(在我的情况下为 C:/git)并添加了该行

alias pr="for i in *; do cd $i; git pull --rebase; cd ..; done;"

但是,这根本不起作用,输出是

sh.exe" cd: /etc/profile.d/*.sh: No such file or directory

随后 git 抱怨它不在存储库中。对于单个调用,输出将重复 20 次以上。 MinGW 文件系统的根目录是我将 git 安装到 (C:/Program Files (x86)/Git) 的位置,上面的 /etc 来自哪里。

现在,我最终通过在我的 .bashrc 文件中创建一个函数解决了这个问题,如下所示:

pr(){
    for i in *
    do
        cd $i
        git pull --rebase
        cd ..
    done
}

所以,我的问题解决了,但我确实想了解为什么我最初的方法不起作用。很明显,我不明白关于别名的一些东西,大概是弄乱了 'i in *' 位。我的期望是 bash 会替换别名映射到的字符串,然后对其进行评估,但这似乎并不那么简单。

【问题讨论】:

  • 如果您在 pr 别名分配和资源之前添加 echo "i=$i" 会发生什么?
  • 另外,您可能希望将其设为短路条件cd "$i" && git pull --rebase && cd ..。否则你可能会得到一些奇怪的结果($i 不是一个目录,但你仍然运行git 并向上移动一个级别,等等......)
  • @BroSlow - 就像下面的答案一样,您的echo 建议让我走上了正确的道路。也感谢&& 的建议。

标签: bash


【解决方案1】:

我没有对此进行全面分析,但这与您的别名中的$i 扩展的时间有关。你这样做的方式,$i 可能会在别名创建期间被初始化。在函数版本中,它将在运行时进行解释。尝试按照您显示的方式定义别名,然后运行:

alias pr  # show how the alias is defined

如果你用单引号定义别名,Bash 会很高兴地推迟 $-variables 的扩展。以下应该与您的功能一样有效。

alias pr='for i in *; do cd $i; git pull --rebase; cd ..; done;'

【讨论】:

  • 有人解释一下-1
  • +1 这绝对正确;双引号内的$i 在定义别名之前已扩展。定义函数时,不会在单引号内或(正如 OP 发现的那样)在函数体中执行参数扩展。
  • 啊哈,看来你是对的。 alias pr 给出以下输出:alias pr='for i in *; do cd /etc/profile.d/*.sh; git pull --rebase; cd ..; done;' 所以这是 $i 被扩展的问题,而不是像我想的那样与 * 有关。我已经验证它也适用于单引号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-16
  • 2010-09-08
  • 2016-06-08
  • 2018-03-04
  • 2016-09-03
相关资源
最近更新 更多