5.2.3 读取输入与用户交互(read、select)
读取输入与用户交互(read、select)#
1. 原理与输入流示意#
2. read 基本用法与命令解释#
read var:从标准输入读取一行赋值给变量echo:输出变量内容
#!/usr/bin/env bash
# file: /tmp/read_basic.sh
read name
echo "Hello, $name"
执行:
bash /tmp/read_basic.sh
# 输入: alice
# 预期输出: Hello, alice
3. read 常用参数与完整示例(含默认值/超时/静默)#
-p提示信息-t超时秒数-s静默输入(密码)-n读取指定字符数-r禁止反斜杠转义
#!/usr/bin/env bash
# file: /tmp/read_params.sh
read -p "请输入用户名: " user
read -s -p "请输入密码: " pass
echo
read -t 5 -p "5秒内输入环境(dev/prod): " env
read -n 1 -p "是否继续(y/n): " yn
echo
env=${env:-dev}
echo "user=$user env=$env yn=$yn"
执行:
bash /tmp/read_params.sh
# 预期输出示例: user=alice env=dev yn=y
4. 多变量读取、空输入处理与校验#
#!/usr/bin/env bash
# file: /tmp/read_multi.sh
read -p "输入 host port user: " host port user
host=${host:-127.0.0.1}
port=${port:-3306}
# 简单格式校验:端口是否为数字
if ! [[ "$port" =~ ^[0-9]+$ ]]; then
echo "端口必须为数字" >&2
exit 1
fi
echo "host=$host port=$port user=$user"
执行:
bash /tmp/read_multi.sh
5. 从管道或文件读取(逐行处理)#
#!/usr/bin/env bash
# file: /tmp/read_file.sh
while read -r line; do
echo "line: $line"
done < /etc/hosts
执行:
bash /tmp/read_file.sh
6. select 菜单选择(交互菜单示例)#
select自动生成编号菜单PS3自定义提示符
#!/usr/bin/env bash
# file: /tmp/select_menu.sh
PS3="请选择环境: "
select env in dev test prod quit; do
case $env in
dev|test|prod)
echo "选择: $env"
break
;;
quit)
echo "退出"
break
;;
*)
echo "无效选项"
;;
esac
done
执行:
bash /tmp/select_menu.sh
# 输入序号,如 1
7. 组合示例:交互式部署参数采集脚本#
#!/usr/bin/env bash
# file: /tmp/deploy_input.sh
read -p "服务名(service): " svc
read -p "端口(port,默认8080): " port
port=${port:-8080}
PS3="部署环境: "
select env in dev test prod quit; do
case $env in
dev|test|prod) break;;
quit) exit 0;;
*) echo "无效选项";;
esac
done
if ! [[ "$port" =~ ^[0-9]+$ ]]; then
echo "端口非法: $port" >&2
exit 2
fi
echo "准备部署: service=$svc port=$port env=$env"
执行:
bash /tmp/deploy_input.sh
8. 常见排错与定位#
- 脚本卡住不继续:检查是否等待输入
bash strace -p <PID> 2>&1 | tail -n 3 # 若看到 read(...),说明等待输入 - read 读取不到管道内容:避免在子 shell 中丢失变量
bash # 错误示例:管道会创建子 shell,变量不回传 echo "a" | while read -r line; do var="$line"; done echo "$var" # 空 # 正确做法:使用重定向 while read -r line; do var="$line"; done < /tmp/file - 含反斜杠的路径被转义:使用
-r
bash read -r path
9. 练习题#
- 编写脚本:输入用户名与端口,端口非数字则提示错误并退出。
- 编写菜单:选择
start/stop/restart/quit,选择后输出对应动作。 - 从
/etc/hosts读取每行,统计非注释行数量并输出。