shell编程指南(全网最全)

shell编程:

1.自定义变量

Shell编程中,使用变量无需事先声明,同时变量名的命名须遵循如下规则:
首个字符必须为字母(a-z,A-Z)
中间不能有空格,可以使用下划线(_)
不能使用标点符号
不能使用bash里的关键字(可用help命令查看保留关键字)
需要给变量赋值时,可以这么写:
变量名=值
要取用一个变量的值,只需在变量名前面加一个$ ( 注意: 给变量赋值的时候,不能在"="两边留空格 )

#!/bin/bash
#定义变量
num=100
n=$num
echo "num=$num"
echo "n=$n"
#清除变量num
unset num
echo "******清除num之后*******"
echo "num=$num"
echo "n=$n"
2.从终端读取变量

read: 从终端读取变量
readonly: 只读变量,不能修改。

#!/bin/bash
#从控制台输入姓名
read name
echo "name=$name"
name=lisi
echo "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 \$\$=$$"
#测试正确的命令
ls
echo "command return status is \$?=$?"
#测试失败的命令,不存在haha文件
ls haha
echo "command return status is \$?=$?"
4.脚本变量特殊用法

双引号" 包含的变量会被解释
单引号’ 包含的变量会当做字符串
反引号` 包含的内容当做命令的执行结果返回
转义字符\ 输出特殊字符,echo命令需加-e转义
(命令序列) 由子shell来完成不影响当前shell的变量
{命令序列} 在当前shell执行会影响当前shell变量
e.x:

#!/bin/bash
city=beijing

echo "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/bash
FILE=test.sh
echo "文件名是:$FILE"
test -e $FILE
echo "当前文件是否存在:$?"
test -f $FILE
echo "当前文件是是普通文件:$?"
[ -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/bash
s1="hello"
s2="hello"
s3="Hello"
test $s1 = $s2
echo "s1==s2=>$?"
test $s1 = $s3
echo "s1==s3=>$?"
test $s1 != $s3
echo "s1!=s3=>$?"
test -z $s1
echo "s1 length is zero:$?"
test -n $s3
echo "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/bash
echo "please input num1 and num2:"
read NUM1 NUM2
test $NUM1 -eq $NUM2
echo "num1==num2=>$?"
test $NUM1 -ne $NUM2
echo "num!=num2=>$?"
test $NUM1 -gt $NUM2
echo "num1>num2=>$?"
test $NUM1 -ge $NUM2
echo "num1>=num2=>$?"
test $NUM1 -lt $NUM2
echo "num1<num2=>$?"
test $NUM1 -le $NUM2
echo "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/bash
num=100
#命令控制方式写法
test $num -gt 0 && test $num -le 200
echo "num>0 && num<=200 =>$?"
#多重判断写法
test $num -gt 0 -a $num -le 200
echo "num>0 && num<=200 =>$?"
file="test.sh"
test -e $file -a -x $file
echo "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
  命令1
else
  命令2
fi
多重if-else语句
if 判断条件1 ; then
  命令1
elif 判断条件2 ; then
  命令2
elif 判断条件3 ; then
  命令3
...
else
    命令n
fi
case语句
case 变量或表达式 in
    变量或表达式1)
        命令1
        ;;
    变量或表达式2)
        命令2
        ;;
    ...
    *)
       默认命令
esac

e.x:

#!/bin/bash
read -p "输入月份(1-12的数字):" month
case $month in
1 | 3 | 5 | 7 | 8 | 10 | 12)
    echo "大月"
    ;;
2 | 4 | 6 | 9 | 11)
    echo "小月"
    ;;
*)
    echo "输入的月份无效!"
esac
10.for循环语句
形式一
for((exp1; exp2; exp3))
do
    statements
done

说明:
exp1、exp2、exp3 是三个表达式,其中 exp2 是判断条件,for 循环根据 exp2 的结果来决定是否继续下一次循环;
statements 是循环体语句,可以有一条,也可以有多条;
do 和 done 是 Shell 中的关键字。

#!/bin/bash
declare -i sum
for ((i=1; i<=100; i++))
do
    sum+=i
done
echo "The sum is: $sum"
形式二
for variable in value_list
do
    statements
done

variable 表示变量,value_list 表示取值列表,in 是 Shell 中的关键字。

#!/bin/bash
declare -i sum
for n in {1..100}
do
   #双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令
   ((sum += n))
done
echo "The sum is: $sum"
11.while与until语句
while循环

while 循环是 Shell 脚本中最简单的一种循环,当条件满足时,while 重复地执行一组语句,当条件不满足时,就退出 while 循环。

while condition
do
    statements
done
#!/bin/bash
declare -i sum
declare -i n
while [ "$n" != "101" ]
  do
     sum+=n
     n+=1
  done
echo "the result is :$sum"
until循环

unti 循环和 while 循环恰好相反,当判断条件不成立时才进行循环,一旦判断条件成立,就终止循环。

until condition
do
    statements
done
#!/bin/bash
declare -i sum
declare -i n
until ((n > 100))
do
    ((sum += n))
    ((n++))
done
echo "the result is :$sum"
12.break与continue
break

使用 while、until、for 循环时,如果想提前结束循环(在不满足结束条件的情况下结束循环),可以使用 break 或者 continue 关键字。

break n

n 表示跳出循环的层数,如果省略 n,则表示跳出当前的整个循环。
e.x:

#!/bin/bash
declare -i sum
for ((i=1; i<=100; i++))
  do
    sum+=i
    if [ $i -eq 10 ];then
      break;
    fi
  done
echo "The sum is: $sum"
continue
continue n

n 表示循环的层数:
如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。
如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。这么说可能有点难以理解,稍后我们通过代码来演示。
e.x:

#!/bin/bash
declare -i sum
for ((i=1; i<=100; i++))
  do
    if [ $i -eq 10 ];then
      continue;
    fi
    sum+=i
  done
echo "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/bash
function add(){
   a=$1
   b=$2
   sum=`expr $a + $b`
   echo "sum=$sum"
}

#函数调用
add 12 7
函数返回值

通常使用$?获取函数的返回值。
e.x:

#!/bin/bash
function add(){
   a=$1
   b=$2
   sum=`expr $a + $b`
   return $sum
}
add 12 7
echo "sum=$?"

但是这种方式获取的返回值不能超过255,否则会出错。
e.x:

#!/bin/bash
function add(){
   a=$1
   b=$2
   sum=`expr $a + $b`
   return $sum
}
add 102 700
echo "sum=$?"

在shell中除了()中定义的变量,只要不做任何修饰,都可以理解为是一个全局变量,因此在函数体外可以直接获取返回值。
e.x:

#!/bin/bash
function add(){
   a=$1
   b=$2
   sum=`expr $a + $b`
   return $sum
}
add 102 700
echo "sum=$sum"
14.其它
追加指定内容至某文件
sed -i '1i 添加的内容' file    #这是在第一行前  添加字符串
sed -i '$i 添加的内容' file    #这是在倒数第二行添加字符串
sed -i '$a 添加的内容' file    #这是在最后一行添加一行字符串
echo '内容' > file    #覆盖之前内容,文件只显示添加后的内容
echo '内容' >> file  #追加内容至最后一行行后
字符串截取
假设有变量: var=http://www.aaa.com/123.htm
1. # 号截取,删除左边字符,保留右边字符。
代码如下:
echo ${var#*//}
其中 var 是变量名,# 号是运算符,*// 表示从左边开始删除第一个 // 号及左边的所有字符
即删除 http://
结果是 :www.aaa.com/123.htm
2. ## 号截取,删除左边字符,保留右边字符。
代码如下:
echo ${var##*/}
##*/ 表示从左边开始删除最后(最右边)一个 / 号及左边的所有字符
即删除 http://www.aaa.com/
结果是 123.htm
3. %号截取,删除右边字符,保留左边字符
代码如下:
echo ${var%/*}
%/* 表示从右边开始,删除第一个 / 号及右边的字符
结果是:http://www.aaa.com
4. %% 号截取,删除右边字符,保留左边字符
代码如下:
echo ${var%%/*}
%%/* 表示从右边开始,删除最后(最左边)一个 / 号及右边的字符
结果是:http:
5. 从左边第几个字符开始,及字符的个数
代码如下:
echo ${var:0:5}
其中的 0 表示左边第一个字符开始,5 表示字符的总个数。
结果是:http:
6. 从左边第几个字符开始,一直到结束
代码如下:
echo ${var:7}
其中的 7 表示左边第8个字符开始,一直到结束。
结果是 :www.aaa.com/123.htm
7. 从右边第几个字符开始,及字符的个数
代码如下:
echo ${var:0-7:3}
其中的 0-7 表示右边算起第七个字符开始,3 表示字符的个数。
结果是:123
8. 从右边第几个字符开始,一直到结束
代码如下:
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

以上分享如有错误或疑问,请评论留言,大家一起探讨。
原创不易,不要忘记一键三连哦!!!

  • 13
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值