返回bash shell的值

问题描述 投票:1回答:4

我正在尝试学习linux bash脚本。我有一个脚本,我想获得此脚本的返回值并将其存储在变量中。

欢迎任何帮助。

先感谢您。

#!/bin/bash
HOST_NAME=$1

{ echo "105" ; sleep 5; } | telnet $HOST_NAME 9761;
bash telnet
4个回答
3
投票

为避免混淆,不要将其视为回报值,将其视为现状 - 退出状态。

在大多数编程语言中,您可以通过捕获函数在变量中返回的内容来捕获函数的返回值,例如,使用类C语言:

int foo() {
    printf("35\n");
    return 7;
}

void main() {
    int var;
    var=foo();
}

在调用var之后main()中的变量foo()将保持值735将被打印到stdout。但是在shell中有类似的代码:

foo() {
    printf "35\n"
    return 7
}

main() {
    local var
    var=$(foo)
}

var将具有值35和未提及的内置变量$?,它始终保持最后一个命令运行的退出状态将具有值7。如果你想复制C行为,其中35转到stdout而var包含7那么那就是:

foo() {
    printf "35\n"
    return 7
}

main() {
    local var
    foo
    var=$?
}

shell函数使用关键字return来报告它们的退出状态的事实最初是令人困惑的,如果你习惯了其他基于Algol的语言,比如C,但是如果他们使用exit那么它会终止整个过程,所以他们不得不使用某些东西很快就会明白它的真正含义。

因此,在使用shell脚本和函数时,请使用“输出”和“退出状态”这两个词,而不是“返回”某些人在某些情况下会假设这两种情况中的任何一种,并且这将避免所有混淆。

顺便说一下,为了避免使事情变得更复杂我在上面说过,$?是一个变量,但它确实是“特殊参数”?的价值。如果你真的想要了解现在的差异,那么请参阅https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameters讨论shell参数,其中包括?#等“特殊参数”,12等“位置参数”,以及HOMEvar等“变量”我上面的剧本。


1
投票

$? shell变量存储返回值,但是对于Linux telnet客户端,这可能没有您想象的那么有用。如果远程主机关闭连接(或发生任何远程或网络错误),则客户端将返回1;如果本地客户端成功关闭连接,则返回0。问题在于编写了许多服务,以便它们发送数据然后自己关闭TCP连接而无需等待客户端:

$ telnet time-b.timefreq.bldrdoc.gov 13
Trying 132.163.96.2...
Connected to time-b-b.nist.gov.
Escape character is '^]'.

58600 19-04-27 13:56:16 50 0 0 736.0 UTC(NIST) *
Connection closed by foreign host.
$ echo $?
1

即使客户端向服务器发送命令以退出TCP流,这仍然会导致远程端关闭连接,结果相同:

$ telnet mail.tardis.ed.ac.uk 25
Trying 193.62.81.50...
Connected to isolus.tardis.ed.ac.uk.
Escape character is '^]'.
220 isolus.tardis.ed.ac.uk ESMTP Postfix (Debian/GNU)
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
$ echo $?
1

所以,无论如何,你都会得到一个1。如果你想要远程脚本的返回值,使用ssh这样会更容易:

$ ssh ssh.tardis.ed.ac.uk "exit 5"
THE TARDIS PROJECT  |  pubpubpubpubpubpubpubpubpub  |  Authorised access only
$ echo $?
5

据我所知,telnet返回零(即成功)的唯一时间是,如果你逃脱并且完全是客户端,就像这样:

$ telnet www.google.com 80
Trying 216.58.210.36...
Connected to www.google.com.
Escape character is '^]'.
^]

telnet> quit
Connection closed.
$ echo $?
0

希望这可以帮助。


1
投票

这取决于你的回报价值。

进程(在类UNIX系统上)可以将一个无符号字节作为退出状态返回给shell,因此它给出的值范围为0-255。按惯例,零表示成功,任何其他值表示失败。

(在较低级别的语言中,如C,您可以获得的不仅仅是退出状态,但在bash中不可见)。

最后一个命令运行的退出状态存储在变量?中,因此您可以从$?获取其值,但是由于许多程序只返回0(它工作)或1(它不起作用),所以没有多大用处。

Bash条件,如ifwhile测试成功(退出代码为0)或失败(退出代码为非零):

if some-command
then
    echo "It worked"
else
    echo "It didn't work"
fi

但是......

如果你的意思是想从脚本中获取输出,那就不一样了。您可以使用以下方法捕获它

var=$(some-command)

但等等,只捕获正常输出,路由到名为stdout(文件描述符1)的流,它不捕获大多数程序写入名为stderr(文件描述符2)的流的错误消息。要捕获错误,您需要将文件描述符2重定向到文件描述符1:

var=$(some-command 2>&1)

输出文本现在位于变量var中。


0
投票

?变量始终存储上一个命令的退出代码。

您可以使用$?检索该值。

一些背景:http://tldp.org/LDP/abs/html/exit-status.html

© www.soinside.com 2019 - 2024. All rights reserved.