SHELL脚本学习(六) 呈现数据

一、标准文件描述符

linux系统会将每个对象当作文件来处理,包括输入和输出。linux用文件描述符来描述每个对象。文件描述符是一个非负整数,唯一会标识的是打开的文件。每个进程一次最多能打开9个文件描述符。处于特殊目的,bash shell保留了前三个文件描述符(0,1,2)。

文件描述符缩写描述
0STDIN标准输入
1STDOUT标准输出
2STDERR标准错误
1.1 STDIN

STDIN文件描述符代表shell的标准输入。对于终端界面来说标准输入就是键盘。shell会从STDIN对应的键盘获取数据并处理。
使用输入重定向时,linux会用重定向指定的文件替换标准输入文件描述符。
许多bash命令可以从STDIN接收数据,例如cat

~$ cat 
first line
first line
second line
second line

也可以使用输入重定向强制cat接收来自STDIN之外的文件的数据。

$ cat < test.sh
#!/usr/bin/bash
cat ./test.sh| while read line
do
    echo $line
done 
1.2 STDOUT

STDOUT文件描述符代表shell的标准输出。在终端界面上标准输出就是显示器。在默认情况下大多数bash命令会将输出送往STDOUT文件描述符。可以使用输出重定向更改此设置。

$ ls -l >file1
$ cat < file1
total 48
...
-rw-rw-r-- 1 ubuntu ubuntu     0 Jun 12 18:03 file1
-rw-rw-r-- 1 ubuntu ubuntu    11 May 24 15:49 file2
...

也可以使用 >> 将数据追加到某个文件。

但是对脚本使用标准输出重定向,就会遇到一个问题,看看下面的例子:

$ ls -al nofile >file3
ls: cannot access 'nofile': No such file or directory
$ cat < file3
$ 

shell创建了输出重定向,但错误信息依然显示在屏幕上。
shell对于错误信息的处理跟普通输出是分开的。如果想让错误信息输出到文件,需要重定向错误。

1.3 STDERR

shell通过特殊的STDERR文件描述符处理错误信息。STDERR文件描述代表shell的标准错误输出。shell运行或者运行在shell的程序和脚本出错时,生成的错误信息都会送往这个位置。在默认情况下STDOUT和STDERR指向同一个地方,也就是显示器。

1.3.1 只重定向错误

STDERR文件描述符为2,可以将文件描述符值放在重定向符号前,只重定向错误信息。

$ ls -l nofile 2> file3
$ cat < file3
ls: cannot access 'nofile': No such file or directory
1.3.2 重定向错误信息和正常输出

如果想重定向错误和输出信息,必须使用两个重定向符号

$ ls -al file1 nofile 1> file2 2>file3
$ cat <file2
--w--w---- 1 ubuntu ubuntu 0 Jun 12 18:23 file1
$ cat <file3
ls: cannot access 'nofile': No such file or directory

可以使用这种方式区分脚本的正常输出和错误信息。

也可以将STDERR和STDOUT重定向到一个文件,bash shell提供了特殊的重定向符号 &>

$ ls -al file1 nofile &> file2
$ cat < file2
ls: cannot access 'nofile': No such file or directory
--w--w---- 1 ubuntu ubuntu 0 Jun 12 18:23 file1

二、在脚本中重定向输出

2.1 临时重定向

如果你有意在脚本中生成一条错误信息。可以将一行单独的信息重定向到STDERR。这只需要使用输出重定向符号将输出重定向到STDERR文件描述符。在重定向到文件描述符时,必须在文件描述符值前面加一个 &

#!/usr/bin/bash
# test.sh
echo "this a error 1" >&2
echo "this a error 2" >&2
echo "this a error 3" >&2
echo "this is a normal output 1"
echo "this is a normal output 2"
echo "this is a normal output 3"


$ ./test.sh > file2 2> file3
$ cat <file2
this is a normal output 1
this is a normal output 2
this is a normal output 3
$ cat <file3
this a error 1
this a error 2
this a error 3
2.2 永久重定向

如果脚本中有大量数据需要重定向,那么逐条重定向echo语句会很麻烦。这时可以使用exec命令,它告诉shell在脚本执行期间重定向某个特定文件描述符:

#!/usr/bin/bash
exec 1>fileout
echo "this is a normal output 1"
echo "this is a normal output 2"
echo "this is a normal output 3"

$ ./test.sh
$ cat <fileout
this is a normal output 1
this is a normal output 2
this is a normal output 3

三、在脚本中重定向输入

与重定向STDERR和STDOUT相似,可以将STDIN从键盘重定向到指定位置。linux系统中,exec命令可以将STDIN重定向到文件:

#!/usr/bin/bash
exec 0<test.sh

while read opt
do
    echo $opt    
done

$ ./test.sh
#!/usr/bin/bash
exec 0<test.sh

while read opt
do
echo $opt
done

read命令读取用户输入的数据,将STDIN重定向为文件后,当read试图从STDIN读取数据时,就会到文件中检索数据。

四、创建自己的重定向

重定向输入输出时,并不局限于默认的3个文件描述符。文件描述符3到8均可以用作输入和输出的重定向。

4.1 创建输出文件描述符

可以用exec命令分配用于输出的文件描述符。

#!/usr/bin/bash
exec 3>fileout

echo "this should store in the file" >&3
echo "this is a normal output"

$ ./test.sh
this is a normal output
$ cat <fileout
this should store in the file
4.2 重定向文件描述符

有一种方法可以恢复已重定向的文件描述符。可以先将STDOUT的位置重定向到一个文件描述符,之后再用这个文件描述符恢复STDOUT

#!/usr/bin/bash
exec 3>&1    
exec >fileout
echo "store in the fileout 1"
echo "store in the fileout 2"
echo "store in the fileout 3"
exec 1>&3
echo "normal output 1"
echo "normal output 2"
echo "normal output 3"

$ ./test.sh
normal output 1
normal output 2
normal output 3
$ cat < fileout
store in the fileout 1
store in the fileout 2
store in the fileout 3
4.3 创建输入文件描述符

可以采用和重定向输出同样的方法重定向输入文件描述符。在重定向之前先将STDIN的位置保存到另一个文件描述符,之后再用这个文件描述符恢复STDIN。

#!/usr/bin/bash
#test.sh
exec 3<&0
exec 0<test.sh

count=1
while read opt
do
    echo $count  $opt
    count=$[ $count+1 ]
done

exec 0<&3

#在bash中执行脚本

$ ./test.sh
1 #!/usr/bin/bash
2 exec 3<&0
3 exec 0<test.sh
4
5 count=1
6 while read opt
7 do
8 echo $count $opt
9 count=$[ $count+1 ]
10 done
11
12 exec 0<&3

4.4 关闭文件描述符

关闭文件描述符,只需要将文件描述符重定向到 &- 即可。
例: exec 3>&-

五、抑制命令输出

要抑制命令输出,只需将输出重定向到 /dev/null

六、将消息同时送往显示器和文件

有时需要将消息同时发送到文件和显示器,与其使用两次重定向,不如使用特殊命令tee。

tee filename
tee命令:将STDIN的数据同时送往两处。一处是显示器,一处是filename指定的文件。
如果要将数据追加到文件,使用 -a选项。

$ date | tee fileout
Wed 12 Jun 2024 08:09:41 PM CST
ubuntu@VM-8-14-ubuntu:~$ cat <fileout
Wed 12 Jun 2024 08:09:41 PM CST
  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值