Linux命令-read(Bash 内建读取输入)

Linux命令-read(Bash 内建读取输入)

    • 命令语法
    • 常用选项
    • 场景化实例
      • [1. 基本交互式输入](#1. 基本交互式输入)
      • [2. 密码静默输入](#2. 密码静默输入)
      • [3. 带超时的输入](#3. 带超时的输入)
      • [4. 读取到数组](#4. 读取到数组)
      • [5. 限制读取字符数](#5. 限制读取字符数)
      • [6. 解析配置文件](#6. 解析配置文件)
      • [7. 使用 -r 避免反斜杠转义](#7. 使用 -r 避免反斜杠转义)
      • [8. 实际脚本:用户注册向导](#8. 实际脚本:用户注册向导)
    • 退出状态
    • 最佳实践

快速参考read 是 Bash 内建命令,用于从标准输入读取一行数据并存入一个或多个变量。read 是 Shell 脚本交互式编程的核心,支持超时、静默输入、数组读取等高级特性,是编写用户友好脚本的必备工具。

提示read 是 Bash 内建命令(type read 显示 read is a shell builtin),执行速度极快,无需额外进程。

命令语法

bash 复制代码
read [选项] [变量名 ...]

常用选项

选项 说明
-p "提示" 显示提示信息
-t 秒数 超时时间,超时返回非零退出码
-s 静默模式,输入不显示(适合密码)
-a 数组名 将输入按单词存入索引数组
-n 字符数 读取指定字符数后自动结束
-r 不转义反斜杠(推荐始终使用)
-e 使用 Readline 库(支持行编辑)
-d 分隔符 用指定字符作为行结束符
-N 字符数 读取指定字符数(忽略分隔符)
-u fd 从指定文件描述符读取

场景化实例

1. 基本交互式输入

bash 复制代码
#!/bin/bash
# 简单交互示例
echo "请输入您的姓名:"
read name
echo "您好,$name!欢迎使用本系统。"

# 使用 -p 一步完成
read -p "请输入您的年龄:" age
echo "年龄:$age 岁"

2. 密码静默输入

bash 复制代码
#!/bin/bash
# 安全输入密码
read -s -p "请输入数据库密码:" db_pass
echo        # 换行
read -s -p "请再次输入确认:" db_pass_confirm
echo

if [ "$db_pass" != "$db_pass_confirm" ]; then
    echo "两次输入不一致!"
    exit 1
fi
echo "密码设置成功"

3. 带超时的输入

bash 复制代码
#!/bin/bash
# 超时示例:5 秒内必须响应
read -t 5 -p "是否继续安装?(y/n) [默认 y]:" choice

exit_code=$?
if [ $exit_code -ne 0 ]; then
    echo -e "\n超时未响应,默认继续安装"
    choice="y"
fi

case "$choice" in
    y|Y|"") echo "开始安装..." ;;
    n|N)    echo "已取消安装"; exit 0 ;;
    *)      echo "无效输入"; exit 1 ;;
esac

4. 读取到数组

bash 复制代码
#!/bin/bash
# 读取多个单词到数组
read -p "请输入服务器列表(空格分隔):" -a servers

echo "共输入 ${#servers[@]} 台服务器:"
for i in "${!servers[@]}"; do
    echo "  [$i] ${servers[$i]}"
done

# 遍历执行任务
for server in "${servers[@]}"; do
    echo "正在连接 $server ..."
done

5. 限制读取字符数

bash 复制代码
#!/bin/bash
# 菜单选择:只需按一个键
read -n 1 -p "请选择操作 [A]添加 [D]删除 [Q]退出:" option
echo

case "$option" in
    a|A) echo "执行添加操作" ;;
    d|D) echo "执行删除操作" ;;
    q|Q) echo "再见!"; exit 0 ;;
    *)   echo "无效选项" ;;
esac

6. 解析配置文件

bash 复制代码
#!/bin/bash
# 读取配置文件(格式: KEY=VALUE)
config_file="/etc/myapp/settings.conf"

while IFS='=' read -r key value; do
    # 跳过空行和注释
    [[ -z "$key" || "$key" =~ ^# ]] && continue
    # 去除首尾空格
    key=$(echo "$key" | xargs)
    value=$(echo "$value" | xargs)
    echo "配置项: $key = $value"
    declare "$key=$value"
done < "$config_file"

7. 使用 -r 避免反斜杠转义

bash 复制代码
#!/bin/bash
# 对比 -r 的影响
echo "测试不含 -r:"
echo "第一行\n第二行" | while read line; do
    echo "读取到: $line"
done

echo "测试含 -r:"
echo "第一行\n第二行" | while read -r line; do
    echo "读取到: $line"
done

# -r 模式下 \n 保持原样,被视为字面字符

8. 实际脚本:用户注册向导

bash 复制代码
#!/bin/bash
# 多步骤交互式注册脚本

echo "===== 用户注册向导 ====="

read -p "用户名(字母数字,3-20位):" username
if [[ ! "$username" =~ ^[a-zA-Z0-9_]{3,20}$ ]]; then
    echo "用户名格式不正确!"
    exit 1
fi

read -s -p "密码(至少8位):" password
echo
if [ ${#password} -lt 8 ]; then
    echo "密码长度不足!"
    exit 1
fi

read -p "邮箱地址:" email
read -t 10 -p "输入验证码(10秒内,按回车跳过):" captcha
echo

echo "注册信息确认:"
echo "  用户名: $username"
echo "  邮箱:   $email"
echo "  密码:   ****"

read -n 1 -p "确认提交?(Y/n):" confirm
echo
if [[ "$confirm" == "y" || "$confirm" == "Y" || "$confirm" == "" ]]; then
    echo "注册成功!"
fi

退出状态

bash 复制代码
# read 退出码检测
read -t 3 -p "输入:" input
case $? in
    0)   echo "正常读取: $input" ;;
    1)   echo "遇到 EOF" ;;
    142) echo "超时" ;;  # 128 + 14(SIGALRM)
esac

最佳实践

始终使用 -r :防止反斜杠被意外转义。IFS= 配合 read 可保留行首尾空白。

bash 复制代码
# 推荐写法:安全读取文件每一行
while IFS= read -r line || [[ -n "$line" ]]; do
    echo "处理: $line"
done < input.txt

# 避免的写法(丢失反斜杠)
while read line; do
    echo "$line"
done < input.txt
相关推荐
researcher-Jiang1 小时前
高性能计算之MPI:第一次MPI并行程序设计练习
linux·运维·服务器
Wireless_wifi61 小时前
Why Choose IPQ9574 for Your WiFi 7 Solution
linux·人工智能·5g
MYMOTOE62 小时前
国内对标腾讯 WorkBuddy 的桌面 AI 智能体软件大全
linux
小c君tt2 小时前
linux学习笔记1
linux·笔记·学习
CCPC不拿奖不改名4 小时前
Redis 工程化部署深度解析
linux·服务器·数据库·redis·深度学习·缓存·rag
鱼很腾apoc5 小时前
【Linux】第7期 进程间通信 (IPC) 详解:管道 (匿名 / 命名) + System V
linux·服务器·c语言·学习·进程间通信·ipc
毒爪的小新5 小时前
踩坑实录 | RAG知识库完整搭建-Milvus2.4+BGE大中文AI模型嵌入
linux·人工智能·ai·milvus·rag
2023自学中6 小时前
imx6ull 开发板, mame 模拟器,运行游戏 测试
linux·游戏·嵌入式·开发板
是个西兰花6 小时前
Linux:进程信号
linux·运维·服务器