如果内置命令,则检查 bash 和 csh
Posted
技术标签:
【中文标题】如果内置命令,则检查 bash 和 csh【英文标题】:Checking in bash and csh if a command is builtin 【发布时间】:2011-11-16 00:22:24 【问题描述】:如果命令是内置的,我如何检查 bash 和 csh?有兼容大多数shell的方法吗?
【问题讨论】:
这确实应该是两个问题。bash
与 POSIX sh 兼容,csh
完全不兼容,shell 完全不同;你不妨问一个关于如何在 Python 和 Java 中做某事的问题。
作为一个几乎每天都只使用 bash 和 csh 并且在他们的第一个谷歌搜索结果中发现这一点的人,我发现这个问题的范围很有帮助。
【参考方案1】:
在 bash 中,您可以使用带有 -t
选项的 type
命令。完整的详细信息可以在bash-builtins
手册页中找到,但相关位是:
类型 -t 名称
如果使用了
-t
选项,type 会打印一个字符串,该字符串是alias
、keyword
、function
、builtin
或file
(如果名称是别名、shell 保留字)之一,函数、内置文件或磁盘文件。如果未找到该名称,则不打印任何内容,并返回 false 退出状态。
因此您可以使用以下检查:
if [[ "$(type -t read)" == "builtin" ]] ; then echo read ; fi
if [[ "$(type -t cd)" == "builtin" ]] ; then echo cd ; fi
if [[ "$(type -t ls)" == "builtin" ]] ; then echo ls ; fi
这将导致输出:
read
cd
【讨论】:
【参考方案2】:这里的其他答案很接近,但如果存在与您正在检查的命令同名的别名或函数,它们都会失败。
这是我的解决方案:
在tcsh
使用where
命令,它给出了所有出现的命令名称,包括它是否是内置的。然后grep
看看其中一行是否说它是内置的。
alias isbuiltin 'test \!:1 != "builtin" && where \!:1 | egrep "built-?in" > /dev/null || echo \!:1" is not a built-in"'
在bash
/zsh
使用type -a
,它给出了所有出现的命令名称,包括它是否是内置的。然后grep
看看其中一行是否说它是内置的。
isbuiltin()
if [[ $# -ne 1 ]]; then
echo "Usage: $0 command"
return 1
fi
cmd=$1
if ! type -a $cmd 2> /dev/null | egrep '\<built-?in\>' > /dev/null
then
printf "$cmd is not a built-in\n" >&2
return 1
fi
return 0
在ksh88
/ksh93
打开一个子shell,以便您可以删除任何别名或同名的命令名称。然后在子shell 中,使用whence -v
。此解决方案中还有一些额外的古老语法来支持ksh88
。
isbuiltin()
if [[ $# -ne 1 ]]; then
echo "Usage: $0 command"
return 1
fi
cmd=$1
if (
#Open a subshell so that aliases and functions can be safely removed,
# allowing `whence -v` to see the built-in command if there is one.
unalias "$cmd";
if [[ "$cmd" != '.' ]] && typeset -f | egrep "^(function *$cmd|$cmd\(\))" > /dev/null 2>&1
then
#Remove the function iff it exists.
#Since `unset` is a special built-in, the subshell dies if it fails
unset -f "$cmd";
fi
PATH='/no';
#NOTE: we can't use `whence -a` because it's not supported in older versions of ksh
whence -v "$cmd" 2>&1
) 2> /dev/null | grep -v 'not found' | grep 'builtin' > /dev/null 2>&1
then
#No-op
:
else
printf "$cmd is not a built-in\n" >&2
return 1
fi
使用解决方案
在您选择的 shell 中应用上述解决方案后,您可以像这样使用它...
在命令行:
$ isbuiltin command
如果命令是内置的,它什么也不打印;否则,它会向 stderr 打印一条消息。
或者你可以在脚本中这样使用它:
if isbuiltin $cmd 2> /dev/null
then
echo "$cmd is a built-in"
else
echo "$cmd is NOT a built-in"
fi
【讨论】:
【参考方案3】:您可以尝试在 csh 中使用 which
或在 bash 中使用 type
。如果某些东西是内置命令,它会这样说;否则,您将在 PATH 中获得命令的位置。
在 csh 中:
# which echo
echo: shell built-in command.
# which parted
/sbin/parted
在 bash 中:
# type echo
echo is a shell builtin
# type parted
parted is /sbin/parted
type
也可能显示如下内容:
# type clear
clear is hashed (/usr/bin/clear)
...这意味着它不是内置的,但 bash 已将其位置存储在哈希表中以加快对其的访问; (一点点)this post on Unix & Linux 中的更多内容。
【讨论】:
【参考方案4】:对于bash
,使用type command
【讨论】:
【参考方案5】:对于csh
,您可以使用:
which command-name
如果它是内置的,它会告诉你。 不确定它是否适用于 bash。 不过,我们小心使用别名。可能有这样的选择。
【讨论】:
以上是关于如果内置命令,则检查 bash 和 csh的主要内容,如果未能解决你的问题,请参考以下文章