bash - 如果存储在局部变量中,函数调用的退出代码将被忽略
问题描述
以下是示例场景:-
定义了一个示例函数,它正在回显一些文本,以及使用 return 设置一些退出代码。还有另一个脚本正在调用此函数。以下是简化代码:-
~/playground/octagon/bucket/test/sample $
pwd
/Users/mogli/playground/octagon/bucket/test/sample
~/playground/octagon/bucket/test/sample $
cat functions.sh
myfunc() {
echo "This is output $1"
return 3
}
~/playground/octagon/bucket/test/sample $
cat example.sh
. functions.sh
function example(){
myfunc_out=$(myfunc $1); myfunc_rc=$?
echo "myfunc_out is: $myfunc_out"
echo "myfunc_rc is: $myfunc_rc"
}
example $1
~/playground/octagon/bucket/test/sample $
sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 3
现在,如果我对用于在 example.sh 中存储函数返回值和退出代码的变量使用局部变量,则退出代码不会正确出现。请在下面找到修改后的 example.sh :-
~/playground/octagon/bucket/test/sample $
cat example.sh
. functions.sh
function example(){
local myfunc_out=$(myfunc $1); local myfunc_rc=$?
echo "myfunc_out is: $myfunc_out"
echo "myfunc_rc is: $myfunc_rc"
}
example $1
~/playground/octagon/bucket/test/sample $
sh example.sh 44
myfunc_out is: This is output 44
myfunc_rc is: 0
解决方案
当你写:
var=$(cmd)
的输出cmd
分配给var
(没有分词)并$?
设置为返回的值cmd
。
当你写:
var=$(cmd1) cmd2
cmd1
被执行并将其输出(没有分词)分配给var
环境中的变量cmd2
,然后执行。 $?
设置为返回的值cmd2
。
当你写:
cmd1 var=$(cmd2)
cmd2
执行时,字符串var=output of cmd2
会进行分词并作为参数传递给cmd1
,并$?
设置为 . 返回的值cmd1
。(在几乎所有情况下,您都希望禁止分词并改为 write cmd1 var="$(cmd2)"
,这将保证只传递一个参数。)
local
是一个命令,并且local myfunc_out=$(myfunc $1)
是第 3 种形式(有一个警告),所以它设置为 .$?
返回的值local
。请注意,如果 的输出myfunc $1
包含空格,则不会进行分词。引用 manpage: Assignment statements may also appear as arguments to the alias, declare, typeset, export, readonly, and local builtin commands
,因此字符串算作变量赋值并且不进行分词。
简而言之,local
有一个退出值,它被用来设置$?
您local
可以使用:
local myfunc_out myfunc_rc
myfunc_out="$(myfunc $1)"; myfunc_rc=$?
请注意,双引号在这里并不是绝对必要的,因为分词不会发生在作业中,但使用它们绝对是一个好习惯。
推荐阅读
- asp.net - 是否可以像 Angular 一样制作 ASP.NET url,即 localhost:5000/#/etc?
- sockets - 客户端上的套接字错误
, 断开 - java - 为什么有时可以有时不能在android oppo上捕获图像
- hellosign-api - HelloSign:如何解决 SameOrigin 错误?
- html - 无论如何,在 Internet Explorer 中没有 activeX 的情况下从本地文件目录加载 pdf 吗?
- postgresql - 自动创建的 PostgreSQL 表与预期不同
- javascript - 对 promise 的异步工作方式感到困惑
- python - 设置 PATH 后无法打开 uiautomatorviewer
- java - 我正在尝试可视化链接列表,我想在头部插入一个节点并将另一个节点推送到下一个
- r - 从出生日期和 r 中的指定时间计算年龄