函数、输入输出与环境协作
前半讲函数定义、参数与返回值;后半讲 read / echo / printf、命令替换与简单重定向。
一、函数:定义与调用
shell
# 方式一
function 函数名 {
命令序列
}
# 方式二(常见写法)
函数名() {
命令序列
}
# 示例
greet() {
echo "Hello, $1!"
}
greet "World"二、函数参数与特殊变量
在函数内同样可用 $1…$9、${10}…、$#、$@、$* 等,含义与脚本全局一致:
| 变量 | 含义 |
|---|---|
$1…$9 | 前九个参数;第十个起用 ${10} |
$# | 参数个数 |
$* | 所有参数,一个整体 |
$@ | 各参数独立(常写作 "$@") |
$$ | 当前进程 PID |
$! | 最近一个后台进程 PID |
$? | 上条命令退出码 |
$- | 当前 Shell 选项 |
通过 echo 返回「数据」(供调用方 $() 捕获):
shell
get_msg() {
echo "Hello"
}
msg=$(get_msg)
echo "$msg"注意:echo 若用于返回值,函数内不要再输出调试信息到标准输出,否则会混在一起。
三、返回值:return 与退出码
return 只宜返回 0–255 的退出状态(成功/失败分类),与 C 语言返回值不同:
shell
file_exists() {
if [ -f "$1" ]; then
return 0
else
return 1
fi
}
if file_exists "test.txt"; then
echo "文件存在"
else
echo "文件不存在"
fi需要返回字符串或更大整数时,用 stdout(echo/printf)配合 $( ) 捕获,见上一节。
四、函数书写习惯
- 函数名小写加下划线,避免与系统命令冲突。
- 内部校验参数是否传入、是否合理。
- 错误可用
return非 0,或打印到 stderr(echo "msg" >&2),不要与正常数据 stdout 混淆。
五、输入:read
shell
read [选项] 变量名常用选项:
| 选项 | 作用 |
|---|---|
-p "提示" | 显示提示再读入 |
-t 秒 | 超时 |
-n 个数 | 读满若干字符即结束 |
-s | 不回显(密码) |
示例:
shell
read -p "请输入姓名:" name
echo "你好,$name"
read -t 60 -p "请输入用户名:" myUsername
read -t 60 -s -p "请输入密码:" myPassword
echo
result="用户名:${myUsername}\n密码:${myPassword}"
echo -e "$result"六、输出:echo 与 printf
shell
echo [选项] 内容或 ${变量}
printf "格式" 参数 ...echo -e:解释\n等转义(依实现略有差异,GNU bash 常见)。echo -n:不换行。printf:格式化更稳定,适合脚本里要对齐列、控制小数位。
shell
echo "Hello"
echo -n "Hello"
printf "Name: %s, Age: %d\n" "Bob" 20七、重定向与从文件读
shell
echo "test" > file.txt # 覆盖
echo "append" >> file.txt # 追加
cat < file.txt # 将文件作为标准输入旧稿「将内容写入不到文件中」应为笔误,实际含义是:将内容写入文件即用 > / >>。
八、命令替换:把命令输出当作值
shell
current_dir=$(pwd)
file_count=$(ls | wc -l)
legacy=`ls | wc -l` # 反引号形式,嵌套时不如 $( ) 清晰九、与「引入外部脚本」的关系
把公共函数、配置变量放在单独文件,在主脚本里用 source 或 . 引入,可实现模块化;详见 健壮性与模块引入。
