如果内置命令,则检查 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 会打印一个字符串,该字符串是aliaskeywordfunctionbuiltinfile(如果名称是别名、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的主要内容,如果未能解决你的问题,请参考以下文章

shell自动补全功能:bash和zsh

如何列出所有的 Bash Shell 内置命令 | Linux 中国

Bash基础——内置命令

Bash内置命令与关键字

linux shell 内置命令的作用,存放在哪里

解析 Bash 内置时间的输出