Shell 退出代码与简单命令不一致

Posted

技术标签:

【中文标题】Shell 退出代码与简单命令不一致【英文标题】:Shell exit codes inconsistants with simple command 【发布时间】:2020-10-09 12:48:40 【问题描述】:

我有一个不应该太难解决的问题,我只是想不出我做错了什么。

我需要测试一个命令是否成功,并且该命令需要从脚本中执行。命令是:

curl 127.0.0.1:5000 &> /dev/null

现在没有服务器在运行,所以它应该总是失败。当我从命令行执行它时它确实会失败。但是,当我从 shell 脚本中运行它时,它会失败,但退出代码是 0。这可能是什么原因?

这是脚本:

if curl 127.0.0.1:5000 &> /dev/null
then
    echo "sucess"
    exit 0
else
    echo "failure"
    exit 1
fi

这是输出:

success
curl: (7) Failed to connect to 127.0.0.1 port 5000: Connection refused

但是,如果我删除重定向,它确实可以按预期工作(我是 shell 代码的初学者,但重定向不应该也重定向退出代码吗?所以我真的不知道这是什么意思)

这是没有重定向的代码,按预期工作(因此表示失败并且退出代码为 1):

if curl 127.0.0.1:5000
then
    echo "sucess"
    exit 0
else
    echo "failure"
    exit 1
fi

有人有想法吗?

编辑: 我在 zsh 中使用sh script_name.sh 启动脚本。当我使用zsh script_name.sh 时,它现在可以正常工作了。我仍然不完全明白为什么,但至少它有效!

【问题讨论】:

有趣,你能分享一下用来做这个的shell吗? 我在zsh中使用命令sh [script_name].sh 哦,现在我尝试使用命令zsh [script_name].sh,它按预期工作!所以我想这是因为如果你用另一个 shell 的命令调用你的脚本,它可能会与退出代码混淆?这很奇怪,因为如果我不使用重定向,它可以与 sh 一起使用。无论如何,现在可以了,谢谢! 你是在哪里学会用sh [script_name].sh 调用脚本的?这会导致很多问题。只需有一个适当的“she-bang”行(在您的情况下为#!/bin/zsh)并使用/path/to/script_name.sh [args] 调用或将脚本存储在$PATH 中包含的目录中。祝你好运。 【参考方案1】:

"&> /dev/null" 在 Bourne shell (sh) 中的解释不同,"&" 将命令置于后台,您可以使用“睡眠 100 &>/dev/null”。既然成功把命令放到后台,那就是成功了,后台命令的退出状态不予理会。​​p>

如果您希望它在 Bourne shell (sh) 中工作,请使用传统语法 ">/dev/null 2>&1",它也可以在较新的 shell 中工作,即更兼容。

在 sh 链接到 bash 的系统中,它将按原样工作。

【讨论】:

感谢您的解释!现在我记得我在某处有效地看到 &> 是 bash 4 的一个功能。

以上是关于Shell 退出代码与简单命令不一致的主要内容,如果未能解决你的问题,请参考以下文章

Linux校验比对文件一致性的shell脚本

linux Shell 中grep+wc取值在shell中的结果与手动执行结果不一致的坑

linux Shell 中grep+wc取值在shell中的结果与手动执行结果不一致的坑

Linux校验比对文件一致性的shell脚本

linuxhistory命令,终端显示和日志文件显示不一致

Python PDB 与命令输出不一致 - 下一条语句未输出