在一本书中,我正在阅读下面这行
ls "$1" 2>/dev/null | grep "$1" 2>/dev/null 1>&2
当用脚本编写时 - 书中说“执行命令以检查作为命令行参数传递的文件是否存在。标准错误被重定向到 /dev/null
(unix 黑洞),标准输出通过 1>&2
重定向到标准错误。因此,该命令不会产生任何输出或错误消息;它唯一的目的是设置命令返回状态值 $?
。"
但是运行代码:
if [ $? -eq 0 ]
否则我会不知道吗,我一开始就尝试过不使用 cmd,也尝试过使用它,但对结果没有影响。我相信作者会出于某种目的而写作。我想不通什么?
最佳答案
这看起来像一本非常糟糕的书,它提供了任何正常人都不会编写的代码,以糟糕地说明通常在 shell 脚本中以完全不同的方式使用的概念。
行:
ls "$1" 2>/dev/null | grep "$1" 2>/dev/null 1>&2
与描述的一样——除了设置返回代码外,它没有任何可见的效果。您的问题是关于获取返回码或其他内容的详细信息吗?
行:
if [ $? -eq 0 ]
是一个不完整的片段,用于检查前一个命令的返回码。它是不完整的,因为没有 then
或 fi
,没有它们 shell 将拒绝它作为语法错误并且不做任何事情(如果你在提示符下键入上面的内容,你会得到第二个提示,告诉你 shell 正在等待更多输入以获得完整的命令)。所以没有更多的代码就没有明显的效果。更完整的东西,比如:
if [ $? -eq 0 ]; then echo YES; else echo NO; fi
将根据该返回码输出YES
或NO
。
执行以 ls
开头的 6 行的更明智的方法是:
if [ ! -e "$1" ]; then
echo "$1: not found"
exit 1
fi
至于 ls
行的实际作用,它以 $1
中的名称作为参数运行 ls
(列出文件),然后使用 grep
在该列表中搜索相同的文件名。
因此,如果文件不存在,ls 会给出错误并且不输出任何内容,因此 grep 失败(将 $?
设置为 1)。如果文件名存在且不是目录,则 grep 将成功(将 $?
设置为 0)。最后,如果文件名存在并且是一个目录,它将搜索该目录的内容,查找与子字符串同名的任何文件或子目录——这可能只是一个错误。此外,如果 $1
是以 -
开头的字符串,它会做一些相当无用且不可预测的事情。
总的来说,这是一个永远不应该编写的 shell 脚本的主要示例——任何提交了这样一个怪物的学生都应该立即得到 F。
关于linux - 对返回状态代码 shell 脚本的使用感到困惑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34474103/