shell是解释性脚步语言,无需编译,通过解释器解释运行;但类似于shell、lua、awk、python这种脚步语言都有着非常多的用途,例如自动化测试、自动化运维等等,所以学会使用它们将会编程自己的得力工具。
一、shell怎么执行?
1、一条一条输入,每输入一条系统执行一条;称之为交互式执行。
2、执行一个完整的脚本文件,包含多条命令或者复杂结构;类似于Windows下的批处理。
二、shell脚步执行需要解释器,Unix/Linux下通常有bash、sh、ash、csh、ksh等shell解释器,在unix下默认的解释器为sh,在linux下默认的解释器为bash。
第一个shell脚本:first.sh
1 #!/bin/bash 2 #第一个脚本,helloworld 3 #脚本名:first.sh 4 5 echo “hello,world ~”
#!是shell脚本的标准开始,意为告诉系统当前脚本使用的解释器为/bin/bash;之后的所有#开头的内容都为注释;echo的作用是向终端输出。
三、shell脚本有两种执行方式:
1、给脚本添加执行权限之后当做可执行文件执行即可:chmod +x first.sh ;./first.sh
2、显式用解释器解释执行:/bin/sh first.sh
四、怎么写shell脚本?你需要知道以下内容:
1、shell和其他编程语言一样支持自定义变量,包括全局变量、局部变量、环境变量、特殊变量;
①、定义变量以及相关操作:变量名=value #变量名和等号之间不能有空格
1 my_value=123456 #全局变量 2 echo “$my_value” #使用一个定义过的变量,只要在变量名前面加美元符号($)即可 3 my_value=555333 #变量重新赋值 4 readonl my_value #设置为只读 5 unset my_value #删除变量
②、变量类型:
1) 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
2) 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
3) shell(特殊)变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
③、特殊变量:
1 $$ #$为当前进程,所以这个变量为当前进程号 2 $? #上个命令的退出状态,或函数的返回值。 3 $0 #脚本名,即第一个参数 4 $N #表示第N个参数 5 $@ #传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同 6 $* #传递给脚本或函数的所有参数。 7 $# #传递给脚本或函数的参数个数。 8 # $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。 9 # 被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
③、命令行参数:运行脚本时传递给脚本的参数称为命令行参数。命令行参数用 $n 表示,例如,$1 表示第一个参数,$2 表示第二个参数,依次类推。
④、命令替换:命令替换是指Shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。语法为:`cmd`
1 #!/bin/bash 2 #`cmd`用法 3 4 DATE=`date` 5 echo "Date is $DATE" 6 7 #输出:Date is Thu Jul 2 03:59:57 MST 2009
⑤、变量替换:变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值
${var}:变量本来的值
${var:-word}:如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word}:如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message}:如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值,若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word}:如果变量 var 被定义,那么返回 word,但不改变 var 的值。
1 #!/bin/bash 2 #${var:-var} 3 4 echo ${var:-"Variable is not set"} 5 echo "1 - Value of var is ${var}" 6 7 #输出为: 8 #Variable is not set 9 #1 - Value of var is
2、运算符:
①、算术运算:原生bash不支持简单的数学运算,但是可以通过expr实现
#!/bin/bash value=`expr 2 \* 3` #特殊字符需要转义,表达式和运算符之间都必须有空格 echo $value #输出 6
②、关系运算:关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
#!/bin/sh a=10 b=20 if [ $a -eq $b ] #if和[]以及表达式和[]之间都必须有空格
then
echo "$a -eq $b : a is equal to b"
else
echo "$a -eq $b: a is not equal to b"
fi
#输出:10 -eq 20: a is not equal to b
③、布尔运算:与或非
#!/bin/sh a=10 b=20 if [ $a -lt 100 -a $b -gt 15 ];then echo "$a -lt 100 -a $b -gt 15 : returns true" else echo "$a -lt 100 -a $b -gt 15 : returns false" fi
④、字符串运算
#!/bin/sh a="abc" b="efg" if [ -z $a ];then echo "-z $a : string length is zero" else echo "-z $a : string length is not zero" fi if [ $a ];then echo "$a : string is not empty" else echo "$a : string is empty" fi
⑤、文件测试运算:文件测试运算符用于检测 Unix 文件的各种属性。
#!/bin/sh file="~/workspace/test.sh" if [ -r $file ];then echo "File has read access" else echo "File does not have read access" fi if [ -w $file ];then echo "File has write permission" else echo "File does not have write permission" fi
2、注释:shell本身不支持多行注释,需要通过其他方式实现
①、#,单行注释
②、多行注释:方法1
: << ! 语句1 ! #此处空格表示换行,下同
方法2:
:' 语句 '
方法3:
if false; then 语句 fi
方法4:
: << 字符 语句 字符
方法5:
((0)) & { 语句 }
3、字符串操作:
①、单引号:str='aaaaa aaaaaa sss' #单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
②、双引号:str="sss \* ss$?" #双引号里可以有变量,也可以出现转义字符
③、字符串拼接:
#!/bin/bash your_name="qinjx" greeting="hello, "$your_name" !" #方法一 greeting_1="hello, ${your_name} !"#方法二 echo $greeting $greeting_1
④、字符串长度:
str="aaaaaaaaaa" echo ${#str} #输出 10
⑤、提取字串:
str="hello world !" echo ${str:1:4} #输出 ello
⑥、查找子串:通过其他方式实现
str="my name is zhangyi" echo `expr index "$str" zhangyi`
4、数组:bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。
①、定义数组:用括号来表示数组,数组元素用“空格”符号分割开
array=(value0 value1 value2 value3) 或者单独赋值 array_name[0]=value0 ...
②、读取数组:
${array[index]}
③、获取数组的长度:使用@ 或 * 可以获取数组中的所有元素
# 取得数组元素的个数 length=${#array_name[@]} # #求长度 @获取全部 # 或者 length=${#array_name[*]} # 取得数组单个元素的长度 lengthn=${#array_name[n]}
5、echo :echo是Shell的一个内部指令,用于在屏幕上打印出指定的字符串
显示转义字符:echo "\"It is a test\"" #"It is a test"
显示变量:name="zhangyi" ; echo $name #zhangyi
显示换行:echo -e "hello \n world!" #linux下要支持转义字符,需要加-e选项
输出结果重定向:echo "hello world" >log.txt
显示命令执行结果:echo `date`
6、printf:printf 命令用于格式化输出, 是echo命令的增强版
语法格式:printf format-string [arguments...] #例如 printf "%d %s\n" 1 "abc"
7、if...else...fi :
格式:
if [ expression ] then Statement(s) to be executed if expression is true else ... fi
8、if...else...elif...fi:
if [ expression 1 ];then Statement(s) to be executed if expression 1 is true elif [ expression 2 ];then Statement(s) to be executed if expression 2 is true elif [ expression 3 ];then Statement(s) to be executed if expression 3 is true else Statement(s) to be executed if no expression is true fi
9、test :数值(-eq -nq -lt -gt -le -ge)、字符串(= != -z -n)、文件(-r -w -x ...)
num1=100 num2=100 if test $[num1] -eq $[num2] then echo 'The two numbers are equal!' else echo 'The two numbers are not equal!' fi
10、case ... esac:与其他语言中的 switch ... case 语句类似,是一种多分枝选择结构。
#语法 case 值 in 模式1) command1 ;; 模式2) command2 ;; *) #相当于default command3 ;; esac
11、for
for 变量 in 列表 do cmd done
12、while:条件为真一直执行
while cmd do Statement(s) to be executed if cmd is true done
13、until:until 循环执行一系列命令直至条件为 true 时停止
until cmd do Statement(s) to be executed until cmd is true done
14、break和continue :用法同C
15、函数返回值、删除函数、在终端调用函数
①、Shell 函数的定义
function function_name ()
{ list of commands [ return value ] }
②、函数调用:调用函数只需要给出函数名,不需要加括号。
③、函数参数:调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值
16、输入输出重定向:
标准流:标准输入0;标准输出1;标注错误2;
cmd > file #输出重定向
cmd < file #输入重定向
cmd >> fiel #在末尾追加
全部格式如下:
/dev/null 文件:如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null
17、文件包含
Shell 中包含脚本可以使用:
. filename #. 和文件名之间有空格
或
source filename
总结:在有C或其他编程语言基础的前提下,掌握shell并不难,在熟悉各种语法特性的前提下便可游刃有余的编写自己的脚步来完成各种你想完成的任务。