Shell教程 

1.0 简介 

Shell环境: 

Shell 编程跟Java,php一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚步解释器就可以来了。 

Linux 的Shell种类众多, 常见的有: 

 Bourne Shell (/usr/bin/sh 或/bin/sh) 

 Bourne Again Shell (/bin/bash) 

 C Shell (/usr/bin/csh) 

 K Shell (/usr/bin/ksh) 

 Shell for Root (/sbin/sh) 


本教程关注的是Bash,即Bourne Again Shell,Bash在日常工作中被广泛使用,同事Bash也是大多数Linux系统默认的Shell 


在一般情况下,人们并不区分Bourne Shell 和Bourne Again Shell,所以像#!/bin/sh ,它也同样可以改为#!/bin/bash 


#! 告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程序 



第一个Shell: 


Hello.sh 


#!/bin/bash 


echo "Hello World" 


执行Shell脚本有两种方式: 

第一种:作为可执行程序 

 chmod +x Hello.sh 

 ./Hello.sh 


注意,一定要写成./Hello.sh,而不是Hello.sh,运行其它二进制的程序也一样,直接写Hello.sh,linux系统会去PATH里寻找有没有叫Hello.sh的,而只有/bin, /sbin, /usr/bin,/usr/sbin等在PATH里,你的当前目录通常不在PATH里,所以写成Hello.sh是会找不到命令的,要用./ Hello.sh告诉系统说,就在当前目录找。 




第二种:作为解释器参数 

 这种运行方式是,直接运行解释器,其参数就是shell脚步的文件名,如: 


/bin/bash Hello.sh 


这种方式运行的脚本,不需要再第一行指定解释器信息,写了也没用。 



常识: 

如何查看当前系统所用的shell类型? 

# echo $0 

-bash 



2.0 变量 

定义变量时,变量名不加美元符号$, 如: 

you_name=”tingyu” 


注意:变量名和等号直接不能有空格,变量名的命名需遵守如下规则: 

 首个字符必须为字母(a-z, A-Z) 

 中间不能有空格,可以使用下划线 

 不能使用标点符号 

 不能使用bash里的关键字 


 除了显式的直接赋值,还可以用语句给变量赋值,如: 

 #!/bin/bash 

 #打印目录下的所有文件 

