linux学习(七) shell脚本(4)

转载 2013年12月03日 23:24:07
显示数据

1.linux标准文件描述符
linux系统将每个对象当做文件处理,包括输入和输出过程,linux使用文件描述符标志每个文件对象。文件描述符是是个非负整数,可以唯一标识会话中打开的文件。每个进程最多可以有9个打开的文件描述符。Bash shell为特殊需要保留前3个文件描述符(0, 1, 2)。
0, STDIN, 标准输入(键盘);
1, STDOUT, 标准输出(显示器)
2, STDERR, 标准错误(将错误输出到显示器)
这3个特殊文件描述符处理脚本的输入和输出。shell使用他们将shell中默认输入和输出重定向到相应位置(通常是显示器)。
STDIN
  STDIN 文件描述符引用shell的标准输入,对于终端接口,标准输入是键盘。Shell通过STDIN 文件描述符从键盘接受数据,并在键入时处理每个字符。{直接使用cat命令,则是将下面标准输入的内容紧跟着显示出来}
	使用重定向符号(<)时,linux将使用重定向引用的文件替换标准的输入文件描述符。它读取文件并获取数据。
STDOUT
	STDOUT文件描述符引用shell的标准输出。在终端接口,标准输出是终端监视器。shell的所有输出(包括shell中运行的程序和脚本)都重定向到标准输出,也就是显示器。
	可以使用重定向符号( > )将输出重定向到其他文件描述符所引用的文件。还可以使用 >> 符号向文件添加数据。 Ls -l  > tests;  who  >> test2; 如果使用脚本的标准输出重定向,可能遇到问题。当要重定向的命令发生错误时,不会将错误信息重定向到重定向文件, 但是错误信息会显示在屏幕上。
STDERR
	shell使用特殊的STDERR文件描述符处理错误信息。STDERR文件描述符引用shell的标准错误输出。这是shell发送错误信息(shell或shell中运行的程序或脚本所生成)的目的地。
	默认情况下,STDERR描述符和STDOUT描述符都指向相同的位置(即使他们分配了不同的文件描述符),即在默认情况下,所有的错误信息都输出到屏幕。处理脚本时,常常要重定向输出错误信息的文件。

2.重定向错误
   (1)仅仅重定向错误
	STDERR的文件描述符的值为2, 通过替换位于重定向符号正前方的这个文件描述符,可以仅重定向错误消息。该值必须位于重定向符号的正前方,否则无效。
$ls -al badfile 2> test3
$cat test3
ls :cannot access badfile: No such file or directory
下示例联合在同一输出中混合使用了STDOUT和STDERR
jason@Ubuntu:~$ ls -al test.sh test2 2> test3
-rwxrw-r-- 1 jason jason 162 12月  2 23:15 test.sh
jason@Ubuntu:~$ cat test3
ls: 无法访问test2: 没有那个文件或目录
	(2)重定向错误和数据
	如果需要同时重定向错误和普通数据,则必须使用两个重定向符号。必须在希望重定向的数据前面放置相应的文件描述符,然后将他们指向相应的输出文件以保存数据。
$ls -al test test2 test3 badtest 2> test6 1> test7
在上例中,将错误信息都输出到test6,普通数据输出到test7
	这样,将标准输出和标准错误重定向到两个文件,如果需要也可以将STDIN和STDOUT重定向到一个文件,包括数据和错误。

3. 在脚本中重定向输出
	(1)临时重定向每一行
	在脚本中要重定向到某个文件描述符时,必须在文件描述符编号前面加&. >&文件描述符(或文件名)
Echo “this is an error message” >&2    /////则将该信息,本来是要定向到标准输出STDOUT的,重定向到了标准错误STDERR,可当做错误信息显示到屏幕上。
Echo “this is an error message” >& test3 ////将该信息,本来是定向到标准输出STDOUT的,重定向到了test3文件中。
	在脚本中也可以使用文件名进行重定向,如Echo “this is an error message” > test3 ///可以不使用&,直接 > 加文件名。

   如果在运行脚本时重定向 STDERR, 则任何使用脚本定向到STDERR的文本都被重定向。如 ./test.sh 2> errfile
	(2)永久重定向
	如果在脚本中重定向许多数据,那么使用echo语句重定向每行就不方便了。可以使用exec命令通知脚本执行期间重定向特殊的文件描述符。
exec 1> testfile
echo hello
echo what are you doing
echo bye
	这种方法的一个缺陷是重定向STDOUT或STDERR之后,就无法轻松的将他们重定向到原来的位置。可以通过创建自己的重定向来解决。
