Shell 函数的返回值和其他编程语言不太一样。return 返回的是退出状态码,不是数据本身。要想返回数据,得用其他方式。
return 用于结束函数执行,并返回一个状态码:
check_file() {
if [ -f "$1" ]; then
return 0
else
return 1
fi
}
check_file "/etc/passwd"
if [ $? -eq 0 ]; then
echo "文件存在"
else
echo "文件不存在"
fi
返回值范围是 0-255,0 表示成功,非 0 表示失败。如果不写 return,函数的返回值就是最后一条命令的退出状态。
$? 保存上一个命令或函数的返回值:
is_even() {
if [ $(($1 % 2)) -eq 0 ]; then
return 0
else
return 1
fi
}
is_even 4
echo "返回值:$?"
is_even 7
echo "返回值:$?"
运行结果:
返回值:0
返回值:1
要注意 $? 只保存最近一次的返回值,用完就没了。如果需要多次使用,应该先保存起来:
is_even 10
result=$?
if [ $result -eq 0 ]; then
echo "是偶数"
fi
return 只能返回数字,要返回字符串得用 echo 或 printf:
get_date() {
date '+%Y-%m-%d'
}
today=$(get_date)
echo "今天是 $today"
函数内部 echo 的内容会被捕获到变量中。这种方式很常用,但要注意函数里不要有多余的输出:
get_full_name() {
echo "调试信息:开始处理" # 这行也会被捕获
echo "$1 $2"
}
name=$(get_full_name "张" "三")
echo "姓名:$name"
运行结果:
姓名:调试信息:开始处理
张 三
调试信息混进去了,这是个常见的坑。调试信息应该输出到标准错误:
get_full_name() {
echo "调试信息:开始处理" >&2
echo "$1 $2"
}
这样调试信息会显示在屏幕上,但不会被 $() 捕获。
可以用数组或分隔符来返回多个值:
get_user_info() {
echo "张三:25:北京"
}
info=$(get_user_info)
IFS=':' read -r name age city <<< "$info"
echo "姓名:$name,年龄:$age,城市:$city"
或者用数组:
get_numbers() {
local arr=(1 2 3 4 5)
echo "${arr[@]}"
}
result=$(get_numbers)
read -ra numbers <<< "$result"
echo "第一个数:${numbers[0]}"
echo "所有数:${numbers[@]}"
return 用于函数,exit 用于整个脚本。在函数里用 exit 会直接结束整个脚本:
test_func() {
echo "函数开始"
exit 0
echo "这行不会执行"
}
echo "脚本开始"
test_func
echo "脚本结束" # 这行也不会执行
运行结果:
脚本开始
函数开始
脚本直接退出了,后面的代码都没执行。要区分清楚:函数里用 return,脚本退出用 exit。
$? 获取返回值,要及时保存