shell脚本学习笔记----7(输入/输出、文件与命令执行)

本文深入探讨Bash脚本中read命令的高级应用,包括如何与用户交互、处理文件输入及限定字符读取。同时,解析重定向运算符的作用,如标准输入输出的修改、文件追加及管道的高效利用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

软件设计原则里,标准输入/输出(Standard I/O)包括标准输入(standard input)、标准输出(standard output)以及 标准错误输出(standard error)。分别代表了程序的数据来源,数据出口,以及报告问题的地方。程序应该不知道也不在意其输入与输出背后是哪种设备,这些设备可能是文件、终端、网络连接甚至是另一个执行中的程序。

7.1 使用read读取行

[xudong@localhost ~]$ x=abd; printf "x is now '%s'. Enter new value: " $x; read x
x is now 'abd'. Enter new value: PDQ
[xudong@localhost ~]$ echo $x
PDQ

read命令是一个非常重要的bash命令,用于从键盘中输入文本,并且可以和用户进行交互;该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY,read的参数比较少使用的比较多的几个参数包括:-a(用于数组),-p(给出输入的提示符),-t(指定读取值时等待的时间单位是秒),-s(不显示输入的值,一般用于密码的输入);当然read也可以不使用参数。

Read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s八个选项。

-a :将内容读入到数值中

echo -n "Input muliple values into an array:"
read -a array
echo "get ${#array[@]} values in array"

-d :表示delimiter,即定界符,一般情况下是以IFS为参数的间隔,但是通过-d,我们可以定义一直读到出现执行的字符位置。例如read –d madfds value,读到有m的字符的时候就不在继续向后读,例如输入为 hello m,有效值为“hello”,请注意m前面的空格等会被删除。这种方式可以输入多个字符串,例如定义“.”作为结符号等等。

-e :只用于互相交互的脚本,它将readline用于收集输入行。读到这几句话不太明白什么意思,先跳过。

-n :用于限定最多可以有多少字符可以作为有效读入。例如echo –n 4 value1 value2,如果我们试图输入12 34,则只有前面有效的12 3,作为输入,实际上在你输入第4个字符‘3’后,就自动结束输入。这里结果是value为12,value2为3。

-p :用于给出提示符,在前面的例子中我们使用了echo –n “…“来给出提示符,可以使用read –p ‘… my promt?’value的方式只需一个语句来表示。

-r :在参数输入中,我们可以使用’/’表示没有输入完,换行继续输入,如果我们需要行最后的’/’作为有效的字符,可以通过-r来进行。此外在输入字符中,我们希望/n这类特殊字符生效,也应采用-r选项。

-s :对于一些特殊的符号,例如箭头号,不将他们在terminal上打印,例如read –s key,我们按光标,在回车之后,如果我们要求显示,即echo,光标向上,如果不使用-s,在输入的时候,输入处显示^[[A,即在terminal上 打印,之后如果要求echo,光标会上移。

-t :用于表示等待输入的时间,单位为秒,等待时间超过,将继续执行后面的脚本,注意不作为null输入,参数将保留原有的值

 

典型用法1:处理/etc/passwd 文件, 该文件标准格式为7个以冒号隔开的字段。 脚本如下

#! /bin/bash

while IFS=: read user pass uid gid fullname homedir Shell
do
    echo "user: "$user" pass: "$pass" uid: "$uid" gid: "$gid" fullname: "$fullname" homedir: "$homedir" Shell: "$Shell
done < /etc/passwd

该脚本处理该文件,对每一行进行简单的输出展示, 其中在 $IFS里的字符会分隔输入行里的数据

结果如下

user: root pass: x uid: 0 gid: 0 fullname: root homedir: /root Shell: /bin/bash
user: bin pass: x uid: 1 gid: 1 fullname: bin homedir: /bin Shell: /sbin/nologin
user: daemon pass: x uid: 2 gid: 2 fullname: daemon homedir: /sbin Shell: /sbin/nologin
user: adm pass: x uid: 3 gid: 4 fullname: adm homedir: /var/adm Shell: /sbin/nologin
user: lp pass: x uid: 4 gid: 7 fullname: lp homedir: /var/spool/lpd Shell: /sbin/nologin
user: sync pass: x uid: 5 gid: 0 fullname: sync homedir: /sbin Shell: /bin/sync
user: shutdown pass: x uid: 6 gid: 0 fullname: shutdown homedir: /sbin Shell: /sbin/shutdown
user: halt pass: x uid: 7 gid: 0 fullname: halt homedir: /sbin Shell: /sbin/halt
user: mail pass: x uid: 8 gid: 12 fullname: mail homedir: /var/spool/mail Shell: /sbin/nologin
user: operator pass: x uid: 11 gid: 0 fullname: operator homedir: /root Shell: /sbin/nologin
user: games pass: x uid: 12 gid: 100 fullname: games homedir: /usr/games Shell: /sbin/nologin
user: ftp pass: x uid: 14 gid: 50 fullname: FTP User homedir: /var/ftp Shell: /sbin/nologin
user: nobody pass: x uid: 65534 gid: 65534 fullname: Kernel Overflow User homedir: / Shell: /sbin/nologin
user: apache pass: x uid: 48 gid: 48 fullname: Apache homedir: /usr/share/httpd Shell: /sbin/nologin

另外对于读取文件 还有一种 使用管道的写法

每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。

读取文件的关键是如何将文本中的数据传送给read命令。

对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令

#!/bin/bash

count=1 //赋值语句,不加空格

cat test | while read line //cat 命令的输出作为read命令的输入,read读到的值放在line中

do

echo "Line $count:$line"

count=$[ $count + 1 ] //注意中括号中的空格。

done

echo "finish"

exit 0

其他的相关例子


a. 拼接文件

#将afile文件中的前三行与bfile中的前四行拼接在一起
while read -u3 i && read -u4 j;do
echo $i $j
done 3<afile 4<bfile
b. 输入不在终端显示

read -p "Input passwd:" -s Passwd
echo $Passwd
c. 限时输入,否则退出

#延迟五秒,没有输入将自动退出
read -p "Input a number:" -t 5 Number
d. 读取限定字符

#从输入中取5个字符
read -p "Input a word:" -n 5 Word
e. 等待输出q退出

#输入,直到输入q,将自动退出
read -dp -p "Input some words end with q:" word

 

7.2 关于重定向

首先,介绍几种基本的输出入重定向运算符

<    是改变标准输入,例如 program < file   可以将program的标准输入修改为file。

>    是修改标准输出,例如 program > file   可以将program的标准输出修改为file。

>>  是附加到文件, 例如 program >> file   可以将program的标准输出附加到file的结尾处。和>一样,如果文件不存在则会新建一个文件。和>不一样的是,如果文件存在,>>不会直接覆盖掉文件

|      是建立管道,program1 | program2 可以将program1 的标准输出修改为program2的标准输入。相比临时文件,这样做的好处是,管道可以使得执行速度快上十倍左右。

7.3 文件描述符

在系统内部,UNIX是以一个小的整数数字(文件描述符),来表示每个进程的打开文件。数字由0开始,至多到系统定义的打开文件数目的限制。其中,文件描述符0、1、2,各自对应到标准输入、标准输出以及标准错误。

下面是一个例子, 将程序的输出传送至一个文件,并将其错误信息传输到另一个文件。

make 1> results 2> ERRS

或者直接舍弃错误信息

make 1> results 2> /dev/null

或者输出错误信息给相同的文件(需要注意:2>&1 这四个字符中间不能有空格)

make 1> results 2>&1

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值