bash shell 脚本 - 从控制台获取字符串并将其存储到变量中

Posted

技术标签:

【中文标题】bash shell 脚本 - 从控制台获取字符串并将其存储到变量中【英文标题】:bash shell script - getting a string from the console and store it into a variable 【发布时间】:2017-09-22 08:11:51 【问题描述】:

我正在执行一些从控制台生成字符串的操作,例如我正在执行以下操作:

./eqagent add-target target-type=kafka events-servers=localhost:9999

并收到此消息:

Equalum 代理返回以下错误:代理目标 已经存在

我想捕获它并将其存储到一个变量中,然后使用 if 语句将其用作条件。

【问题讨论】:

【参考方案1】:

试试这个:

message=$(./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1)

varname=$(some command) 语法称为命令替换,并扩展为括号内包含的命令生成的字符串。

2>&1 部分是一个重定向,它采用文件描述符 2 的输出(通常称为“标准错误”)并使其转到与文件描述符 1 相同的输出(通常称为“标准输出” )。这可以确保您的进程替换将收集两者的输出,因为命令替换只捕获标准输出,而不是标准错误。

如果你只是想测试成功失败,你可以使用命令的返回码,像这样:

if
  ./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1
then
  # Success!
else
  # Failure...
fi

如果在命令执行后立即调用,返回码也可以在特殊的 shell 变量 $? 中获得,并且 vy 约定成功时为零,失败时为非零值。

【讨论】:

【参考方案2】:

在我看来,您的问题就像一个典型的X-Y problem:您的问题是您想在命令失败时采取行动,而当这种情况发生时,它会将返回值设置为非零值。所以你真正想要的是使用$? 变量。这是您的用例的一般示例:

$ ./command
Argh... Failure!
$ echo $?
1

所以你可以这样做:

if [ $? -eq 1 ]; then
    echo "It failed :("
fi

您可能有多个返回值来描述错误,因此您可以检查等于23255 的值。

但是您的 shell 允许您以更简洁的方式做到这一点:

# prints 'it failed :(' only when command's result ($?) is non-null
./command || echo "it failed :("

所以对于您的示例,您应该能够使用:

./eqagent add-target target-type=kafka events-servers=localhost:9999 || echo "it failed :("

如果您的命令真的只使用字符串返回错误状态(不是很好),您可以使用以下命令检查 exact 字符串:

output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999)
if [ "$output" == "Equalum agent has returned the following error: The agent target already exists" ]; then
    echo "it failed :("
fi

最后你可以检查是否包含子字符串(如果这不是你的程序的唯一输出):

error_msg="The agent target already exists"
if [ -z "$output##*$error_msg*" ] ;then
    echo "it failed :("
fi

上述语法适用于大多数 shell(bash、ksh、dash…)。

如果您在 $output 变量中没有得到您期望的输出,这很可能是程序在 stderr 而不是 stdout 上打印错误,您可以使用以下技巧连接两个输出:

output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999 2>&1)

最后在实际用例中,您可能需要两者的混合:

error_msg="The agent target already exists"
output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999)
if [ $? -ne 0 ]; then
    echo -n "it failed "
    if [ -z "$output##*$error_msg*" ] ;then
        echo "; because target already exists. :-s"
    else
        echo ":-("
    fi
fi

【讨论】:

if [ ! $? -eq 0]; then 将失败,因为“0”后面没有空格。另外为什么不改用if [ $? -ne 0 ]? -ne = 不等于 第一个是错字,第二个是没有充分理由的,因为这是我的手指写的 ☺ 都更正了,谢谢。 另外,output=$(./eqagent add-target target-type=kafka events-servers=localhost:9999) 不会捕获任何错误消息(假设错误消息被发送到 stderr),您也应该捕获它 已经在 In case you don't get the output you expect in the $output variable, which is likely if the program prints error on stderr instead of stdout, you can join both outputs 部分介绍了?【参考方案3】:

你不能这样做吗:

variable=`your-command`

然后使用 $variable 做任何你想做的事情

【讨论】:

【参考方案4】:
var="$((./eqagent add-target target-type=kafka events-servers=localhost:9999)2>&1)" # We must also make sure that stderr goes into stdin so we can capture the error message. That is what 2>&1 does
if [ $? -ne 0 ];then # Eg, it failed
    echo "the output is stored in '$var'." 
    echo "$var" > error_log.txt
fi

这应该可以解决问题

编辑:忘记添加标准错误重定向...

【讨论】:

括号的内部集没有用,因为您无用地生成了一个额外的外壳,并且与管道重定向无关。

以上是关于bash shell 脚本 - 从控制台获取字符串并将其存储到变量中的主要内容,如果未能解决你的问题,请参考以下文章

使用bash shell脚本从文件中查找和提取特定字符串后的值?

求Bash Shell脚本,判定文件是不是存在。

需要 bash shell 脚本来从文件中读取名称值对

Linux学习笔记:bash颜色显示及shell脚本相关

shell脚本的漂亮打印

shell脚本获取MD5值