4.在脚本中重定向输入
	exec命令可以将STDIN重定向到linux系统的文件。 Exec 0< testfile
该命令告知shell应该从testfile中读取数据,而不是获得STDIN输入(在使用read命令进行读取的时候就会忽略读取STDIN,而从重定向的文件中进行读取)。在脚本请求输出的任何时候都可以使用这种重定向方式。
    这种方式可以读取文件的数据并进行脚本处理,linux系统管理员常见的一个任务是,从日志文件读取数据并进行处理。这种方式很使用。

5.创建自己的重定向
	shell中最多可以有9个打开的文件描述符,其他6个文件描述符编号从3~8,可以将这些文件描述符应用到任何文件,然后在脚本中打开他们。
(1)创建输出文件描述符
	使用exec命令为输出分配文件描述符。与标准的文件描述符一样,向文件位置分配了备选文件符之后,该重定向是永久的,除非重新分配。
exec 3>test3
echo "hello jason" >&3
	这种方法可以使得在脚本中将普通输出重定向到监视器,将特殊信息重定向到文件。
(2)重定向文件描述符
	可以向标准文件描述符分配一个备选文件描述符,反之亦然。这样,就可以将STDOUT的原位置重定向到备选文件描述符A(进行暂存),然后如果在脚本中重定向STDOUT到某个文件(这样在输出到STDOUT的时候就会输出到文件),如果需要再恢复STDOUT的输出位置,则可以从暂存的备选文件描述符A中恢复STDOUT。
exec 3>&1
exec 1>test3
echo "this should be stored in the output file"
echo "along with this line"

exec 1>&3
echo "Now things should be back to normal"
首先,将文件描述符3的输出重定向到1的当前位置,即标准输出STDOUT,则任何输出到文件描述符3的数据都会输出到标准输出STDOUT; 然后将文件描述符1重定向到test3文件,则任何标准输出的数据都会输出到test3文件中;最后将文件描述符1 重定向到文件描述符3(此时文件描述符3的输出定到 STDOUT到屏幕),则文件描述符1的输出也定向到了STDOUT(即标准输出到显示器)。
(3)创建输入文件描述符
	在重定向输入描述符之前,将STDIN文件描述符位置暂时保存到另一个备选文件描述符,然后在完成了文件的读取操作之后,可以将STDIN 恢复为原来的位置。
exec 6<&0

exec 0< test3
count=1
while read line
do
	echo "Line #$count: $line"
	count=$[$count+1]
done

exec 0<&6
read -p "Are you done now?" answer
case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry";;
esac

(4)创建读取/写入文件描述符
   为读取和写入打开同一个文件描述符。可以使用同一个文件描述符从一个文件读取数据,同时向这个文件写入数据。但这种方式不常用{因为为同一个文件进行操作,不太容易进行读写指针的控制}
(5)关闭文件描述符
	如果在脚本中创建新的输入或输出文件描述符,shell将在脚本退出时自动关闭他们。但有时需要在脚本结束前手动关闭文件描述符。
要关闭文件描述符,将他重定向到特殊符号 &-。 exec 3>&-, 则就关闭了文件描述符3

6.列出开放的文件描述符
lsof命令列出整个linux系统上所有的开放文件描述符。
经常使用选项 -p 指定进程pid, -d 指定要显示的文件描述符编号
lsof -a -p $$ -d 0,1,2
jason@Ubuntu:~$ lsof -a -p $$ -d 0,1,2
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    1939 jason    0u   CHR  136,0      0t0    3 /dev/pts/0
bash    1939 jason    1u   CHR  136,0      0t0    3 /dev/pts/0
bash    1939 jason    2u   CHR  136,0      0t0    3 /dev/pts/0

jason@Ubuntu:~$ lsof -a -p $$ -d 0,1,2
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    2798 jason    0u   CHR  136,1      0t0    4 /dev/pts/1
bash    2798 jason    1u   CHR  136,1      0t0    4 /dev/pts/1
bash    2798 jason    2u   CHR  136,1      0t0    4 /dev/pts/1

每个shell进程都可以最多有9个文件描述符。

