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
您可能有多个返回值来描述错误,因此您可以检查等于2
、3
或255
的值。
但是您的 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 脚本 - 从控制台获取字符串并将其存储到变量中的主要内容,如果未能解决你的问题,请参考以下文章