shell脚本学习笔记----7(输⼊输出、⽂件与命令执⾏)
软件设计原则⾥,标准输⼊/输出(Standard I/O)包括标准输⼊(standard input)、标准输出(standard output)以及 标准错误输出(standard error)。分别代表了程序的来源,数据出⼝,以及报告问题的地⽅。程序应该不知道也不在意其输⼊与输出背后是哪种设备,这些设备可能是⽂件、终端、⽹络连接甚⾄是另⼀个执⾏中的程序。
7.1 使⽤读取⾏
1[xudong@localhost ~]$ x=abd; printf "x is now '%s'. Enter new value: " $x; read x
2x is now 'abd'. Enter new value: PDQ
3[xudong@localhost ~]$ echo $x
4PDQ
read命令是⼀个⾮常重要的bash命令,⽤于从键盘中输⼊⽂本,并且可以和⽤户进⾏交互;该命令可以⼀次读取多个变量的值,变量和输⼊的值都需要使⽤空格隔开。在read命令后⾯,如果没有指定变量名,读取的数据将被⾃动赋值给特定的变量REPLY,read的参数⽐较少使⽤的⽐较多的⼏个参数包括:-
a(⽤于数组),-p(给出输⼊的提⽰符),-t(指定读取值时等待的时间单位是秒),-s(不显⽰输⼊的值,⼀般⽤于密码的输⼊);当然read也可以不使⽤参数。
Read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s⼋个选项。
-a :将内容读⼊到数值中
1echo -n "Input muliple values into an array:"
2read -a array
3echo "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个以冒号隔开的字段。 脚本如下
1#! /bin/bash
shell最简单脚本
2
3while IFS=: read user pass uid gid fullname homedir Shell
4do
5 echo "user: "$user" pass: "$pass" uid: "$uid" gid: "$gid" fullname: "$fullname" homedir: "$homedir" Shell: "$Shell
6done < /etc/passwd
该脚本处理该⽂件,对每⼀⾏进⾏简单的输出展⽰, 其中在 $IFS⾥的字符会分隔输⼊⾏⾥的数据
结果如下
1user: root pass: x uid: 0 gid: 0 fullname: root homedir: /root Shell: /bin/bash
2user: bin pass: x uid: 1 gid: 1 fullname: bin homedir: /bin Shell: /sbin/nologin
3user: daemon pass: x uid: 2 gid: 2 fullname: daemon homedir: /sbin Shell: /sbin/nologin
4user: adm pass: x uid: 3 gid: 4 fullname: adm homedir: /var/adm Shell: /sbin/nologin
5user: lp pass: x uid: 4 gid: 7 fullname: lp homedir: /var/spool/lpd Shell: /sbin/nologin
6user: sync pass: x uid: 5 gid: 0 fullname: sync homedir: /sbin Shell: /bin/sync
7user: shutdown pass: x uid: 6 gid: 0 fullname: shutdown homedir: /sbin Shell: /sbin/shutdown
8user: halt pass: x uid: 7 gid: 0 fullname: halt homedir: /sbin Shell: /sbin/halt
9user: mail pass: x uid: 8 gid: 12 fullname: mail homedir: /var/spool/mail Shell: /sbin/nologin
10user: operator pass: x uid: 11 gid: 0 fullname: operator homedir: /root Shell: /sbin/nologin
11user: games pass: x uid: 12 gid: 100 fullname: games homedir: /usr/games Shell: /sbin/nologin
12user: ftp pass: x uid: 14 gid: 50 fullname: FTP User homedir: /var/ftp Shell: /sbin/nologin
13user: nobody pass: x uid: 65534 gid: 65534 fullname: Kernel Overflow User homedir: / Shell: /sbin/nologin
14user: apache pass: x uid: 48 gid: 48 fullname: Apache homedir: /usr/share/httpd Shell: /sbin/nologin
另外对于读取⽂件 还有⼀种 使⽤管道的写法
每次调⽤read命令都会读取⽂件中的"⼀⾏"⽂本。当⽂件没有可读的⾏时,read命令将以⾮零状态退出。读取⽂件的关键是如何将⽂本中的数据传送给read命令。
对⽂件使⽤cat命令并通过管道将结果直接传送给包含read命令的while命令
1#!/bin/bash
2
3count=1 //赋值语句,不加空格
4
5cat test | while read line //cat 命令的输出作为read命令的输⼊,read读到的值放在line中
6
7do
8
9echo "Line $count:$line"
10
11count=$[ $count + 1 ] //注意中括号中的空格。
12
13done
14
15echo "finish"
16
17exit 0
其他的相关例⼦
1
2 a. 拼接⽂件
3
4#将afile⽂件中的前三⾏与bfile中的前四⾏拼接在⼀起
5while read -u3 i && read -u4 j;do
6echo $i $j
7done 3<afile 4<bfile
8 b. 输⼊不在终端显⽰
9
10read -p "Input passwd:" -s Passwd
11echo $Passwd
12 c. 限时输⼊,否则退出
13
14#延迟五秒,没有输⼊将⾃动退出
15read -p "Input a number:" -t 5 Number
16 d. 读取限定字符
17
18#从输⼊中取5个字符
19read -p "Input a word:" -n 5 Word
20 e. 等待输出q退出
21
22#输⼊,直到输⼊q,将⾃动退出
23read -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
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论