shell编程:
1.自定义变量
Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则:
首个字符必须为字母(a-z,A-Z)
中间不能有空格,可以使用下划线(_)
不能使用标点符号
不能使用bash里的关键字(可用help命令查看保留关键字)
需要给变量赋值时,可以这么写:
变量名=值
要取用一个变量的值,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在"="两边留空格 )
#!/bin/bash#定义变量num=100n=$numecho "num=$num"echo "n=$n"#清除变量numunset numecho "******清除num之后*******"echo "num=$num"echo "n=$n"
2.从终端读取变量
read: 从终端读取变量
readonly: 只读变量,不能修改。
#!/bin/bash#从控制台输入姓名read nameecho "name=$name"name=lisiecho "name=$name"
3.预设变量
预设变量很像C或者Java的主方法的命令行传参。
$n n为数字,$0代表当前执行的进程名,$1— 9 代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如{10}
∗ 这个变量代表命令行中所有的参数, * 这个变量代表命令行中所有的参数, ∗这个变量代表命令行中所有的参数,*把所有的参数看成一个整体
@ 这个变量也代表命令行中所有的参数,不过 @ 这个变量也代表命令行中所有的参数,不过 @这个变量也代表命令行中所有的参数,不过@把每个参数区分对待
$# 这个变量代表命令行中所有参数的个数
$$ 这个变量代表命当前进程的进程号
$? 上一条命令返回的状态,0表示成功,非0表示失败
e.x:
#!/bin/bash#打印当前进程名字echo "current pname is \$0=$0"echo "\$1=$1"echo "\$2=$2"echo "\$3=$3"echo "\$4=$4"echo "\$5=$5"echo "\$6=$6"echo "\$7=$7"echo "\$8=$8"echo "\$9=$9"#打印第十个参数,注意超过10个参数必须使用{}括号。echo "\$10=${10}"#打印所有参数echo "argument number is \$#=$#"echo "\$@=$@"echo "\$*=$*"#打印当前进程编号echo "current pid is \$\$=$$"#测试正确的命令lsecho "command return status is \$?=$?"#测试失败的命令,不存在haha文件ls hahaecho "command return status is \$?=$?"
4.脚本变量特殊用法
双引号" 包含的变量会被解释
单引号’ 包含的变量会当做字符串
反引号` 包含的内容当做命令的执行结果返回
转义字符\ 输出特殊字符,echo命令需加-e转义
(命令序列) 由子shell来完成不影响当前shell的变量
{命令序列} 在当前shell执行会影响当前shell变量
e.x:
#!/bin/bashcity=beijingecho "city is:$city"echo 'city is $city'echo "today is `date`"echo 'today is `date`'echo -e "I am a chinese\nI love china\nI am a programer!"price=50( price=100;echo "inner price=$price" )echo "price=$price"{price=200;echo "inner price=$price";}echo "price=$price"
5.文件测试
-e 文件是否存在
-s 文件是否非空
-b 是否是块设备文件
-c 是否是字符设备文件
-d 是否是目录
-f 是否是普通文件
-L 是否是软链接文件
-S 是否是套接字文件
-p 是否是管道文件
-r 是否可读
-w 是否可写
-x 是否可执行
e.x:
#创建test.sh脚本文件
touch test.sh
#!/bin/bashFILE=test.shecho "文件名是:$FILE"test -e $FILEecho "当前文件是否存在:$?"test -f $FILEecho "当前文件是是普通文件:$?"[ -s $FILE ]echo "当前文件是否为空:$?"[ -d $FILE ]echo "当前文件是否是目录:$?"[ -r $FILE ]echo "当前文件是否可读:$?"[ -w $FILE ]echo "当前文件是否可写:$?"[ -x $FILE ]echo "当前文件是否可执行:$?"[ -L $FILE ]echo "当前文件是否是软件链接文件:$?"[ -S $FILE ]echo "当前文件是否是套接字文件:$?"[ -p $FILE ]echo "当前文件是否是管道文件:$?"
6.字符串测试
s1=s2 判断两个字符串的内容是否相同
s1!=s2 判断两个字符串的内容是否不相同
-z s 判断字符串s的长度是否为零
-n s 判断字符串s的长度是否不为零
注意:=和!= 两边有留有至少一个空格 否则就是赋值语句,永远为真。
#!/bin/bashs1="hello"s2="hello"s3="Hello"test $s1 = $s2echo "s1==s2=>$?"test $s1 = $s3echo "s1==s3=>$?"test $s1 != $s3echo "s1!=s3=>$?"test -z $s1echo "s1 length is zero:$?"test -n $s3echo "s3 length is not zero:$?"
7.数字测试
a -eq b 判断两个数字是否相同
a -ne b 判断两个数字是否不相同
a -gt b 判断a是否大于b
a -ge b 判断a是否大于等于b
a -lt b 判断a是否小于b
a -le b 判断a是否小于等于b
e.x:
#!/bin/bashecho "please input num1 and num2:"read NUM1 NUM2test $NUM1 -eq $NUM2echo "num1==num2=>$?"test $NUM1 -ne $NUM2echo "num!=num2=>$?"test $NUM1 -gt $NUM2echo "num1>num2=>$?"test $NUM1 -ge $NUM2echo "num1>=num2=>$?"test $NUM1 -lt $NUM2echo "num1<num2=>$?"test $NUM1 -le $NUM2echo "num<=num2=>$?"
8.复合测试
command1 && command2 command1返回0才执行command2
command1 || command2 command1返回非0才执行command2
condition1 -a condition2 两边条件都成立,返回0
condition1 -o condition2 两边条件任何一个成立,返回0
! condition 状态取反
e.x:
#!/bin/bashnum=100#命令控制方式写法test $num -gt 0 && test $num -le 200echo "num>0 && num<=200 =>$?"#多重判断写法test $num -gt 0 -a $num -le 200echo "num>0 && num<=200 =>$?"file="test.sh"test -e $file -a -x $fileecho "test.sh file is exist and excuteable:$?"s1="Hello"test $s1 = "hello" -o $s1 = "Hello"echo "s1 equals ignorse case 'hello':$?"
9.if/case控制语句
if语句
if 判断条件 ; then命令fi#或if 判断条件then命令fi
if-else语句
if 判断条件 ; then命令1else命令2fi
多重if-else语句
if 判断条件1 ; then命令1elif 判断条件2 ; then命令2elif 判断条件3 ; then命令3...else命令nfi
case语句
case 变量或表达式 in变量或表达式1)命令1;;变量或表达式2)命令2;;...*)默认命令esac
e.x:
#!/bin/bashread -p "输入月份(1-12的数字):" monthcase $month in1 | 3 | 5 | 7 | 8 | 10 | 12)echo "大月";;2 | 4 | 6 | 9 | 11)echo "小月";;*)echo "输入的月份无效!"esac
10.for循环语句
形式一
for((exp1; exp2; exp3))dostatementsdone
说明:
exp1、exp2、exp3 是三个表达式,其中 exp2 是判断条件,for 循环根据 exp2 的结果来决定是否继续下一次循环;
statements 是循环体语句,可以有一条,也可以有多条;
do 和 done 是 Shell 中的关键字。
#!/bin/bashdeclare -i sumfor ((i=1; i<=100; i++))dosum+=idoneecho "The sum is: $sum"
形式二
for variable in value_listdostatementsdone
variable 表示变量,value_list 表示取值列表,in 是 Shell 中的关键字。
#!/bin/bashdeclare -i sumfor n in {1..100}do#双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令((sum += n))doneecho "The sum is: $sum"
11.while与until语句
while循环
while 循环是 Shell 脚本中最简单的一种循环,当条件满足时,while 重复地执行一组语句,当条件不满足时,就退出 while 循环。
while conditiondostatementsdone
#!/bin/bashdeclare -i sumdeclare -i nwhile [ "$n" != "101" ]dosum+=nn+=1doneecho "the result is :$sum"
until循环
unti 循环和 while 循环恰好相反,当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环。
until conditiondostatementsdone
#!/bin/bashdeclare -i sumdeclare -i nuntil ((n > 100))do((sum += n))((n++))doneecho "the result is :$sum"
12.break与continue
break
使用 while、until、for 循环时,如果想提前结束循环(在不满足结束条件的情况下结束循环),可以使用 break 或者 continue 关键字。
break n
n 表示跳出循环的层数,如果省略 n,则表示跳出当前的整个循环。
e.x:
#!/bin/bashdeclare -i sumfor ((i=1; i<=100; i++))dosum+=iif [ $i -eq 10 ];thenbreak;fidoneecho "The sum is: $sum"
continue
continue n
n 表示循环的层数:
如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。这么说可能有点难以理解,稍后我们通过代码来演示。
e.x:
#!/bin/bashdeclare -i sumfor ((i=1; i<=100; i++))doif [ $i -eq 10 ];thencontinue;fisum+=idoneecho "The sum is: $sum"
break与continue的区别
break 用来结束所有循环,循环语句不再有执行的机会;continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环。
13.shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
函数定义
可以带 function 关键字使用 function fun_name() 来定义,也可以直接给出函数名 fun_name() 定义。不能带任何参数,函数名必须唯一。函数必须先定义,再调用。
#定义方式一function_name() {statements[return value]}#定义方式二function function_name {statements[return value]}
e.x:
#!/bin/bash#函数定义function sayHello(){echo "hello,world!"}#函数调用sayHello
函数传参
使用$1, 2 , … 2,… 2,…n 获取外部传参。
e.x:
#!/bin/bashfunction add(){a=$1b=$2sum=`expr $a + $b`echo "sum=$sum"}#函数调用add 12 7
函数返回值
通常使用$?获取函数的返回值。
e.x:
#!/bin/bashfunction add(){a=$1b=$2sum=`expr $a + $b`return $sum}add 12 7echo "sum=$?"
但是这种方式获取的返回值不能超过255,否则会出错。
e.x:
#!/bin/bashfunction add(){a=$1b=$2sum=`expr $a + $b`return $sum}add 102 700echo "sum=$?"
在shell中除了()中定义的变量,只要不做任何修饰,都可以理解为是一个全局变量,因此在函数体外可以直接获取返回值。
e.x:
#!/bin/bashfunction add(){a=$1b=$2sum=`expr $a + $b`return $sum}add 102 700echo "sum=$sum"
14.其它
追加指定内容至某文件
sed -i '1i 添加的内容' file #这是在第一行前 添加字符串sed -i '$i 添加的内容' file #这是在倒数第二行添加字符串sed -i '$a 添加的内容' file #这是在最后一行添加一行字符串echo '内容' > file #覆盖之前内容,文件只显示添加后的内容echo '内容' >> file #追加内容至最后一行行后
字符串截取
假设有变量: var=/123.htm1. # 号截取,删除左边字符,保留右边字符。代码如下:echo ${var#*//}其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符即删除 http://结果是 :/123.htm2. ## 号截取,删除左边字符,保留右边字符。代码如下:echo ${var##*/}##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符即删除 /结果是 123.htm3. %号截取,删除右边字符,保留左边字符代码如下:echo ${var%/*}%/* 表示从右边开始,删除第一个 / 号及右边的字符结果是:4. %% 号截取,删除右边字符,保留左边字符代码如下:echo ${var%%/*}%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符结果是:http:5. 从左边第几个字符开始,及字符的个数代码如下:echo ${var:0:5}其中的 0 表示左边第一个字符开始,5 表示字符的总个数。结果是:http:6. 从左边第几个字符开始,一直到结束代码如下:echo ${var:7}其中的 7 表示左边第8个字符开始,一直到结束。结果是 :/123.htm7. 从右边第几个字符开始,及字符的个数代码如下:echo ${var:0-7:3}其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。结果是:1238. 从右边第几个字符开始,一直到结束代码如下:echo ${var:0-7}表示从右边第七个字符开始,一直到结束。结果是:123.htm注:(左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示)
修改特定配置文件
FILEN="/opt/hbase/hbase-1.3.1/conf/hbase-site.xml"(cat <<DATA<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="configuration.xsl"?><configuration><property><name>hbase.rootdir</name><value>hdfs://master/hbase</value></property><property><name>hbase.cluster.distributed</name><value>true</value></property><property><name>hbase.zookeeper.quorum</name><value>$ZKNODES_STR</value></property><property><name>hbase.zookeeper.property.dataDir</name><value>/opt/hbase/hbase-1.3.1/zk/data</value></property><property><name>hbase.tmp.dir</name><value>/opt/hbase/hbase-1.3.1/tmp</value></property></configuration>DATA) > $FILEN
Last But Not Least
以上分享如有错误或疑问,请评论留言,大家一起探讨。
原创不易,不要忘记一键三连哦!!!