如何防止bash使用内置命令?

时间:2015-04-09 13:55:26

标签: bash sh built-in

我正在尝试修复使用echo的脚本,即使用内置命令而不是命令,我该如何防止这种情况?

我知道我可以/bin/echo强制使用它,但我不想对路径进行硬编码(为了便携性)。

我想用的东西是:

$ECHO=`which echo`
$ECHO -e "text\nhere"

但是which echo返回:“echo:shell内置命令”。


我最终定义了一个使用echo的{​​{1}}函数,正如@Kenster推荐的那样。这样我就不需要在脚本中修改echo的调用。

env

2 个答案:

答案 0 :(得分:7)

使用env程序。 Env是一个命令,可以启动另一个可能已修改环境的程序。因为env是一个程序,所以它无法访问shell内置函数,别名等等。

此命令将运行echo程序,在命令路径中搜索它:

$ env echo foo

您可以在运行strace vs echo时使用env echo监控系统调用来验证这一点:

$ strace -f -e trace=process bash -c 'echo foo'
execve("/bin/bash", ["bash", "-c", "echo foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f153fa14700) = 0
foo
exit_group(0)                           = ?

$ strace -f -e trace=process bash -c 'env echo foo'
execve("/bin/bash", ["bash", "-c", "env echo foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f474eb2e700) = 0
execve("/usr/bin/env", ["env", "echo", "foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f60cad15700) = 0
execve("/usr/local/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/local/bin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/sbin/echo", ["echo", "foo"], [/* 16 vars */]) = -1 ENOENT (No such file or directory)
execve("/bin/echo", ["echo", "foo"], [/* 16 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f0146906700) = 0
foo
exit_group(0)                           = ?

答案 1 :(得分:6)

您可以禁用内置回声:

enable -n echo

现在只需执行echo anything即可运行外部版本。它只影响当前脚本进程,因此您可以在脚本中安全地执行此操作。