在Bash中循环别名

时间:2018-10-13 13:07:46

标签: bash alias

我在aliases中定义了几个~/.bash_aliases。他们使用不同的环境变量设置调用同一命令,因此我不必每次都键入这些命令。 aliases在交互式shell中可以正常工作。

alias cmd1='VAR=setting1 cmd $@'
alias cmd2='VAR=setting2 cmd $@'

现在,我想将所有这些命令变体一起调用,每个变体都带有“列表”选项。为此,我在Bash中设置了以下脚本:

#!/bin/bash
shopt -s expand_aliases
source ~/.bash_aliases
CMDs='cmd1 cmd2'
for cmd in CMDs ; do
    $cmd list
done

但是,此脚本会产生错误

  

“找不到命令”

每个调用的alias

。我已经尝试了所有种类的变体,但看不到Bash的内部原理在这里如何工作。 -欢迎提供任何见解!

2 个答案:

答案 0 :(得分:4)

别名不带参数。发生的情况是,定义别名时$@扩展为 nothing ,因此其行为与alias cmd1='VAR=setting1 cmd '完全相同。简单地将“参数”附加到别名的扩展名上。

改为定义函数:

cmd1 () {
    VAR=setting1 cmd "$@"
}

cmd2 () {
    VAR=setting2 cmd "$@"
}

此外,别名扩展发生在参数扩展之前 ,这解释了您所看到的错误。一旦$cmd扩展到cmd1bash就不会尝试将cmd1扩展为别名。它只是将其视为找不到的命令的名称。一旦应用所有扩展,函数查找就会发生,因此您的循环

CMDs='cmd1 cmd2'
source ~/.bash_aliases
for cmd in CMDs ; do
  "$cmd" list
done

现在可以使用。发现cmd1是一个函数,因此以list作为参数执行。 (您可能希望将函数以不同的名称存储在文件中,但这并不重要。尽管有.bash_aliases这个名称,但它必须是有效的脚本,而不仅仅是别名的集合。)< / p>

答案 1 :(得分:0)

您可以使用using System; using System.Linq; using NodaTime; using NodaTime.Extensions; class Test { static void Main() { Instant min = Instant.FromUtc(1930, 1, 1, 0, 0, 0); Instant max = Instant.FromUtc(2100, 1, 1, 0, 0, 0); foreach (var zone in DateTimeZoneProviders.Tzdb.GetAllZones()) { var initialStandard = zone.GetZoneInterval(min).StandardOffset; var zoneIntervals = zone.GetZoneIntervals(min, max); var firstChange = zoneIntervals.FirstOrDefault(zi => zi.StandardOffset != initialStandard); if (firstChange != null) { Console.WriteLine(zone.Id); Console.WriteLine($"Initial standard offset: {initialStandard}"); Console.WriteLine($"First different standard offset: {firstChange}"); Console.WriteLine(); } } } }

eval

注意 #!/bin/bash shopt -s expand_aliases alias xxx="printf '%s\n'" alias yyy="echo" for cmd in xxx yyy do eval $cmd foo bar bla done 是一种野兽,非常不安全。查阅Bash FAQ 048以获得指导。