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

如何防止bash使用内置命令?,bash,sh,built-in,Bash,Sh,Built In,我正在尝试修复一个使用echo的脚本,即使用内置命令而不是命令,如何防止这种情况发生 我知道我可以做/bin/echo来强制使用它,但我不想硬编码路径(为了可移植性) 我想用一些东西作为: $ECHO=`which echo` $ECHO -e "text\nhere" 但是哪个echo返回:“echo:shell内置命令” 我最终定义了一个echo函数,它使用@Kenster推荐的env。这样,我就不需要在脚本中修改对echo的调用 echo() { env echo $* } #

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

我知道我可以做
/bin/echo
来强制使用它,但我不想硬编码路径(为了可移植性)

我想用一些东西作为:

$ECHO=`which echo`
$ECHO -e "text\nhere"
但是
哪个echo
返回:“echo:shell内置命令”


我最终定义了一个
echo
函数,它使用@Kenster推荐的
env
。这样,我就不需要在脚本中修改对echo的调用

echo() {
  env echo $*
}

# the function is called before the built-in command.
echo -en "text\nhere"

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

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

$ env echo foo
您可以通过使用
strace
在运行
echo
vs
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)                           = ?

您可以禁用内置回显:

enable -n echo

现在只需执行
回显任何内容
即可运行外部版本。它只影响当前脚本进程,因此您可以在脚本中安全地执行它

'内置命令而不是命令'WTF'。我相信,有些命令(如
echo
)可以相当可靠地硬编码路径。如果您担心可移植性,请使用
printf
,没有任何形式的
echo
@MichaelJaros非内置
echo
支持
-e
添加转义序列和
-n
防止拖尾新行。已删除(且不正确)的答案建议使用
命令内置:
命令echo…
。这不起作用,因为
命令
绕过shell函数,但不绕过内置命令。我在这里提到这一点是为了帮助那些无法阅读已删除答案并可能尝试使用
命令的人。我最终使用了您的解决方案,但使用了一个函数来简化实现:
echo(){env echo$*}
效果非常好!酷,我不知道。
enable
是内置命令吗?它在
sh
中工作吗?
enable
是bash中内置的(当然,除非您
enable-n enable
)。它在POSIX
sh
中不起作用,因为POSIX没有内置与外部的真正概念。当我
内置
启用
在一起时,首先想到的是
启用-n启用
:D。