【问题标题】:Confused about use of return status code shell script?对使用返回状态码 shell 脚本感到困惑?
【发布时间】:2015-12-26 18:38:04
【问题描述】:

在一本书中,我正在阅读下面一行

ls "$1" 2>/dev/null | grep "$1" 2>/dev/null 1>&2

当用脚本编写时 - 书中说“执行命令以检查作为命令行参数传递的文件是否存在。标准错误被重定向到/dev/null(unix黑洞) ,标准输出通过1>&2重定向到标准错误。因此,该命令不会产生任何输出或错误消息;它唯一的目的是设置命令返回状态值$?" p>

但是运行代码:

if [ $? -eq 0 ]

否则我会不知道吗,我已经尝试过在开始时不使用 cmd,并且在不影响结果的情况下使用它。我相信作者会出于某种目的而写作。我想不通是什么?

【问题讨论】:

  • 你能在书名中添加更多上下文吗?
  • 截图有用吗?
  • 请立即查看。有帮助吗?
  • 这里有问题吗?第一行不产生任何输出,只是设置返回状态。第二行检查返回状态,但不完整,也没有输出,因此您看不到该检查的任何可见效果。
  • @ChrisDodd 检查更新

标签: linux bash shell unix


【解决方案1】:

这看起来像一本非常糟糕的书,它给出的代码是任何理智的人都不会写的,用来说明通常在 shell 脚本中以完全不同的方式使用的概念。

行:

ls "$1" 2>/dev/null | grep "$1" 2>/dev/null 1>&2

如前所述——除了设置返回码之外,它没有任何可见的效果。你的问题是关于这详细做什么来获得返回码或其他什么?

行:

if [ $? -eq 0 ]

是检查前一个命令的返回码的不完整片段。它是不完整的,因为没有thenfi,没有它们,shell 会将其作为语法错误拒绝并且不执行任何操作(如果您在提示符下键入上述内容,您将获得辅助提示,告诉您shell 正在等待更多输入以获取完整的命令)。所以没有更多的代码就没有明显的效果。更完整的东西,例如:

if [ $? -eq 0 ]; then echo YES; else echo NO; fi

将根据该返回码输出YESNO

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。

【讨论】:

  • 克里斯我试图上传完整的代码作为截图,我卡住了为什么这是 "ls "$1" 2>/dev/null | grep "$1" 2>/dev/null 1> &2" 需要检查 $?.... 的值。
  • @asad:这不是——它是一个随机的无用命令,它设置$? 的值,就像所有命令一样。 if 检查它设置的$? 的值。
  • Chris 相信你一定有一本学习unix shell编程的好书推荐吧?
  • 有了屏幕……嗯,书单,没关系。 sh 会将 last 命令运行 (grep) 的返回码保留为 $?,然后由 if 检查 - 但 then 在单独的行上。上下文对我们来说非常重要,有时不是一句话就能说明一切
  • if 命令一直延伸到fi 命令——shell 将继续读取行,直到它得到fi,并且在那之前不会执行任何操作。在if..fi 命令中,换行符和; 完全相同。
猜你喜欢
  • 1970-01-01
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2018-11-27
  • 2023-01-01
  • 1970-01-01
相关资源
最近更新 更多