7.禁止命令输出
有时候不希望显示任何脚本输出。可以通过将STDERR重定向到成为空文件(null file)的特殊文件。该问价不包含任何内容。Shell输出到空文件的任何数据都不会保存。
Exec 1> /dev/null
8.使用临时文件
	 linux系统保留了一个特殊的目录位置,以供临时文件使用。Linux系统使用/tmp目录处理不需要永久保存的文件,大部分linux发行版的系统配置都是在启动时自动删除/tmp目录中的任何文件。
	系统上的任何账户都有权读写/tmp目录中的文件,该特性可以使得用户轻松创建临时文件,而无需担心清理问题。
	Mktemp命令可以在/tmp目录中创建一个唯一的临时文件,shell在创建该文件时不适用默认的umask,它仅仅向文件所有者分配读取和写入的权限。创建临时文件之后,可以通过脚本进行完整权限的读取和写入,但其他人都不能访问它。
(1)创建本地临时文件
	使用mktemp命令在本地目录中创建临时文件,只需要指定一个文件名模板即可。模板包括文本文件名以及附加到文件名后的6个X
$mktemp testing.XXXXXX
$ls -al testing.*
mktemp命令使用一个6字符代码替换6个X,以确保文件名在目录中的唯一性。这样可以创建多个临时文件,每个文件确保是唯一的。
jason@Ubuntu:~$ mktemp jason.XXXXXX
jason.TBuZw9
jason@Ubuntu:~$ mktemp jason.XXXXXX
jason.MSkOOF

mktemp 使用 -t 选项可以获得返回一个包含完整路径名的临时文件,而不仅仅是文件名。
jason@Ubuntu:~$ mktemp -t jason.XXXXXX
/tmp/jason.cgZyTt


在脚本中使用mktemp命令时,需要使用一个变量名保存该文件名,以便稍后在脚本中引用。
tempfile=`mktemp jason.XXXXXX`
exec 3>$tempfile
echo this is a teemp
echo fdsfjd >&3
exec 3>&-
cat $tempfile
rm -f $tempfile 2> /dev/null

(2)创建临时目录
-d选项使得mktemp命令创建一个临时目录而不是一个文件。然后可以将该目录用于任何目的。

9.记录消息
	有时候需要将输出同时发送到监视器和日志文件,这种情况不需要使用两次重定向,只需要使用特殊的tee命令即可。将数据同时发送到两个目的地,一个是STDOUT,一个是指定的文件。
$date | tee test3
//上条命令将 date命令的输出管道给了tee命令,tee命令一方面输出到显示器,一方面输出到文件test3中。
如果希望向文件中添加数据,而不是将文件删除后再写入,则可以使用-a命令。如:
$date | tee -a test3  //则向test3追加数据。

	


    




Linux学习4_shell脚本学习

终于到shell 脚本这章了,在以前笔者卖了好多关子说shell脚本怎么怎么重要,确实shell脚本在linux系统管理员的运维工作中非常非常重要。下面笔者就带你正式进入shell脚本的世界吧。 到现...

《linux命令行与shell脚本编程大全》第三版 - 核心笔记(3/4):正则表达式

《linux命令行与shell脚本编程大全》 全书4部分: ☆ 【1】linux命令行(1-10章) ☆ 【2】shell脚本编程基础(11-16章) ☆ 【3】高级shell脚本编程(17-...

dubbo -4在linux手工部署dubbo(shell脚本)

1.环境变量配置 vi /etc/profile ## java env export JAVA_HOME=/usr/local/java/jdk1.7.0_72 export JRE_HOME=$J...

《linux命令行与shell脚本编程大全》第三版 - 核心笔记(3/4):sed和gawk

《linux命令行与shell脚本编程大全》 全书4部分: ☆ 【1】linux命令行(1-10章) ☆ 【2】shell脚本编程基础(11-16章) ☆ 【3】高级shell脚本编程(17-...

linux之基础shell脚本编程4 字符串操作,变量赋值,配置用户环境

九 字符串 9.1 bash的字符串处理工具: 9.1.1 字符串切片:   ${#var} :返回字符串变量 var 的长度   ${var:offs...

Linux shell脚本全面学习

  • 2015年04月19日 20:57
  • 53KB
  • 下载

Linux命令行与shell脚本(4)--Linux文件权限

Linux安全性 Linux系统使用一个专门的文件来将用户的登录名匹配到对应的UID值。这个文件就是/etc/passwd文件 Linux系统将用户密码保存在一个单独的文件/etc/shadow中,只...

Linux shell脚本全面学习

  • 2012年01月05日 17:32
  • 102KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux学习(七) shell脚本(4)
举报原因:
原因补充:

(最多只允许输入30个字)