在bash中启动可执行文件的顺序


14

如果我test在bash中执行命令,test(评估条件表达式)内置实用程序将启动:

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

但是,从type -a test上面的输出中可以看到,test/ usr / local / bin目录中有另一个,/ usr / bin目录中又有一个。可执行文件如何排序,即始终首选内置命令,然后其余命令取决于$ PATH变量中的目录顺序?另外,是否可以更改可执行文件的启动顺序,例如,如果键入test,则启动/ usr / bin / test而不是bash-builtin test


您可以在调用命令时指定完整路径,例如,/usr/bin/test -f "$file"...
jasonwryan 2014年

@jasonwryan我知道这一点,但是我只是想知道是否有一种方法可以更改可执行文件的启动顺序。
马丁

Answers:


25

最高优先级是bash别名,然后是特殊的内置函数(仅在POSIX模式下),然后是功能,然后是内置函数,然后是中的搜索$PATH

要执行内置函数,请使用builtin test
要执行外部应用程序,请使用显式路径:/bin/test
要忽略函数和别名,请使用command test
要绕过别名,请使用\test或任何其他类型的扩展。

可以通过禁用/启用内置功能enable test

(根据下面的评论更新)
(修复了bash disable内置的不正确的管理员编辑-实际上只有enable


1
@ 1_CR gena2x是正确的。我的答案省略了特殊的内置函数,后者比POSIX的函数优先(尽管某些外壳不兼容; bash仅在POSIX模式下遵从)。
吉尔斯(Gilles)'“ SO-不要邪恶”

1
建议的编辑:当您引用命令(或命令的任何部分)时,如\test'test'或中,别名被禁用tes't'
约翰·库格曼

2
那不是全貌。似乎任何类型的扩展(在ba​​sh手册中,所有的替换,代字号扩展等称为扩展)都将禁用别名。我试过了。
gena2x 2014年

1
从bash手册页中引用:“每个简单命令的第一个单词(如果未加引号,则检查其是否具有别名。如果是,则用别名文本替换该单词。/$,,反引号和=并且上面列出的任何shell元字符或引号都不能出现在别名中。”
约翰·库格曼

2
+1有助于我找到此信息的来源的提示:该信息位于bash手册页中“命令执行”部分第二和第三段的下面。
twan163 '16

6

内置命令始终比外部命令优先。其基本原理是内置命令速度更快(在某些情况下,例如cd或,只有内置命令才能达到预期的效果)。test -o BASH_OPTION

有时,外部命令可能具有内置的shell不具备的功能。在这种情况下,您可以通过提供明确的路径(即包含斜杠)来调用外部命令(这避免了对中顺序的任何关注$PATH)。如果您不想对外部路径进行硬编码,但确实想避免使用内置函数,则可以在bash,ksh和zsh中使用"$(type -P test)"(请注意capital P)。强制使用外部命令的另一种方法是使用内建()或遍历实用程序()。"$(whence -p test)"=testcommandcommand -p test …envenv test …

在zsh中,您可以使用禁用内置函数disable test。这是永久性的(对于当前的Shell或子Shell),直到使用启用了内置功能enable test。在bash中,您可以执行相同的操作enable -n test来禁用和enable test重新启用。

您可以使用别名或函数来强制执行其他命令,例如alias test=/usr/bin/testtest () { /usr/bin/test "$@"; }。如果您有这样的别名,则可以通过引用别名的任何部分来阻止其使用,例如\test将执行常规功能/内置/外部查找。请注意,取决于外壳程序及其设置,在读取功能或执行功能时,功能中的别名定义可能会扩展。如果定义了函数,则可以使用它command test来防止函数查找和别名查找(因此,test除非禁用,否则将调用内置函数)。


难道不env也在这里才合适?
Steven Penny

因此,如果外壳程序从BusyBox运行,那么来自同一BusyBox的其他(通常是外部)命令是否被视为内部命令?例如,我df在第一个位置上添加了完整的PATH,删除了别名“ df”,which df显示了/ opt / bin / df,但是df运行了/ bin / df-> busybox
papo

@papo which df不一定告诉您df运行什么。unix.stackexchange.com/questions/85249/...
吉尔“SO-停止作恶”
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.