for file in /root/zhangb/* 

 do 

 if [ -f $file ] 

 then 

 echo $file 

 fi 

 done 


 以上语句将/etc 下目录的文件名循环出来 


2.0.1使用变量 

打印变量:(var_scrip.sh) 

 #!/bin/bash 


you_name='zhangsan' 

#一般打印 

echo $you_name 

#用{}确定变量的边界(推荐用法) 

echo ${you_name} 


 #给变量重新赋值(注意 赋值的时候直接使用,引用变量的时候才需要加$符号) 

you_name='lisi' 


 典型的例子: 

 for skill in Ada Coffe Action Java; 

do 

 echo "I am good at ${skill}Script" 

done 


2.0.2只读变量 

使用readonly命令可以将变量定义为只读变量,只能读 ,不能改变变量的值 


my_url="www.baidu.com" 

readonly my_url 

#试图改变只读变量 

my_url="www.sohu.com" 


注意:试图改变只读变量时,会报” my_url: readonly variable” 错误提示 

var_scrip.sh: line 16: my_url: readonly variable 



2.0.3 删除变量 

使用unset命令可以删除变量 


my_home="dengzhou" 

echo ${my_home} 

#删除变量 

unset my_home 

#再次打印变量,变量为空 

echo ${my_home} 


2.0.4 变量类型 

 运行shell时,会同时存在三种变量: 

 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效 

 环境变量:所有的程序,包括shell的启动程序,都可以访问环境变量 

 shell变量:shell变量是由shell程序设置的特殊变量 



2.0.5 shell字符串 

单引号: 

 str='this is a string' 


 单引号字符串的限制: 

 单引号里的任何字符都会原样输出,单引号字符串中的变量时无效的 

 单引号字串中不能出现单引号(对单引号使用转义符也不行) 


双引号: 

 my_name='tingyu' 

str="Hello , I know you are \"${my_name}\" \n " 

echo $str 


输出结果:Hello , I know you are "tingyu" \n 



 双引号的优点: 

 双引号可以有变量 

 双引号可以出现转义字符 


拼接字符串: 

 first_name="zhang" 

last_name="san" 

echo $first_name $last_name 


获取字符串长度: 

 string="abcd" 

echo ${#string} 

 输出结果: 4 


提取字符串: 

string="runoob is a great site" 

#从第二个字符开始提取,提取4个字符 

echo ${string:1:4} 

 输出结果: unoo 


查找字符串: 

 string="runoob is a great site" 

 #查找字符”i 或s” 的位置 

echo `expr index "$string" is 


 输出结果:8 


 注意: 以上脚本中 "`" 是反引号,而不是单引号 "'",不要看错了哦。 



2.0.5 shell数组 

 在shell中,用括号来表示数组,数组元素用”空格”符号分割开。定义数组的一般格式: 


 数组名=(值1 值2 值3 ) 


或者 


array_name=( 

 val0 

 val1 

 val2 

 val3 

) 


还可以单独定义数组的各个分量: 

array_name[0]=value0 

array_name[1]=value1 

array_name[2]=value2 



读取数组: 

 读取数组的一般格式: 

 ${数组名[下标]} 


 例如:value=${array_name[n]} 


 使用@符号可以获取数组中的所有元素,例如: 

 echo ${array_name[@]} 



代码: 

array_name=( 

 'zhangsan' 

 'lisi' 

) 


#打印第一个元素 

echo ${array_name[1]} 


#打印全部的元素 

echo ${array_name[@]} 


#循环打印数组 

for i in ${array_name[@]} 

do 

 echo $i 

done 


获取数组的长度: 

 length=${#array_name[@]} 

 或 

 length=${#array_name[*]} 


获取数组单个元素的长度: 

 length=${#array_name[n]} 


#打印数组的长度 

echo "array_name length=${#array_name[@]}" 


#打印数组的长度 

echo "array_name length=${#array_name[*]}" 


#打印下标未1(即第二个) 元素的长度 

echo "array_name[1] length=${#array_name[1]}" 


输出结果: 

array_name length=2 

array_name length=2 

array_name[1] length=4 


2.0.6 shell注释 

以”#”开头的行就是注释,会被解释器忽略 


shell里没有多行注释,只能每一行加一个#号 


如果需要多行注释,可以将多行用一对{} 括起来,定义为一个函数。 



3.0 传递参数 

 我们可以在执行shell脚本时,向脚本传递参数,脚本内获取 参数的格式为$n, 1为shell脚本的第一个参数,以此类推.. 

 脚本:args.sh 

 #!/bin/bash 


echo "shell args instal........." 


echo "script file name:$0" #获取脚本名称 

echo "first arg:$1" #获取脚本第一个参数 

echo "second arg:$2" 

echo "third arg:$3" 


echo "the args length:$#" #传递到脚本的参数个数 

echo "all args:$*" #输出所有参数 

echo "all args:$@" #输出所有参数 

echo "current process id:$$" #脚本运行的当前进程ID 

echo "last process id:$!" #后台运行的最后一个进程ID 

echo "exit state:$?" #最后命令的退出状态 

echo "options:$-" #shell使用的当前选项,与set命令功能相同 


 #执行脚本 

 # sh args.sh 1 2 3 

shell args instal......... 

script file name:args.sh 

first arg:1 

second arg:2 

third arg:3 

the args length:3 

all args:1 2 3 

all args:1 2 3 

current process id:19635 

last process id: 

exit state:0 

options:Hb 



参数处理 说明 

$# 传递到脚本的参数个数 

$* 以一个单字符串显示所有向脚本传递的参数。 

如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 

$$ 脚本运行的当前进程ID号 

$! 后台运行的最后一个进程的ID号 

$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 

如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 

$- 显示Shell使用的当前选项,与set命令功能相同。 


$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 



$* 和 $@ 的异同点: 

• 相同点:都是引用所有参数。 

• 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。 



#-----------$*的用法---------------- 

for i in "$*";do 

 echo $i 

done 


#-----------$@的用法---------------- 

echo "---------" 


for i in "$@";do 

 echo $i 

done 


输出结果如下: 


1 2 3 

--------- 

1 

2 

3 



4.0 数组 

数组中可以存放多个值。 Bash Shell 只支持一维数组(不支持多维数组)。初始化的时候不需要定义数组大小。数组的元素下标由0开始。 



5.0 运算符 

原生的bash不支持简单的数学运算,但是可以通过其他命令来实现。例如awk 和expr, expr最常用。 

5.0.1 算数运算符 

 val=`expr 2 + 2` 

echo "sum:$val" 


注意:表达式和运算符之间要有空格,不能写成2+2, 中间需有空格 

完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。 

#!/bin/bash 


a=10 

b=20 


val=`expr $a + $b` 

echo "a + b :$val" 


val=`expr $a - $b` 

echo "a - b :$val" 


val=`expr $a \* $b` 

echo "a * b :$val" 


val=`expr $b / $a` 

echo "b / a :$val " 


val=`expr $b % $a` 

echo "b % a :$val" 


if [ $a == $b ] 

then 

 echo "a == b" 

fi 


if [ $a != $b ] 

then 

 echo "a != b" 

fi 


输出结果: 

a + b :30 

a - b :-10 

a * b :200 

b / a :2 

b % a :0 

a != b 



• 乘号(*)前边必须加反斜杠(\)才能实现乘法运算; 


5.0.2 关系运算符 

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。 


if [ $a -eq $b ] 

then 

 echo "$a -eq $b: a == b" 

else 

 echo "$a -eq $b: a != b" 

fi 



if [ $a -ne $b ] 

then 

 echo "$a -ne $b: a == b" 

else 

 echo "$a -ne $b: a != b" 

fi 



输出结果: 

10 -eq 20: a != b 

10 -ne 20: a == b 



算符 说明 举例 

-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。 

-ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 

-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。 

-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。 

-ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。 

-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。 



5.0.3 布尔运算符 

下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20: 

运算符 说明 举例 

! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。 

-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。 

-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 



5.0.4 字符串运算符 

下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg": 

运算符 说明 举例 

= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。 

!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。 

-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。 

-n 检测字符串长度是否为0,不为0返回 true。 [ -n $a ] 返回 true。 

str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。 



a="abc" 

b="def" 


if [ $a = $b ] 

then 

 echo "$a = $b: a == b" 

else 

 echo "$a = $b: a != b" 

fi 



if [ $a != $b ] 

then 

 echo "$a != $b: a != b" 

else 

 echo "$a != $b: a == b" 

fi 


if [ -z $a ] 

then 

 echo "-z $a : length==0" 

else 

 echo "-z $a : length !=0" 

fi 


if [ $a ] 

then 

 echo "$a : is not null" 

else 

 echo "$a : is null" 

fi 


输出结果: 

abc = def: a != b 

abc != def: a != b 

-z abc : length !=0 

abc : is not null 



5.0.5 文件测试运算符 

文件测试运算符用于检测 Unix 文件的各种属性。 

属性检测描述如下: 

操作符 说明 举例 

-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。 

-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。 

-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。 

-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。 

-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。 

-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。 

-p file 检测文件是否是具名管道,如果是,则返回 true。 [ -p $file ] 返回 false。 

-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。 

-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。 

-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。 

-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。 

-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。 

-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。 



5.0.6 逻辑运算符 

以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20: 

运算符 说明 举例 

&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false 

|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true 



6.0 echo命令 

echo命令,用于字符串输出。 



#!/bin/bash 

#显示普通字符串 

echo "It is a test" 

#显示转义字符 

echo "\"It is a test\"" 


#显示换行 

echo -e "ok ! \n" # -e开启转义 

echo "Hello" 


echo -e "OK ! \c" # -e 开启转义 \c不换行 

echo "World" 


#重定向字符串到文件 

echo "It is a test" >echo.txt 


#read命令从标准输入中读取一行,并将值赋值为shell变量 

read name 


echo "Hello World,$name " 


#原样输出字符串,不进行转义或去变量(用单引号) 

echo '$name\"' 


echo `date` 



输出结果: 

It is a test 

"It is a test" 

ok ! 


Hello 

OK ! World 

zhangsan 

Hello World,zhangsan 

$name\" 

Thu Aug 11 16:08:36 CST 2016 



7.0 printf命令 

输出命令:printf 

该命令模仿C程序库的priintf()程序,标准所定义,因此使用printf的脚本比使用echo的移植性好。 printf不会像echo自动换行,这里可以使用 \n 进行处理。 


printf 语法: 

 printf format-string [arguments] 


参数说明: 

• format-string: 为格式控制字符串 

• arguments: 为参数列表。 


#!/bin/bash 



printf "Hello World \n" 


printf "%-10s %-8s %-4s\n" name sex weight 

printf "%-10s %-8s %-4s\n" zhangsan F 66.1 

printf "%-10s %-8s %-4s\n" lisi M 56.9 


# format-string为双引号 

printf "%d %s\n" 1 "abc" 


# 单引号与双引号效果一样 

printf '%d %s\n' 1 "abc" 


# 没有引号也可以输出 

printf %s abcdef 


printf %s abc def 


printf "%s\n" abc def 


# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用 

printf "%s %s %s \n" a b c d e f g h i j 


# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替 

printf "%s and %d \n" 



输出结果: 

Hello World 

name sex weight 

zhangsan F 66.1 

lisi M 56.9 

1 abc 

1 abc 

abcdefabcdefabc 

def 

a b c 

d e f 

g h i 

j 

 and 0 



printf的转义序列 

序列 说明 

\a 警告字符,通常为ASCII的BEL字符 

\b 后退 

\c 抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略 

\f 换页(formfeed) 

\n 换行 

\r 回车(Carriage return) 

\t 水平制表符 

\v 垂直制表符 

\\ 一个字面上的反斜杠字符 

\ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效 

\0ddd 表示1到3位的八进制值字符 


8.0 test命令 

test命令用于检测某个条件是否成立,它可以进行数值,字符串和文件三个方面的测试。 


数值测试: 

参数 说明 

-eq 等于则为真 

-ne 不等于则为真 

-gt 大于则为真 

-ge 大于等于则为真 

-lt 小于则为真 

-le 小于等于则为真 



字符串测试: 

参数 说明 

= 等于则为真 

!= 不相等则为真 

-z 字符串 字符串的长度为零则为真 

-n 字符串 字符串的长度不为零则为真 



文件测试: 

参数 说明 

-e 文件名 如果文件存在则为真 

-r 文件名 如果文件存在且可读则为真 

-w 文件名 如果文件存在且可写则为真 

-x 文件名 如果文件存在且可执行则为真 

-s 文件名 如果文件存在且至少有一个字符则为真 

-d 文件名 如果文件存在且为目录则为真 

-f 文件名 如果文件存在且为普通文件则为真 

-c 文件名 如果文件存在且为字符型特殊文件则为真 

-b 文件名 如果文件存在且为块特殊文件则为真 



脚本:more test.sh 

#!/bin/bash 


num1=100 

num2=200 


if test $[num1] -eq $[num2] 

then 

 echo 'num1 == num2' 

else 

 echo 'num1 != num2' 

fi 


num1="runoob" 

num2="runoob" 


if test num1=num2 

then 

 echo 'num1=num2' 

else 

 echo 'num1 !=num2' 

fi 



if test -e /root/zhangb/study/Hello.sh 

then 

 echo "file exsit" 

else 

 echo "file not exsit" 

fi 



9.0 流程控制 

if 格式: 

if condition 

then 

 command1 

 command2 

fi 

写成一行(适用于终端命令提示符): 

if [ ps –ef |grep –c “ssh” ]; then echo “true”; fi 



if else格式: 

if condition 

then 

 command1 

 command2 

else 

 command3 

 command4 

fi 


if else-if else 格式: 

if condition 

then 

 command1 

elif condition 

then 

 command2 

else 

 command3 

fi 


for 循环: 

for var in item1 item2…. itemN 

do 

 command1 

 command2 

done 


写成一行: 

for var in item1 item2… itemN;do command1;command2…. done; 


while循环: 

while condition 

do 

 command 

done 


until循环: 

until condition 

do 

 command 

done 



case分支判断: 

case 值 in 

 模式1) 

 command1 

 command2 

 ;; 

 模式2) 

 command3 

 command4 

 ;; 

 *) 

 command5 

 ;; 

esac 



breank命令: 


continue命令: 


esac: 

case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break 

--------------------------------------------------------------------------------------------------------------------------------- 

#!/bin/bash 


a=10 

b=20 


echo "------if elif else -----------" 


if [ $a == $b ] 

then 

 echo "a == b" 

elif [ $a -gt $b ] 

then 

 echo "a > b" 

elif [ $a -lt $b ] 

then 

 echo "a < b" 

else 

 echo "no....." 

fi 



num1=$[2*3] 

num2=$[1+5] 


if test $[num1] -eq $[num2] 

then 

 echo "num1 == num2" 

else 

 echo "num1 != num2" 

fi 


echo "-------for---------" 

for loop in 1 2 3 4 5 

do 

 echo "The value is $loop" 

done 



echo "---------while-----------" 

int=1 

while(( $int<=5 )) 

do 

 echo $int 

 let "int++" 

done 


echo "---------while无限循环-----------" 

while : 

do 

 echo " 00000 " 

 sleep 2 

done 


echo "---------while无限循环-----------" 

while true 

do 

 echo " while true " 

 sleep 3 

done 


echo "----------case用法----------" 

echo "input 1 to 4:" 

read aNum 

case $aNum in 

 1) 

 echo "You choice 1" 

 ;; 

 2) 

 echo "You choice 2" 

 ;; 

 3) 

 echo "You choice 3" 

 ;; 

 4) 

 echo "You choice 4" 

 ;; 

 *) 

 echo "You not input 1 to 4...." 

 ;; 

esac 



echo "-------break用法-----------" 

while : 

do 

 echo -n "input 1 to 5 number:" 

 read aNum 

 case $aNum in 

 1|2|3|4|5) echo "You input num is:$aNum" 

 ;; 

 *) echo "You input num is not 1 to 5 ,Game over" 

 break 

 ;; 

 esac 

done 



echo "-------continue用法------------" 

while : 

do 

 echo -n "input 1 to 5 Number:" 

 read aNum 

 case $aNum in 

 1|2|3|4|5) echo "You put Num is: $aNum" 

 ;; 

 *) echo "You input error" 

 continue 

 echo "Game over" 

 ;; 


 esac 

done 



10.0函数 

shell中函数的格式定义如下: 

[ function ] funname [ () ] 

{ 

 action; 

 [ return int; ] 

} 


注意: 

 参数返回,可以显式加: return 返回,如果不加,将以最后一条命令运行结果作为返回值。return后跟返回值0-255 



#!/bin/bash 


#普通方法 

demoFun(){ 

 echo "this is the first shell function!" 

} 


echo "funtion begain to start......" 

demoFun 

echo "function end...." 


#带返回值的方法 

funWithReturn(){ 

 echo "this function will get the sun of two number...." 

 echo "input the first number:" 

 read aNum 

 echo "input the second number:" 

 read bNum 

 return $(($aNum+$bNum)) 

} 


funWithReturn 

echo "the sum=$?" 



#带参数的方法 

funWithParam(){ 

 echo "the 1 args:$1" 

 echo "the 2 args:$2" 

 echo "the 10 args:${10}" 

 echo "the 11 args:${11}" 

 echo "all args:$*" 

} 


funWithParam 1 2 3 4 5 6 7 8 9 10 11 12 


注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。 

11.0输入/输出重定向 

大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。 

重定向命令列表如下: 

命令 说明 

command > file 将输出重定向到 file。 

command < file 将输入重定向到 file。 

command >> file 将输出以追加的方式重定向到 file。 

n > file 将文件描述符为 n 的文件重定向到 file。 

n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。 

n >& m 将输出文件 m 和 n 合并。 

n <& m 将输入文件 m 和 n 合并。 

<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 



需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。 



输入重定向: 

文件中读取命令或内容 

# wc -l < yunsuan.sh 

80 



重定向深入讲解: 


一般情况下,每个Unix/Linux命令运行时都会同时打开三个文件; 


 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。 

 标准输出文件(stdout):stdout的文件描述符为1,Unix程序默认向stdout输入数据。 

 标准错误文件(stderr):stderr的文件描述符为2,Unix程序默认会向stderr流中写入错误信息。 


如果希望stderr重定向到file,可以这样写: 

command 2 > file 


如果希望stderr追加到到file,可以这样写: 

command 2 >> file 



如果希望stdout 和stderr合并后重定向到file,可以这样写: 

command > file 2>&1 


或者 

command >> file 2>&1 


如果希望stdin和stdout都重定向可以这样写: 

command < file1 > file2 


command命令将stdin重定向到file1 , 将stdout重定向到file2 



Here Document 

Here Document是shell中的一种特殊的重定向方式,用来将输入重定向到一个交互式shell脚本或程序,它的基本形式如下: 

 command << delimiter 

 document 

 delimiter 

它的作用是将两个delimiter之间的内容(document)作为输入传递给command 


注意: 

• 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。 

• 开始的delimiter前后的空格会被忽略掉。 


#!/bin/bash 


#统计EOF之间的行数 

wc -l << EOF 

 www.runoob.com 

 Hello World 

EOF 



#显示EOF直接的文本到终端上 

cat << EOF 

 www.baidu.com 

EOF 



/dev/null 文件 


如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到/dev/null 


command > /dev/null 



12.0文件包含 

和其他语言一样,shell也可以包含外部脚本,这样可以很方便的封装一些公用的代码作为一个独立的文件。 


Shell文件包含的语法格式如下: 

. filename #注意点号(.) 和文件名中间有一个空格 

或者 

source filename 


实例: 

文件clud1.sh: 

#!/bin/bash 


url=http://www.runoob.com 



文件clud2.sh: 

#!/bin/bash 


#use clud1.sh file 

#. /root/zhangb/study/clud1.sh 


source /root/zhangb/study/clud1.sh 


echo "netAddr:$url" 



执行clud2.sh 


# sh clud2.sh 

netAddr:http://www.runoob.com 



 dianxinguangchang.zhongshanerlu.yuexiuqu.guangzhoushi.guangdongsheng 

2016-08-11 19:28