如何区分内置util和外部util? (例如回声)

如何区分内置util和外部util? (例如回声)

有些命令既作为内置命令又作为外部实用程序提供。举echo个例子。在我运行 Bash 3.2 的机器 (macOS) 上,

$ type echo
echo is a shell builtin

跑步man bash | less --pattern='^ *echo +\['节目:

echo [-neE] [arg ...]

但是运行man 1 echo会显示 的不同实现的手册页echo,具有不同的签名:

echo [-n] [string ...]

我能够-e成功使用,所以我必须运行内置程序,大概就是这样/bin/echo

$ which echo
/bin/echo

其他实现在哪里,以及我如何区分内置函数和外部实用程序(例如printf

更新/修正感谢@Gilles 的澄清。证据就在布丁里!

$ /bin/echo -e "\tabc"
-e \tabc

$ echo -e "\tabc"
        abc

答案1

要查明命令是否内置,请运行type

$ type echo
echo is a shell builtin

type本身是一个内置命令,并且知道内置了哪些命令。(在 bash 中,内置命令可以被禁用,并且type如果内置命令被禁用,将正确报告命令不是内置的。)type报告如果您使用该命令将执行的任何内容名称 — 别名、函数、内置或外部命令。

which是一个外部命令,报告外部命令的位置。它不知道任何关于别名、函数或内置函数的信息。它甚至可能不会报告正确的外部命令,具体取决于您的设置。忘记which并使用type即可

我必须运行内置程序,大概就是这样/bin/echo

不!根据定义,内置命令不是外部命令。与所有其他内置函数一样,实现内置函数的代码echo位于/bin/bash./bin/echo是一个与内置命令同名的外部命令echo

当命令同时作为内置命令和外部命令存在时,使用其名称调用内置命令。在按顺序列出的目录中,命令名称的优先顺序是别名、函数、内置命令、外部命令$PATH。如果出于某种原因您想要强制执行外部命令,请使用其完整路径。

答案2

已知名称(词)

查找提供 a 的内容word(假设该单词是别名、函数或命令的有效名称)的最佳方法是使用-a以下选项type

$ type -a echo
echo is a shell builtin
echo is /bin/echo

如果还定义了函数和别名,您可能会得到与此类似的列表:

$ type -a echo
echo is aliased to `echo "A new echo"'
echo is a function
echo ()
{
    printf '%s\n' "A function echo" "$@"
}
echo is a shell builtin
echo is /bin/echo

它们的打印顺序是优先顺序。在上面打印的列表中:将首先执行别名。如果删除别名 ( unalias),则执行该函数。等等等等。

例子:

$ echo "test"
A function echo
A new echo
test

引用通常绕过别名:

$ \echo         # or "e"cho, "echo", 'e'"ch"o, and many other variations.
A function echo
test

这相当于取消别名设置:

$ unalias echo; echo test
A function echo
test

该函数可以通过 unset (选项 -f)来删除:

$ unset -f echo 
$ type -a echo
echo is a shell builtin
echo is /bin/echo

可以通过启用来关闭别名:

$ enable -n echo
$ type -a echo
echo is /bin/echo

并且可以移动外部(外壳外部)实用程序:

# mv /bin/echo /bin/echo-aside
# type -a echo
bash: type: echo: not found

内置函数列表

如果内置函数的名称未知,可以将其列出。

在 bash 中,有一个(也许?)名称奇怪的命令,称为enable( builtinin ksh)。不带选项
调用enable将打印enabled内置函数列表:

$ enable
enable .
enable :
enable [
enable alias

有一些选项可以打印所有 ( -a)、仅启用(-p或不打印任何内容)和特殊(由 Posix 定义)内置函数 ( -s)。

删除单词“enable”并使其成为一行列表:

$ echo $(enable -s | cut -d" " -f2)
. : break continue eval exec exit export readonly return set shift source times trap unset

$ echo $(enable -p | cut -d" " -f2)
. : [ alias bg bind break builtin caller cd command compgen complete compopt continue declare dirs disown echo enable eval exec exit export false fc fg getopts hash help history jobs kill let local logout mapfile popd printf pushd pwd read readarray readonly return set shift shopt source suspend test times trap true type typeset ulimit umask unalias unset wait

相关内容