Gnu/Linux 这句话的含义

Gnu/Linux 这句话的含义

当我运行这些命令时,Gnu/Linux 实际上在做什么?

cd; ls /Bin/g* &> /dev/null; echo $?

最终输出为0。

答案1

如果目的是确定g目录中是否存在以该字母开头的名称/Bin,那么更好的方法是在bashshell 中,

shopt -s nullglob
set -- /Bin/g*
if [ "$#" -ne 0 ]; then
    printf 'There are %d names starting with "g" in /Bin\n' "$#"
    echo 'These are those names:'
    printf '\t%s\n' "$@"
else
    echo 'No names in /Bin start with "g"'
fi

假设您所在的系统正在运行bash...

0如果有名称与模式匹配,则命令集输出,如果没有与该模式匹配的名称,或者某些目录权限不允许,/Bin/g*则将输出非零值(可能2,也许,但至少非零)生成列表。1ls

一开始的cd是相当无趣的,并且可能不需要(删除此命令会产生影响的情况是相当人为的)。它将您的当前目录更改为任何值,或者如果未设置,则更改$HOME为由/etc/passwd(或等效数据库)定义的主目录。HOME

在执行命令之前ls,shell 会将/Bin/g*模式扩展为匹配名称的列表。如果您有权读取 的目录列表/Bin,并且/Bin目录中存在以字母 开头的名称g,那么这些名称的列表将替换作为 的参数的模式ls。如果没有匹配项,或者您没有正确的访问权限/Bin,则模式将按原样保留。

执行时ls,它会获取 shell 扩展提供给它的参数列表,/Bin/g*并尝试列出这些名称。鉴于这些名称存在,并且您有权列出任何子目录/Bin字母开头的g命令ls最终将成功终止并返回退出状态0。如果名字是这样的话不是存在,或者如果其中一个名称引用了您无权列出其内容的子目录,则它将失败并返回非零退出状态(在这些情况下GNUls返回)。2

&>/dev/null是一个重定向,在bashshell 中,会将标准输出流和标准错误流重定向到/dev/null.运行时ls,这意味着该命令的所有输出和所有错误都将被丢弃(/dev/null是一个特殊的设备文件,写入时会丢弃所有数据)。重定向&>运算符不是标准的,最好写成>/dev/null 2>&1,即“将标准输出重定向到/dev/null,然后将标准错误重定向到标准输出所在的位置”。从技术上讲,此步骤甚至在 shell 扩展/Bin/g*通配模式之前就已发生。

最终echo $?输出最近的退出状态。这将是 的退出状态ls(或者可能是由于未能扩展模式而导致的错误代码,或者可能是由于在 中找不到而根本/Bin/g*无法运行而导致的错误代码,请参见下文)。ls$PATH

有两个 shell 选项会影响这一点:

  1. 如果nullglob在当前 shell 会话中设置该选项,则模式/Bin/g*将为完全移除而不是被保留。这意味着它将ls在没有参数的情况下运行,并且它将列出当前的目录(之后可能是您的主目录cd)。如果您有权读取当前目录,则此操作将会成功。如果您无权读取目录内容,ls将返回非零退出状态(在这种情况下GNUls将返回)。1

  2. 如果failglob设置了 shell 选项并且没有名称与模式匹配/Bin/*,则会抱怨,no match: /Bin/g*并且您会得到非零退出状态(可能1;甚至ls根本不会运行)。

    由于是 shell 产生错误消息,并且 shell 的标准错误流是不是发送到/dev/null(请记住,这只是ls重定向的输出流,在这种情况下甚至不会运行)此错误消息将在最终打印ls之前打印在您的终端中。echo $?1

一个 shell 变量会影响这一点:

  • 当 shell 扩展未加引号的值时,该IFS变量生效。这就是您在最后一步 ( echo $?) 中所做的事情。当 shell 扩展$?为能够使用正确的值进行调用时,它首先使用 中的字符作为分隔echo符将值拆分为单词。$IFS默认情况下,$IFS是一个空格、一个制表符和一个换行符。

    如果IFS要设置为字符串(这些是if using和 GNU012的可能值),那么 shell 会将值( 的退出状态)拆分为空字符串(因为该值将被视为分隔符split on),并且将在没有参数的情况下调用,产生一个单独的换行符作为输出。$?bashls$?lsecho

    为了避免这种不幸的情况,您可以使用echo "$?"(注意 的双引号$?)。

不包括:

  • PATHls以及如果在 中找不到会发生什么和不会发生什么$PATH,以及为什么这不会影响cdecho
  • 所有与实际执行命令相关的事情,fork+exec等。
  • 别名扩展或覆盖任何工具的 shell 函数cdls或者echo
  • 在非bashshell 中会发生什么以及为什么?
  • 的效果set -f

相关内容