shell编程-基础

1.linux 下 Bash 程序开

1.1 怎样写 shell 脚本

1.使用编辑工具编辑shell 脚本,例如 vim,脚本名字一般用.sh 为后缀,不用.sh 为后缀 时编辑的内容为全黑,不会有高亮突显命令与变量。
2.写完后设置脚本的执行权3.执行脚本,做测试,执行方式:./shell-name;bash shell-name ;sh shell-name

1.2 彩色 shell 的输出

1.echo -e 可以在控制台输出彩色字符
2.色彩:
前背景:30-37
后背景:40-47
0:黑 1:红 2:绿 3:黄 4:蓝 5:洋红 6:青 7:白
3.使用格式:
\033[3X;4ym 同时修改前景和背景颜色
\033[3Xm 只更改前景颜色
\033[4Xm 只更改背景颜色
\033[0m 还原前景和背景颜色,一定要记得还原哦!

1.3shell 中的变量

1.变量类型:
系统变量:由系统本身维护,通常为大写
自定义变量(UDV):用户创建和维护,通常小写
2.使用 set 来查看系统变量,$来调用变量
[root@desktop29 ~]# set
BASH=/bin/bash
BASH_ARGC=()
BASH_ARGV=() …… ……
3.自定义变量:
通过“变量名=值”来定义,等号之间没有空格,将右边的值赋给左边的变量,可以定义
空值,如:mony= ,等号右边没有任何值;mon="" ,引号中没有任何空格
命名规则:必须以字符或者_开头,不要使用?和*,区分大小写
4.实例:
[root@desktop29 ~]# UNAME=liudehua 定义变量
[root@desktop29 ~]# echo $UNAME 调用变量
liudehua
[root@desktop29 ~]# read UNAME 定义变量
liming
[root@desktop29 ~]# echo $UNAME
liming

1.4echo 命令

1.使用 echo 命令可以显示文本或变量的值:echo [选项] [字符、变量……]
2.选项:
-n 不换行输出,默认就是 echo 一次换一行,用在持续的打印输出
-e 启用转义字符解析
\a 响铃 \b 退格 \c 去除尾部的新行
\n 换行 \r回车 \t 水平制表符 \\斜杠
3.实例:
[root@desktop29 ~]# echo -e "HOST\t\tUSER\n172.24.24.23\t$UNAME"
HOST USER
172.24.24.23 liming

1.5shell 中数学计算

1.语法:expr 操作数 1 运算符 操作数 2(注意中间是要空格的!!)
2.运算符:+ 加;/除;%取余;\* 乘(需要转义)
3.实例:
[root@desktop29 ~]# expr 2 + 4
6
[root@desktop29 ~]# expr 2 / 4
0
[root@desktop29 ~]# UU=$(expr 2 \* 100)
[root@desktop29 ~]# expr $UU / 4
50
[root@desktop29 ~]# echo $UU
200

1.6 引号的使用

1.引号:
"" :双引号,对\做转义,对$的变量作解析
' ' :单引号,不做任何修
`` :斜点,用来执行命令
[root@desktop29 ~]# echo "$UU and date" #不能解读 date 命令,需要$来调用
200 and date
[root@desktop29 ~]# echo "$UU and $(date)"
200 and Wed Oct 5 08:28:42 CST 2011
[root@desktop29 ~]# echo "$UU and \$(date)" #\转义了
200 and $(date)
[root@desktop29 ~]# echo `$UU and date`
bash: 200: command not found
``斜点不能对$作解析,里面只能使用命令
[root@desktop29 ~]# echo "$UU and `date`"
200 and Wed Oct 5 08:29:20 CST 2011
[root@desktop29 ~]# echo '$UU and date' #不做任何修改
$UU and date
[root@desktop29 ~]# echo `date`
Wed Oct 5 08:30:09 CST 2011
[root@desktop29 ~]# echo "expr 3 + 4 "
expr 3 + 4
[root@desktop29 ~]# echo `expr 3 + 4 ` #先执行 bash
7
[root@desktop29 ~]# echo "$(expr 3 + 4 )"
7

1.7 退出和退出状态

1.在 linux 执行指令后,将返回 0:成功 非 0:不成功或有错
2.通过 echo $?来查看退出状态
[root@desktop29 ~]# ls /boot/grub/grub.conf
/boot/grub/grub.conf
[root@desktop29 ~]# echo $? #命令执行正确,返回 0
0
[root@desktop29 ~]# ls /boot/grub/grub.con
ls: /boot/grub/grub.con: No such file or directory
[root@desktop29 ~]# echo $? 命令执行不正确,返回非 0
2

1.8read 语法

1.read 作用:获得用户通过键盘输入的数据并保存到变量中
2.语法:read 变量 1 变量 2 ……
[root@desktop29 ~]# read TT HH
tt hh
[root@desktop29 ~]# echo $TT
tt
[root@desktop29 ~]# echo $HH
hh
[root@desktop29 ~]# echo "rr ff ss" |while read HH GG II 
> do
> echo $HH
> echo $GG $II
> done
rr
ff ss
[root@desktop29 ~]# echo $GG #显示是空
[root@desktop29 ~]#

1.9 通配符的使用

1.通配符的意义:
* :任何的字符出现 0 到多
? :任何一个字符
[]:括号内提供的字符选一个
[ - ]:括号内一段字符
[^ ]:括号内的都排除掉
[root@desktop29 ~]# ls /lib/libn*.so
/lib/libnsl-2.5.so /lib/libnss_hesiod-2.5.so
/lib/libnss_compat-2.5.so /lib/libnss_ldap-2.5.so
…… ……
[root@desktop29 ~]# ls /lib/lib?[abef]*.so
/lib/libdb-4.3.so /lib/libdevmapper.so
/lib/libdevmapper-event-lvm2mirror.so /lib/libkeyutils-1.2.so
/lib/libdevmapper-event-lvm2snapshot.so /lib/libresolv-2.5.so
/lib/libdevmapper-event.so /lib/libSegFault.so
[root@desktop29 ~]# ls /lib/lib[^abefnd]*.so
/lib/libBrokenLocale-2.5.so /lib/libm-2.5.so /lib/libSegFault.so
/lib/libc-2.5.so /lib/libproc-3.2.7.so /lib/libthread_db-1.0.so
/lib/libcidn-2.5.so /lib/libpthread-2.5.so /lib/libutil-2.5.so
/lib/libcrypt-2.5.so /lib/libresolv-2.5.s

1.10 一行内执行多条命令

1.语法:命令 1;命令 2;命令 3;……
[root@desktop29 ~]# echo "ee" >> ff.txt;cp ff.txt d.t;rm ff.txt -f;echo $?
0
[root@desktop29 ~]# cat d.t
ee
[root@desktop29 ~]# cat ff.txt #被删了
cat: ff.txt: No such file or directory

1.11 命令行参数

参数可以有多个或者没有,如:
[root@desktop29 ~]# rm d.t -fv #2 个参数
removed `d.t'
[root@desktop29 ~]# date #0 个参数
Wed Oct 5 09:20:15 CST 2011
特殊的参数:
-$#保存着命令后面所带的参数的总数
-$*或-$@将命令后的所有参数作为一个字符串保存
位置参数:
$0:命令本身;$1:命令后面的第一个参数;$n:该命令后面的第 n 个参数
测试位置参数和特殊的参数
[root@desktop29 ~]# vim dd.sh
#!/bin/bash
echo "\$0 : $0"
echo "\$1 : $1"
echo "\$2 : $2"
echo "\$# : $#"
echo "\$* : $*"
[root@desktop29 ~]# chmod u+x dd.sh
[root@desktop29 ~]# ./dd.sh root redhat
$0 : ./dd.sh
$1 : root
$2 : redhat
$# : 2
$* : root redhat

1.12shell 脚本中条件判断

1.返回 shell中 0(ture)或 1(flase)结果
if/then 结构
2.test 或者[]执行 shell 测试,返回 shell 结果。[]中写入测试条件,注意[空格 测
试条件 空格]
3.测试条件:
 
字符的比较 
数字的比较
代表的意思
== 
-eq  相等 
>  
-gt  大于
-lt  小于 
!=
 -ne   不等于
<=  
-le  小于等于
>= 
-ge  大于等于

 

-a:逻辑与,并且;-o:或者,逻辑或
4.bash2.02 版本以上[[……]]
5.返回常规编程语言格式的结果
((……))和 let……还可以做数字的比较 
[root@desktop29 ~]# [ "qq" != "cc" ];echo $?
0
[root@desktop29 ~]# [ 100 -eq 12 ];echo $?
1
[root@desktop29 ~]# echo "100 / ( 5 + 5)" | bc
10

1.13 测试文件或文件夹属性 

1.常见判断
-a 文件是否存在
-b 文件是否为块设备
-d 文件是否为目录
-s 文件大小是否为 0
-r 文件是否可读
-w 文件是否可写
-x 文件是否可执行
#man bash 获得更多解释 
[root@desktop29 /]# touch ff
[root@desktop29 /]# chmod 111 ff
[root@desktop29 /]# su - student root #用户则测不出文件的 r,w,x 属性
[student@desktop29 ~]$ [ -w /ff];echo $?
1
[student@desktop29 ~]$ [ -f /ff ];echo $?
0
[student@desktop29 ~]$ [ -x /ff ];echo $?
0
[student@desktop29 ~]$ [ -d /ff -a -x /ff ];echo $? #-a 是and,非目录,所以为 1
1
实例:写一个脚本判断目录下的文件和目录的属性,并打印:
[student@desktop29 ~]$ cat ds.sh
#!/bin/bash
echo -e "please input a doc\nexample /etc"
read DD
D=directory
F=file
for RR in $DD/*
do
if [ -d $RR ];then
if[ -w $RR -a -r $RR -a -x $RR ];then
echo -e "$RR\t\t$D-rwx"
else
if [ -w $RR -a -r $RR ] ;then
echo -e "$RR\t\t$D-wr"
else
if [ -w $RR -a -x $RR ] ;then
echo -e "$RR\t\t$D-wx"
else
if [ -x $RR -a -r $RR ] ;then
echo -e "$RR\t\t$D-xr"else
if[ -w $RR ] ;then
echo -e "$RR\t\t$D-w"
else
if [ -r $RR ] ;then
echo -e "$RR\t\t$D-r"
else
if[ -x $RR ] ;then
echo -e "$RR\t\t$D-x"
fi
fi
fi
fi
fi
fi
fi
else
if [ -f $RR ] ;then
if [ -w $RR -a -r $RR -a -x $RR ];then
echo -e "$RR\t\t$F-rwx"
else
if[ -w $RR -a -r $RR ] ;then
echo -e "$RR\t\t$F-wr"
else
if [ -w $RR -a -x $RR ] ;then
echo -e "$RR\t\t$F- wx"
else
if [ -x $RR -a -r $RR ] ;then
echo -e "$RR\t\t$F- xr"
else
if[ -w $RR ] ;then
echo -e "$RR\t\t$F- w"
else
if [ -r $RR ] ;then
echo -e "$RR\t\t$F- r"
else
if[ -x $RR ] ;then
echo -e "$RR\t\t$F- x"
fi
fi
fi
fi
fi
fi
fi
fi
fi
done

1.14if……else……fi 

语法:
if[判断条件]
then
命令 1
命令 2
else
命令 3
命令 4
fi 
实例:依据钱数决定吃快餐或吃 KFC之 if-else-fi 版
编辑脚本:
[root@localhost ~]# vim eat.sh
#!/bin/bash
echo " money :"
read FF
if [ $FF -lt 5 ];then
echo "fastfood"
else
echo "KFC"
fi
修改权限
[root@localhost ~]# chmod u+x eat.sh
测试
[root@localhost ~]# ./eat.sh
money :
4
fastfood
[root@localhost ~]# ./eat.sh
money :
6
KFC

1.15&&和||以及[[……]] 

1.&&与运算,||或运算,不能使用在[……]之间,只能使用在[[……]]之间
2.单独使用,&&代表之前的条件 true 时,||代表之前的条件 false
3.[[……]]这是一个扩展测试命令,使用该命令可以防止在脚本中出现的逻辑错误信息,如
&&、||、<和>;在[[……]]可以自动计算十进制和 8/16 进制的值
1.&&在[]与[[]]之间的区别:
[root@localhost ~]# [[ -d /tmp && -w /tmp ]];echo $?
0
[root@localhost ~]# [ -d /tmp && -w /tmp ];echo $?
bash: [: missing `]'
2
2 依据钱数决定吃快餐或吃 KFC-逻辑符号版
#!/bin/bash
echo " money :"
read FF
[ $FF -lt 5 ] && echo "fastfood" || echo "KFC"
测试:
[root@localhost ~]# ./eat.sh
money :
5
KFC
[root@localhost ~]# ./eat.sh
money :
1
fastfood

1.16if 语句的直接使用 

if 语句可以直接接 shell语句,根据$?判断:
[root@localhost ~]# cat if_shell.sh
#!/bin/bash
D=/etc
if cd $D &> /dev/null;then #直接接 shell 命令
echo "now in $D"
else
echo "can't change to $D"
fi
[root@localhost ~]# ./if_shell.sh
now in /etc

1.17if 语句的嵌套 

实例:菜单项的选择之 if 嵌套版,
选择1,2,3来显示进入的状态,如果没有输入则打印what do you like?,如果输入的不
是 1,2,3 中的一个,则打印 please choose:1,2,3 并退出 
[root@localhost ~]# cat mu.sh
#!/bin/bash
echo "please choose:1,2,3"
echo "1.linux"
echo "2.win7"
echo "3.quit"
read CH
if [ "$CH" != "" ];then
if [ $CH -eq 1 ] ;then
echo " wellcom to linux"
else
if [ $CH -eq 2 ];then
echo "wellcom to win7"
else
if [ $CH -eq 3 ];then
echo "quit"
else
echo "please choose 1,2,3"
fi
fi
fi
else
echo "what do you like?"
fi
测试:
[root@localhost ~]# ./mu.sh
please choose:1,2,3
1.linux
2.win7
3.quit
what do you like?
[root@localhost ~]# ./mu.sh
please choose:1,2,3
1.linux
2.win7
3.quit
1
wellcom to linux

1.18if……then……elif 

多级 if……then……else 可以替换 if 的嵌套使用,直接使用一个或多个测试条件
将菜单项的选择作修改:
#!/bin/bash
echo "please choose:1,2,3"
echo "1.linux"
echo "2.win7"
echo "3.quit"
read CH
if [ "$CH" != "" ];then
if [ $CH -eq 1 ] ;then
echo " wellcom to linux"
elif [ $CH -eq 2 ];then
echo "wellcom to win7"
elif [ $CH -eq 3 ];then
echo "quit"
else
echo "please choose 1,2,3"
fi
else
echo "what do you like?"
fi

1.19exit 退出代码 

shell脚本执行后如果不成功则会返回一个非0 的值,exit 可以实现脚本退出时返回值,我们可以根据不同的返回值看出是哪个脚本出现问题。 
实例:如果用户输入的是目录,则返回值为 1,如果不是则返回 4
#!/bin/bash
echo -e "input a dir\nexample /etc"
read DD
if [ -d $DD ];then
echo " $DD is a directory"
exit 1
else
echo "$DD is not a directory or not exit"
exit 4
fi
测试:
[root@localhost ~]# ./exit.sh
input a dir
example /etc
/etc
/etc is a directory
[root@localhost ~]# echo $?
1
[root@localhost ~]# ./exit.sh
input a dir
example /etc
/dd
/dd is not a directory or not exit
[root@localhost ~]# echo $?
4

1.20  loop 循环 

1.循环的定义:计算机可以重复的执行特定的指令,知道给定的条件满足为止。
2.bash 中的循环:for loop ;while loop
3.注意:
每个循环使用时,首先用在循环中的变量要在循环之前初始化,然后对每次循环都要对
条件测试,最后在循环体中执行一次需要对循环测试条件值修改 

1.21  for loop 

语法:
for 变量名 in 列表
do
循环体
done
列表时一个集合,集合由空格间隔,可以是以下几中:
数字/字符集合
1 2 3 6 7
{1..254}
文件集合
/etc/*.conf
指令结果集合
$(find /etc -perm -002) 
实例:
1.数字集合
99 乘法表:
#!/bin/bash
for A in {1..9}
do
for B in {1..9}
do
RE=$( expr $A \* $B )
echo " $A * $B = $RE "
done
done
测试:
[root@localhost ~]# ./9X9.sh
1 * 1 = 1
…… ……
3 * 1 = 3
…… ……
9 * 9 = 81
用脚本编辑 iptables 规则脚本: 
#!/bin/bash
echo "#!/bin/bash" >> /bin/setFilewall.sh
for IP in {1..254}
do
echo "iptables -I INPUT -s 192.168.0.$IP -p tcp --dport 80 -j ACCEPT"
>> /bin/setFilewall.sh
echo "iptables is making..."
done
测试:
[root@localhost ~]# ./iptables.sh
iptables is making...
iptables is making...
…………
[root@localhost ~]# tail /bin/setFilewall.sh -n 2
iptables -I INPUT -s 192.168.0.253 -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -s 192.168.0.254 -p tcp --dport 80 -j ACCEPT
2.文件集合 
for FF in /root/cc/*
do
cp $FF $FF.bak -pv
done
测试:
[root@localhost ~]# ./chmod_cc.sh
`/root/cc/1.cc' -> `/root/cc/1.cc.bak'
`/root/cc/2.cc' -> `/root/cc/2.cc.bak'
…… ……
3.指令集合的实验 
#!/bin/bash
for FF in $(find /root/cc -perm +002)
do
chmod o-w $FF
echo "$FF :o-w"
done

1.22 for 循环 c 语言格式 

((……))不需要使用$来实现对 shell 变量名的调用。特别要注意的是此类语法的逻辑和
shell截然相反,在(())中,0 代表 false,所有非 0 代表 true 例如:
1.
for ((i = 0;i<= 5;i ++))
do
echo "welcome $i times "
done
建议不要使用在 if-then 中
2.if(( UID > 0 )) ; then ; echo " Welcome root " ; fI 
例子:
国际象棋棋盘:算法(行和列号相加后的结果对 2 取余,为 0 的就是白色块,不为 0 的就
是黑色块。) 
#!/bin/bash
for ((A=1;A<=9;A++)) 等同于 for A in {1..9}
do
for ((B=1;B<=9;B++))
do
C=$( expr $A + $B )
D=$( expr $C % 2 ) #取余运算
if [ $D -eq 0 ];then
echo -en "\033[30;40m \033[0m"
else
echo -en "\033[37;47m \033[0m"
fi
done
echo -e
done

1.23for 循环的练习 

练习:编辑一个监控服务器的脚本,将信息显示在屏幕上,错误信息记录在日志里: 
for FF in $(cat /etc/ser.conf | grep -Ev "^(#|$)" )
do
#if 后不能用[ping -c2 $FF &> /dev/nul],无论能否 ping 通,返回结果都是非 0
if ping -c2 $FF &> /dev/nul ;then
echo "$FF is up..."
else
echo "$FF is down..."
logger "$FF is down ..."
fi
done

1.24while 循环 

语法:
while [ 条件测试 ]
do
命令
done
注意:要修改测试条件的值,防止死循环,可以与 if-then-fi嵌套使用,用 exit 函数退出
实例: 
CHOOSE=0
while [[$CHOOSE != "Q"&& $CHOOSE != "q" ]]
do
if (( CHOOSE !="0" )) ; then
echo -e "Please input \033[33mq \033[0m to quit"
sleep 4
fi
clear
echo " 1 . Linux "
echo " 2 . Uni x "
echo " Q .Qui t "
read CHOOSE
echo "Please Input \033[ 33mq \033[0m to quit "
done
练习:实现菜单选择,如果选择错误则重新显示菜单,直到选对。 
#!/bin/bash
IN=0
while [ "$IN" != "3" ]
do
echo "1.linux"
echo "2.windows"
echo "3.quit"
read IN
if [ $IN -eq 1 ];then
echo "wellcom to linux"
exit 1
elif [ $IN -eq 2 ];then
echo "wellcom to windows"
exit 2
elif [ $IN -eq 3 ];then
exit 3
else #选错了就会清屏后提示 please input 1\2\3 并打印菜单
clear
echo "please input 1\2\3"
fi
done

1.25case 语句 

case 语句是 if-then-elfi的替代语句 语法:
case 变量名 in
匹配 1) 命令;;
匹配 2) 命令;;
匹配 3) 命令;; *) 命令;;
esac
实例: 
PIDFIL E=/var/spool /test . pid
case $1 in
" start")
if [ - e $PIDFILE ] ; then
echo " the testcase has already run"
else
echo $$ > $PIDFILE ; echo " starting now. . . "
fi ;;
" stop")
kill -9 $( cat $PIDFILE ) ; rm - f $PIDFILE ; ;
" status")
....
*) # 默认值, 匹配所有上面没有给定的值
echo " Usage : /etc/init.d/testcase (start|stop|status) ";;
esac
练习:写一个自己的服务,能像其他服务一样用 chkconfig 开启: 
#!/bin/bash
#chkconfig: 345 45 67 #这 2 行必须要有才能被 chkconfig 解读
#description: this is myserver
case $1 in
start)
echo "myserver is started...";;
stop)
echo "myserver is stoped...";;
*) echo " $0 { start|stop}"
esac
修改执行权限
[root@localhost ~]# chmod u+x myserver.sh
2.复制到/etc/init.d 下,并修改名字
[root@localhost ~]# cp myserver.sh /etc/init.d/myserver
测试:
[root@localhost ~]# chkconfig myserver on
[root@localhost ~]# chkconfig --list | grep myserver
myserver 0:off 1:off 2:on 3:on 4:on 5:on 6:off
[root@localhost ~]# /etc/init.d/myserver start
myserver is started... 

1.26 如何调试脚本 

-v:打印 shell脚本执行的行号
[root@localhost ~]# bash -v testvx.sh #将整个脚本都展示出来,并执行
#!/bin/bash
echo "plese input a number"
plese input a number
read N
3
R=$( expr $N \* $N )
expr $N \* $N
echo "$N * $N = $R "
3 * 3 = 9
-x:对每一个指令作展开计算
[root@localhost ~]# bash -x testvx.sh #用++与+来区分计算和非计算
+ echo 'plese input a number'
plese input a number
+ read N
5 输入
++ expr 5 '*' 5
+ R=25
+ echo '5 * 5 = 25 '
5 * 5 = 25 脚本计算的结果

1.27 函数的使用 

函数是一系列的指令或命令
本身不运行,可以多次调用,简化代码
语法:
函数名 ()
命令 1;命令 2
return #返回值
函数的参数:
函数也可以作为一个程序一样运行,接收参数
方式:函数名 参数 1 参数 2
在函数方法体中参数可以用$1、$2 来表示对应的参数 1、参数 2
实例: 
max ( )
{
if(( $1 > $2 )); then
return $1 # 注意, 此时函数已经结束了
fi
return $2
}
max 10 100
echo $? # 通过 $ ? 取得函数的返回值
setPath ( )
{
PAT H=/bin:/usr/bin
if (( $UID == 0 )) ; then # 如果为 root
PATH = $PATH:/usr/bin/sbin:/sbin # 路径追加 sbin 的目录
fi
i f (( $2 == "after" )); then # 根据位置参数 2,决定如何添加新路径
PATH = $PATH:$1 # 在原 PATH 后面追加
else
PATH=$1:$PATH # 在原 PATH 之前添加
fi
}

 

练习 1:结合之前学的语言,使用函数的方式,编写一个菜单选项的脚本,能实现选择菜单
并执行该菜单的功能:
#!/bin/bash
showmanu () #展示菜单的函数
{
echo -e "1.linux\n2.windows\n3.quit"
read IN
}
testchoose () #测试用户输入选项的函数
{
if [ $IN -eq 1 ] ;then
echo "wellcom to linux"
exit 1
elif [ $IN -eq 2 ] ;then
echo "wellcom to windows"
exit 2
elif [ $IN -eq 3 ] ;then
exit 3
else
clear
echo "please input 1\2\3"
fi
}
main () #当选择错误时,需要循环的显示菜单和测试用户输入的选项
{
IN=0
while [ "$IN" != "3" ]
do
showmanu #调用菜单函数
testchoose #调用测试选项函数
done
}
main #调用函数
练习 2:在一个脚本中调用其他脚本:
脚本 1:f.sh
#!/bin/bash
echo "---脚本 1---"
echo "test server..."
脚本 2:ff.sh
#!/bin/bash
[ $# -eq 1 ] && (
for F in $1/*
do
[ -d $F ] && echo "$F is a directory"
done ) || echo "please input a right directory"
调用测试脚本:
#!/bin/bash
F=/root/f.sh
FF=/root/ff.sh
menu ()
{
echo -e "1.testServer\n2.findDir\n3.quit"
}
main ()
{
menu
read INPUT
case $INPUT in
1)
bash $F
;;
2)
bash $FF /etc #调用时,可以带参数
;;
3)
exit -1 ;;
*)
clear #清屏
main #调用 main 函数
esac
}
main

1.28I/O 重定向和文件描述

• Linux 经常使用到的 1>,>, &>重定向,各自代表着标准输出,标准错误,以及两者
都包括(1&&2)
• Linux 同时除以上的几个重定向外提供给我们0-10 的其他文件描述(File Description:
FD)
• 它可以用来对前者的信息做一备份 ,之后再重新调用其信息

1.29 重定向的高级应用

>&n 使用系统调用 dup(2)复制文件描述符 n 并把结果用作标准输出;
<&n 标准输入复制自文件描述符 n;
<&- 关闭标准输入(键盘);
>&- 关闭标准输出;
n<&- 表示将 n 号输入关闭;
n>&- 表示将 n 号输出关闭;
上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的
0 或 1。如:
. .. 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。
. .. 2>&1 运行一个命令并把它的标准输出和输出合并。(通过复制文件描述符 1 来建立
文件描述符 2,合并了两个流。)
2>&1 也就是 FD2=FD1 ,把 FD2 的“数据输出通道” 改为 FD1 的“数据输出通道”。因
为 FD2 的默认输出和 FD1 的默认输出本来都是 monitor,一样的!
exec 1>outfilename # 打开文件 outfilename 作为 stdout。
exec 2>errfilename # 打开文件 errfilename 作为 stderr。
exec 0<&- # 关闭 FD0。
exec 1>&- # 关闭 FD1。
exec 5>&- # 关闭 FD5。
exec 3>&1; exec 4>&1 #建立FD3; 把 FD3看作最初始的 FD1 的硬盘备份
ss=$(((ls you no 2>&1 1>&3 3>&-; echo $?>&4)|egrep \ >file) 4>&1)*exec 3>&-; exec 4>&- #关闭 FD3、FD4。
 
posted @ 2019-05-28 16:17  邹姣姣  阅读(233)  评论(0编辑  收藏  举报