shell学习笔记(三)shell输入与输出目录:
======================================================
echo read cat 管道 | tee 标准输入.输出和错误 文件重定向 标准输入的重定向 标准输出的重定向 标准输出的重定向 标准输出和标准错误的重定向 标准输入和标准输出的重定向 exec 管道|(pipe)与文件重定向区别 =====================================================
-n 回车不换行,系统默认是回车换行,如:echo 空白
[root@viong_app1 soft]# cat echo
echo -e "i an man\n\n" 回车换行
echo -e "a\tb\tc\nd\te\bf" 因为e\b 是退格 所以e被删除
[root@viong_app1 soft]# ./echo
read [ -p ][ -r ][ -s ][ -u[ n ] ] [ VariableName?Prompt ]
描述
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量,用 IFS(内部字段分隔符)变量中的字符作为分隔符。VariableName 参数指定 shell 变量的名称,shell 变量获取输入行一个字段的值。
由VariableName 参数指定的第一个 shell 变量指定给每一个字段的值,由 VariableName 参数指定的第二个 shell 变量指定给第二个字段的值,以此类推,直到最后一个字段。
如果标准输入行的字段比相应的由 VariableName 参数指定的 shell 变量的个数多,把全部余下的字段的值赋给指定的最后的 shell 变量。
如果比 shell 变量的个数少,则剩余的 shell 变量被设置为空字符串。 注意: 如果省略了 VariableName 参数,变量 REPLY 用作缺省变量名。
由 read 命令设置的 shell 变量影响当前 shell 执行环境
read命令-p(提示语句) -n(字符个数) -t(等待时间) -s(不回显) 和“读文件”
阻止换行
read name
echo "hello $name "
-------------------------------------------------------------------
[root@viong_app1 soft]# cat read.sh
read -p "Enter your name:" name name1
[root@viong_app1 soft]# ./read.sh
Enter your name:li ming bai
hello ming bai #余下的字段的值赋给指定的最后的 shell 变量
[root@viong_app1 soft]# ./read.sh
hello #剩余的 shell 变量被设置为空字符串
#!/bin/bash
read –p "Enter your name:" name
echo "hello $name "
-t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态;
#!/bin/bash
if read -t 5 -p "please enter your name:" name
then
echo "hello $name "
else
echo "sorry,time out "
fi
exit 0
-n选项后接数值1,指示read命令只要接受到一个字符就退出,只要按下一个字符进行回答,read命令立即接受输入并将其传给变量,无需按回车键.对于read命令来说,-n选项不会检测enter(新行)键
#!/bin/bash
read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
echo "fine ,continue";;
N | n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
exit 0
-s选项能够使read命令中输入的数据不显示在监视器上(实际上,数据是显示的,只是read命令将文本颜色设置成与背景相同的颜色)。
#!/bin/bash
read -s -p "Enter your password:" pass
echo "your password is $pass"
exit 0
-------------------------------------------------------------------------------------------------
每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出,读取文件的关键是如何将文本中的数据传送给read命令
最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的while命令
[root@viong_app1 soft]# cat test
-----------------------------------------------------------------------------------------
[root@viong_app1 soft]# cat read.sh
cat test|while read line #cat 命令的输出作为read 命令的输入,read 读到的值放在line 中
count=$[ $count + 1 ] # 注意中括号中的空格。
while read line #cat 命令的输出作为read命令的输入,read读到的值放在line中
count=$[ $count + 1 ] #注意中括号中的空格。
-------------------------------------------------------------------------------------------
[root@viong_app1 soft]# ./read.sh
说明:把档案串连接后传到基本输出,用它来显示文件内容.创建文件,还可以用它来显示控制字符
-n 或 --number 由 1 开始对所有输出的行数编号
-b 或 --number-nonblank 和 -n 相似,只不过对于空白行不编号
-s 或 --squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行
-v 或 --show-nonprinting
范例:
cat -n textfile1 > textfile2 把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
cat -b textfile1 textfile2 >> textfile3 把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里
范例:
把 textfile1 的档案内容加上行号后输入 textfile2 这个档案里
cat -n textfile1 > textfile2
把 textfile1 和 textfile2 的档案内容加上行号(空白行不加)之后将内容附加到 textfile3 里。
cat -b textfile1 textfile2 >> textfile3
cat /dev/null > /etc/test.txt 此为清空/etc/test.txt档案内容
管道是把一个命令的输出传递给另外一个命令作为输入,管道用竖杠“|“表示
df -k|awk '{print$1}'|grep -v "文件系统" 命令之间传递
[root@viong_app1 soft]# df -k
/dev/mapper/VolGroup00-LogVol00
18187836 1737764 15511272 11% /
/dev/sda1 101086 12753 83114 14% /boot
tmpfs 513304 0 513304 0% /dev/shm
[root@viong_app1 soft]# df -k|awk '{print$1}'|grep -v "文件系统"
/dev/mapper/VolGroup00-LogVol00
tee是把输出的一个副本输送到标准输出,另外一个副本拷贝到相应的文件中
如果希望在看到输出的同时,也将其存入一个文件,加-a代表累加原有的内容,不覆盖
[root@viong_app1 soft]# df -k|awk '{print$1}'|grep -v "文件系统" |tee disk
/dev/mapper/VolGroup00-LogVol00
[root@viong_app1 soft]# cat disk
/dev/mapper/VolGroup00-LogVol00
-------------------------------------------------------------------------------------------------
[root@viong_app1 soft]# df -k|awk '{print$1}'|grep -v "文件系统" |tee -a disk
[root@viong_app1 soft]# cat disk
/dev/mapper/VolGroup00-LogVol00
/dev/mapper/VolGroup00-LogVol00
linux启动后,会默认打开3个文件描述符,分别是:标准输入standard input 0,正确输出standard output 1,错误输出:error output 2
文件描述符:可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作。 用户可以自定义文件描述符范围是:3-num,这个最大数字,跟用户的:ulimit –n 定义数字有关系,不能超过最大值。
以后打开文件后。新增文件绑定描述符 可以依次增加。 一条shell命令执行,都会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认3个文件描述符
输入文件—标准输入 0(缺省是键盘,也可以是文件或其他命令的输出)
输出文件---标准输出 1(缺省是屏幕,也可以是文件)
错误输出文件—标准错误 2(缺省是屏幕,也可以是文件)
系统中实际上有12个文件描述符,可以任意使用文件描述符3到9
所谓文件重定向就是改变程序运行的输入来源和输出地点
命令默认从键盘获得的输入,改成从文件,或者其它打开文件以及设备输入,执行这个命令,将标准输入0,与文件或设备绑定,将由它进行输入.
command < filename command命令以filename文件作为标准输入
command << delimiter(定界符) 从标准输入中读入,直到遇到delimiter定界符
command < &m 把文件描述符m作为标准输入
[root@viong_app1 soft]# cat name
[root@viong_app1 soft]# sort < name
---------------------------------------------------------------------------
[root@viong_app1 soft]# cat score
[root@viong_app1 soft]# cat >> score <<exit
[root@viong_app1 soft]# cat score
--------------------------------------------------------------------------
从标准输入【键盘】获得数据,然后输出追加给score文件
[root@lvs_app1 soft]# cat score
<<exit 直到遇到exit定界符,退出,相当于结束的输入字符,不用按ctrl+d或者ctrl+c离开
-------------------------------------------------------------------------------------
[root@lvs_app1 soft]# cat score1
[root@lvs_app1 soft]# cat>>score<score1 #cat从score1获得输入数据,然后输出追加给score文件
[root@lvs_app1 soft]# cat score
将一条命令执行结果(标准输出,本来都要打印到屏幕上面的) 重定向其它输出设备(文件,打开文件操作符,或打印机等等)
command > filename 把标准输出重定向到一个新文件
command >> filename 把标准输出重定向到一个文件中(追加)
command > &m 把标准输出重定向到文件描述符m中
[root@viong_app1 viong]# ll >test
[root@viong_app1 viong]# cat test
-rw-r--r-- 1 root root 0 05-29 16:52 test
drwxr-xr-x 2 root root 4096 04-22 21:44 viong
[root@viong_app1 viong]# ll 1>test
[root@viong_app1 viong]# cat test
-rw-r--r-- 1 root root 0 05-29 16:52 test
drwxr-xr-x 2 root root 4096 04-22 21:44 viong
-------------------------------------------------------------
[root@viong_app1 viong]# ll >>test
[root@viong_app1 viong]# cat test
-rw-r--r-- 1 root root 0 05-29 16:52 test
drwxr-xr-x 2 root root 4096 04-22 21:44 viong
-rw-r--r-- 1 root root 101 05-29 16:52 test
drwxr-xr-x 2 root root 4096 04-22 21:44 viong
shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空
[root@viong_app1 soft]# >test #test文件存在,就清空内容,不存在就创建一个空文件test
command 2 > filename 把标准错误重定向到一个新文件
command >> filename 把标准错误重定向到一个文件中(追加)
[root@viong_app1 soft]# ll hom hom1 2>err.txt
-rw-r--r-- 1 root root 101 05-09 18:45 hom
[root@viong_app1 soft]# cat err.txt
[root@viong_app1 soft]# ll hom hom1 2>>err.txt
-rw-r--r-- 1 root root 101 05-09 18:45 hom
[root@viong_app1 soft]# cat err.txt
--------------------------------------------------------------------------------------------------
[root@viong_app1 soft]# ll hom hom1 2>/dev/null
-rw-r--r-- 1 root root 101 05-09 18:45 hom
[root@lvs_app1 soft]# ll hom hom1 1>/dev/null 2>/dev/null #把标准输出和错误转发给/dev/null
[root@lvs_app1 soft]# ll hom hom1 &>/dev/null #把标准输出和错误转发给/dev/null
-------------------------------------------------------------------------------------------------
[root@lvs_app1 soft]# ll hom hom1 2>&- #关闭标准错误
-rw-r--r-- 1 root root 101 05-09 18:45 hom
[root@lvs_app1 soft]# ll hom hom1 1>&- 2>&- #关闭标准输出和错误
[root@lvs_app1 soft]# ll hom hom1 &>- #关闭标准输出和错误
合并标准输出和标准错误的时候,切记shell 是从做到右分析相应的命令 command > filename 2>&1 把标准输出和标准错误一起重定向到一个文件中
命令解释:首先command命令标准输出到filename文件,如遇到标准错误输出到&1.而&1代表缺省屏幕(标准输出),而缺省屏幕输出到filename文件,及所有错误和结果输出到filename文件中
command >> filename 2>&1 把标准输出和标准错误一起重定向到一个文件中(追加)
[root@viong_app1 soft]# >err.txt #先清空err.txt文件内容
[root@viong_app1 soft]# ll hom hom1>err.txt 2>&1 #标准输出和错误都重定向到err.txt文件中
[root@viong_app1 soft]# cat err.txt
-rw-r--r-- 1 root root 101 05-09 18:45 hom
[root@viong_app1 soft]# ll hom hom1>>err.txt 2>&1
[root@viong_app1 soft]# cat err.txt
-rw-r--r-- 1 root root 101 05-09 18:45 hom
-rw-r--r-- 1 root root 101 05-09 18:45 hom
-------------------------------------------------------------------------------------------------
[root@viong_app1 soft]# > err.txt
[root@viong_app1 soft]# ll hom hom1 2>err.txt 1>homnew #标准输出和错误分别重定向到不同文件中
[root@viong_app1 soft]# cat err.txt
[root@viong_app1 soft]# cat homnew
-rw-r--r-- 1 root root 101 05-09 18:45 hom
command < filename <filename 2 command命令以filename文件作为标准输入,以fi lename2文件作为标准输出
[root@viong_app1 soft]# cat name
[root@viong_app1 soft]# sort <name >name1类似cat name|sort>name1命令
[root@viong_app1 soft]# cat name1
exec 文件描述符[n] <或> file或文件描述符或设备
在上面讲的输入,输出重定向 将输入,输出绑定文件或设备后,只对当前那条指令是有效的,如果需要在绑定之后,接下来的所有命令都支持的话,就需要用exec命令
exec命令可以用来替代当前shell,换句话说,并没有启动子shell,使用这一命令时任何现有环境变量将会被清除,并重新启动一个shell
对文件描述符进行操作的时候, 它不会覆盖当前的shell [root@viong_app1 soft]# export viong=10
[root@viong_app1 soft]# echo $viong
[root@viong_app1 soft]# exec ./hello.sh
#这个时候退出当前shell,重新启动一个shell
[root@viong_app1 ~]# echo $viong #查看之前环境变量已被清除
--------------------------------------------------------------------------------------------------
[root@lvs_app1 soft]# exec 5<&1 #将标准输出与文件描述符5绑定
[root@lvs_app1 soft]# ls /proc/self/fd #出现文件描述符5
[root@lvs_app1 soft]# exec 1>exec.txt #接下来所有命令标准输出,绑定到exec.txt文件(输出到该文件)
注意:这里输出的内容是追加的 [root@lvs_app1 soft]# ll #执行命令后并无返回结果
[root@lvs_app1 soft]# exec 1<&5 #恢复标准输出
[root@lvs_app1 soft]# ll #执行命令后返回结果到屏幕上
-rwxr-xr-x 1 root root 339 05-16 16:07 break.sh
-rwxr-xr-x 1 root root 269 05-16 17:01 case.sh
-rwxr-xr-x 1 root root 702 05-16 16:17 continue.sh
[root@lvs_app1 soft]# exec 5>&- #关闭文件描述符5
[root@lvs_app1 soft]# ls /proc/self/fd
--------------------------------------------------------------------------------------------------
[root@viong_app1 soft]# cat name
[root@viong_app1 soft]# cat exec.sh
[root@viong_app1 soft]# ./exec.sh
[root@lvs_app1 soft]# cat exec.sh
exec 3<>name #打开name可读性操作,与文件描述符3绑定
[root@lvs_app1 soft]# ./exec.sh
------------------------------------------------------------------------------------------------------
[root@lvs_app1 soft]# exec 6<&1
[root@lvs_app1 soft]# ls /proc/self/fd/
[root@lvs_app1 soft]# exec 6<&1-
-bash: echo: write error: 错误的文件描述符
-bash: echo: write error: 错误的文件描述符
[root@lvs_app1 soft]# exec 6<&-
-bash: echo: write error: 错误的文件描述符
-bash: echo: write error: 错误的文件描述符
遇到以上因为疏误导致无法输入任何命令,就要利用之前重启shell命令
[root@viong_app1 soft]# exec ./hello.sh #重启到另外一个shell
[root@lvs_app1 ~]# ls /proc/self/fd/ #恢复正常状态
1、管道命令只处理前一个命令正确输出,不处理错误输出
2、管道命令右边命令,必须能够接收标准输入流命令才行。
接收标准输入的命令才可以用作管道右边。否则传递过程中数据会抛弃。 常用来作为接收数据管道命令有:sed,awk,cut,head,top,less,more,wc,join,sort,split 等等,都是些文本处理命令。
本文转自viong 51CTO博客,原文链接:http://blog.51cto.com/viong/894428,如需转载请自行联系原作者