shell脚本

单引号和反斜杠都是不允许变量替换,按字面意思处理;
双引号允许使用$符对变量进行替换
当一个命令被包含在一堆括号里并在括号前加上$符号,或者被包含在反引号`中时,shell把他替换为这个命令的输出结果。这个过程被称为命令替换。
当一个命令被包含在一对括号里并在括号前加上$符号,如$(command),或者被包含在反引号“`” (如`command`)中的时候,shell把它替换为这个命令的输出结果。这个过程被称为命令替换。
反引号位 (`) 位于键盘的Tab键的上方、1键的左方。注意与单引号(')位于Enter键的左方的区别。

  • 例2.3 :
[root@localhost root]#pwd
/root/d1
[root@localhost root]# cmd1=pwd
[root@localhost root]# echo “The value of command is: $cmd1.”
The value of command is: pwd
[root@localhost root]# cmd1=$(pwd)
[root@localhost root]# echo “The value of command is: $cmd1.”
The value of comomand is: /root/d1
Read
1、输入命令:
  • 可以使用read命令来将用户的输入赋值给一个shell变量中。
  • 语法:read [options] variable-list
  • 常用选项:
-a name 把词读入到name数组中去。
-e 把一整行读入到第一个变量中,其余的变量均为null。
-n 在输出echo后的字符串后,光标仍然停留在同一行。
-p prompt 如果是从终端读入数据则显示prompt字符串。
  • 读入的一行输入由许多词组成,他们是用空格(或者制表符,或shell环境变量IFS的值)分隔开的。
  • 如果这些词的数量比列出的变量的数量多,则把余下的所有词赋值给最后一个变量。如果列出的变量的数量多于输入的词的数量,这多余的变量的值被设置为null。
  • 通常情况下,在用户按下回车键时,read命令结束。
实例:
  • (1)-n
  • #!/bin/bash
  • echo -n "Enter your name:"   //参数-n的作用是不换行,echo默认是换行
  • read  name                   //从键盘输入
  • echo "hello $name,welcome to my program"     //显示信息
  • exit 0                       //退出shell程序。
  • (2)由于read命令提供了-p参数,允许在read命令行中直接指定一个提示。
  • 所以上面的脚本可以简写成下面的脚本::
  • #!/bin/bash
  • read -p "Enter your name:" name
  • echo "hello $name, welcome to my program"
  • exit 0
2、计时输入.
  • 使用read命令存在着潜在危险。脚本很可能会停下来一直等待用户的输入。如果无论是否输入数据脚本都必须继续执行,那么可以使用-t选项指定一个计时器。-t选项指定read命令等待输入的秒数。当计时满时,read命令返回一个非零退出状态;
  • #!/bin/bash
  • if read -t 5 -p "please enter your name:" name
  • then 
  •     echo "hello $name ,welcome to my script"
  • else
  •     echo "sorry,too slow"
  • fi
  • exit 0
除了输入时间计时,还可以设置read命令计数输入的字符。当输入的字符数目达到预定数目时,自动退出,并将输入的数据赋值给变量。
#!/bin/bash
read –n 1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y)
      echo "fine ,continue";;
N | n)
      echo "ok,good bye";;
*)
     echo "error choice";;
esac
exit 0

默读(不显示在屏幕上)
-s0
最后,还可以使用read命令读取Linux系统上的文件。
  • 每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。
  • 读取文件的关键是如何将文本中的数据传送给read命令。
  • 最常用的方法是对文件使用cat命令并通过管道将结果直接传送给包含read命令的 while命令
  • 例子::
  • #!/bin/bash
  • count=1    //赋值语句,不加空格
  • cat test | while read line        //cat 命令的输出作为read命令的输入,read读到的值放在line中
  • do
  •    echo "Line $count:$line"
  •    count=$[ $count + 1 ]          //注意中括号中的空格。
  • done
  • echo "finish"
  • exit 0
echo
-n不要在最后自动换行
-e若字符串中出现以下字符,则特别加以处理,而不会把它当成一般文字输出:
  •   \a 发出警告声;
  •    \b 删除前一个字符;
  •    \c 最后不加上换行符号;
  •    \f 换行但光标仍旧停留在原来的位置;
  •    \n 换行且光标移至行首;
  •    \r 光标移至行首,但不换行;
  •    \t 插入tab;
  •    \v 与\f相同;
  •    \\ 插入\字符;
  •    \nnn 插入nnn(八进制)所代表的ASCII字符;
例:
  • $ echo -e "a\tb\tc\nd\te\tf"
  • a       b       c
  • d       e       f
  •  上例运用 \t 来区隔 abc 还有 def ,以及用 \n 将 def 换至下一行。
  • 例四:
  • $ echo -ne "a\tb\tc\nd\te\bf\a"
  • a       b       c
  • d       f  
  • 因为 e 字母后面是删除键(\b),因此输入结果就没有e了。
  • 在结束时听到一声铃响,那是\a的杰作!
  • 由于同时使用了 -n 选项,因此 shell prompt 紧接在第二行之后。
若不用 -n 的话,那在\a后再加个\c,也是同样的效果
  1. Shift命令
  • 当有脚本程序的参数多于9个时,用shift命令来使用多于9个的参数。
  • 命令句法:shift [N]
  • 功能:把命令行参数向左移动N个位置
3. set命令
命令语法:set [options] argnument-list
功能:设置标志、选项和位置参数;使用在argument-list中的值来设置位置参数。
常用选项:
      --      不把以’-’开头的词作为参数选项
控制结构语句:
二路跳转(if语句)
p Linux里的if的结束标志是将if反过来写成fi;而elif其实是else if的缩写
多路跳转(case和if语句)
循环结构(for、while和until语句)
if-then-elif-else-fi语句
1、字符串比较
测试字符是否相等、长度是否为零,字符串是否为NULL
-n:比较字符串长度是否大于零;-z比较字符串的穿度是否等于零。
q 例:从键盘读入两个字符串,判断这两个字符串是否相等,如相等输出。
(1)用vi编辑程序
[root@localhost bin]#vi test4
#!/bin/bash
read  ar1
read  ar2
[ "$ar1"  =  "$ar2" ]
echo $?   #保存前一个命令的返回码
(2)设置权限:
  [root@localhost bin]#chmod +x test4
(3)执行:
[root@localhost root]# ./test4
aaa
bbb
1
注意: “[”后面和“]”前面及等号“=”的前后都应有一空格;
q 例: 比较字符串长度是否大于零。
(1)用vi编辑程序
[root@localhost bin]#vi test5
#!/bin/bash
read  ar
 [  -n  "$ar"  ]
echo $?   #保存前一个命令的返回码
(2)设置权限:
[root@localhost bin]#chmod +x test5
(3)执行:
[root@localhost root]# ./test5
0
注意: 运行结果1表示ar的长度小于等于零,0表示ar的长度大于零。
2、算术比较
-eq:相等
-ge:大于等于
-le:小于等于
-ne:不等于
-gt:大于
-lt:小于
q 例: 比较两个数字是否相等。
(1)用vi编辑程序
[root@localhost bin]#vi test6
#!/bin/bash
read x y
if  test  $x  -eq  $y
   then
      echo “$x= =$y”
   else
      echo “$x!=$y”
fi
(2)设置权限:
  [root@localhost bin]#chmod +x test6
(3)执行:
[root@localhost bin]# ./test6
50  100
50!=100
[root@localhost bin]# ./test6
150  150
150= =150
3.逻辑操作
!:反 与一个逻辑值相反的逻辑值
-a:与(and)两个逻辑值为“是”返回值才为“是”,反之为“否”
-o:或(or) 两个逻辑值有一个为“是”,返回值就为“是”
q 例: 一个变量赋予一定的值,另一个为空,求两者的与、或。
(1)用vi编辑程序
[root@localhost bin]#vi test7
#!/bin/bash
part1 ="1111"
part2 =""    #part2为空
 [ "$part1"  -a  "$part2" ]
echo $?   #保存前一个命令的返回码
 [ "$part1"  -o  "$part2" ]
echo $? 
(2)设置权限:
  [root@localhost bin]#chmod +x test7
(3)执行:
[root@localhost bin]# ./test7
1
0
4、文件条件测试
文件测试表达式通常是为了测试文件的信息,一般由脚本来决定文件是否应该备份、复制或删除。
常用操作符

q 例:判断zb目录是否存在/root下。
(1)用vi编辑程序
[root@localhost bin]#vi test8
#!/bin/bash
[ -d ./root/zb ]
echo $?   #保存前一个命令的返回码
(2)设置权限:
[root@localhost bin]#chmod +x test8
(3)执行:
[root@localhost bint]# ./test8
1
(4) 在/root添加zb目录
  [root@localhost bin]#mkdir zb
(5)执行:
[root@localhost bin]# ./test8
0
注意: 运行结果1表示判断的目录不存在,0表示判断的目录存在。
q 例:输入一个字符串,如果是目录,则显示目录下的信息,如为文件显示文件的内容。
[root@localhost bin]#vi test9
#!/bin/bash
echo “Please enter the directory name or file name”
read  DORF
if [ -d $DORF ]
then
  ls $DORF
elif [ -f $DORF]
then
cat $DORF
else
  echo “input error!”
fi
1、for循环
语法:
for 变量in列表
do
操作
done
在列表中的词逐一赋值给变量,然后就执行操作中的命令。
列表中的词有多少个,在循环中的命令就可以执行相应的次数。
q 例: 在列表中的值:a,b,c,e,i,2,4,6,8用循环的方式把字符与数字分成两行输出。
(1)用gedit编辑脚本程序test4
[root@localhost root]# gedit test9
#!/bin/sh
for i in a,b,c,e,i   2,4,6,8
 do
  echo $i
 done
(2)设置权限:
[root@localhost bin]#chmod +x test9
(3)执行:
[root@localhost bin]# ./test9
a,b,c,e,i
2,4,6,8
注意:在循环列表中的空格可表示换行。
q 例:求从1到100的和。
(1)用gedit编辑脚本程序test11
[root@localhost bin]# gedit test11
#!/bin/sh
total=0
for ((j=1;j<=100;j++));
  do
     total=`expr $total + $j`
  done
echo "The result is $total"
(2)设置权限:
[root@localhost bin]#chmod +x test11
(3)执行:
[root@localhost bin]# ./test11
The result is 5050
注意:for语句中的双括号不能省,最后的分号可有可无,表达式total=`expr $total + $j`的加号两边的空格不能省,否则会成为字符串的连接。
while语句
while表达式
do
操作
done
只要while表达式为真,do和done之间的操作就一直会进行。
q 例:用while循环求1到100的和。
  (1)用gedit编辑脚本程序test12
[root@localhost bin]#gedit test12
    total=0
    num=0
    while((num<=100));
    do
    total=`expr $total + $num`
   ((num+=1))
   done
   echo "The result is $total"
(2)设置权限:
  [root@localhost bin]#chmod +x test12
(3)执行:
[root@localhost bin]# ./test12
The result is 5050
until语句
until表达式
do
操作
done
重复do和done之间的操作直到表达式成立为止。
q 例:用until循环求1到100的和。
(1)用gedit编辑脚本程序test13
[root@localhost bin]#gedit test13
total=0
num=0
until [ $num -gt 100 ]
do
 total=`expr $total + $num` 
 num=`expr $num + 1`
done
echo "The result is $total"
(2)设置权限:
  [root@localhost bin]#chmod +x test13
(3)执行:
[root@localhost bin]#./test13
The result is 5050
case语句
case字符串in
值1|值2)操作
;;
值3|值4)操作
;;
esac
case的作用就是当字符串与某个值相同时就执行哪个值后面的操作。
如果同一个操作对于多个值,则使用|将各个值分开。
在case的每一个操作的最后面都有两个;;分号是必须的。
q 例:Linux是一个多用户操作系统,编写一程序根据不同的用户登录输出不同的反馈结果。
      用vi编辑脚本程序test15
[root@localhost bin]#vi test15
#!/bin/sh
case $USER in
 beichen)
   echo "You are beichen!";;
 liangnian)
   echo "You are liangnian"; //注意这里只有一个分号
   echo "Welcome!";;  //这里才是两个分号
 root)
   echo "You are root! "; echo "Welcome!";;
    //将两命令写在一行,用一个分号作为分隔符
 *)
   echo "Who are you?$USER?";;
esac
break和continue语句
break命令使得程序跳出for、while、until循环,执行done后面的语句,终止循环。
continue命令使得程序跳到done,这使得循环条件被再次求值,从而开始新的一次循环,循环变量取循环列表中的下一个值。
无论哪种情况,循环体中在这两条命令后的语句都没有执行。
break命令和continue命令常作为条件语句的一部分来使用。
exit语句
exit命令使脚本程序结束运行,退出码为n。
语句语法:exit n
在任何一个交互式shell的命令提示符中使用这个命令,它都会让你退出系统。
如果在退出时不指定一个退出状态,那么该脚本中最后一条被执行命令的状态将被用作返回值。
在shell脚本编程中,退出码0表示成功,退出码1~125是脚本程序使用的错误代码。其余数字具有保留含义
printf语句
x、Open规范建议应该用它来代替echo命令以产生格式化的输出
语句语法:
print “format string”parameter1 parameter2 。。。
格式字符串与c/c++中使用的非常相似,但是有一些自己的限制。主要是不支持浮点数。
格式字符串由各种可打印字符、转义序列和字符转换限定符组成
格式字符串中除了%和\之外的所有字符都将按原样输出
let命令
let可以用来计算算术表达式的值。如果表达式中有空格或者特殊字符,则应将表达式括在双引号中。
语法命令:let express-list
如果最后的表达式取值为0,let命令返回1;否则返回0.
例:[root@localhost root]# let “x=6” “y = 9”“z = 16”
[root@localhost root]# let t=x+y #加号前后无空格
[root@localhost root]# echo “t= $t”
t= 15
[root@localhost root]# let A=2**x B=y*z
[root@localhost root]# echo “A=$A    B=$B”
A=64     B=144
命令语法:$((expression))
shell计算expression并用其计算结果代替$((expression))。这个语法类似于命令替换所用的语法“$(...)”,并将执行相同的功能。可将$((expression))作为参数传递给命令或者放置在命令行上任何数字位置上。
不需要在expression中的变量名称前加上$符号。
例:age_check程序
#!/bin/bash
echo -n "How old are you? "
read age
echo "Wow, in $((100-age)) years, you'll be 100! "
[root@localhost root]# age_check
How old are you? 20
Wow, in 80 years, you'll be 100!
expr命令
expr命令将它的参数当作一个表达式来求值。
命令语法:expr args
功能:计算表达式的参数‘args’的值,并返回它的值到标准输出。
常见用法:x=`expr $x + 1`
反引号(``)字符使x取值为命令expr $x + 1的执行结果。也可以用语法$()替换反引号``。
例: expr命令的应用
[root@localhost root]# a1=5
[root@localhost root]# a1=$( expr $a1 + 1 )
[root@localhost root]# echo $ar1
6
字符串操作
(1)获取子字符串的位置
如 str=“2013134.key”获取“key”的位置
方法1:$expr match $str “.*key” (返回11)
方法2: $expr index $str “key”  (返回9)
还有其他方法吗?
如果只是判断“key”是否在str中出现,可以这样写:
if [[  $str == *key* ]]
then
   echo “yes,key is in str”
f i
(2)根据返回值,对字符串str进行截取
如 str=“2013134.key”已经获取“.”的位置是第8个,现在要截取str的前7个字符,作为子字符串
方法1:echo  ${str:0:7}  //从第0个字符开始截取,截取7个字符
方法2:$expr substr "$variable" startposition length
$expr substr $str 1 7
数组
bash支持一维数组变量。
1. 数组的声明
可以使用declare、local、readonly等各种语句声明数组变量,也可以直接赋值的方法声明一个数组。
常用格式:name=(value1 ... valueN)
l value1形如“[[subscript]=]string”。
l 下标是可选的,若给出,则给数组中相应的位置赋值;否则将给数组中上次赋值位置的下一个位置赋值
例:
[root@localhost root]# ns=(max san [6]=zhang [25]=wang)
[root@localhost root]# echo ${ns[0]}
max
[root@localhost root]# echo ${ns[6]}
zhang
2. 数组元素的引用
可以用${name[subscript]}引用数组中的元素。这种方式叫数组索引。
下标[@]与[*]的作用都是得到整个数组元素,但它们加上双引号使用时是不同的。
“${name[@]}”含义将原数组的内容复制到一个新数组中,生成的新数组和原来一样;
“${name[*]}”把原数组中的所有元素当成一个元素复制到新数组中,生成新的数组只有一个元素。
例:
[root@localhost root]# a=(“${ns[@]}”)
[root@localhost root]# echo ${a[0]}
max
[root@localhost root]# b=(“${ns[*]}”)
[root@localhost root]# echo ${b[0]}
max san zhang wang
注意:给数组赋值时,等号右边要使用圆括号。
例2.17 demo_num_array程序
# 将数字的总和放在数值变量sum中,从0开始。读下一个数组的值并加到sum。
# 当读完所有的元素,停止并显示结果。
#!/bin/bash
# 将斐波纳契数列中的数初始化到Fibonacci 数组中
declare -a Fibonacci=( 0 1 1 2 3 5 8 13 21 34 )
size=${#Fibonacci[*]}  # Fibonacci数组的大小作为字符串
index=1  # 数组索引初始化指向第二个元素
sum=0  # sum 初始化为0
next=0  # 用来存储下一个数组元素
while [ $index -lt $size ]
do
next=$(( ${Fibonacci[$index]} ))  #将下一个值存为整数  sum=$((sum + next))  sum=$((sum+next))  # 更新sum变量
  index=$((index + 1))  # 将数组索引加1
done
#显示最后的和
echo "The sum of the given ${#Fibonacci[*]} numbers is $((sum))."
exit 0
函数
shell程序也支持函数。函数能完成一个特定的功能,可以重复调用这个函数。
函数格式如下:
函数名(   )
{
   函数体
}
函数调用方式为:
函数名  参数列表
可以使用local关键字在shell函数中声明局部变量,局部变量将局限在函数的作用范围内。
例2.19 demo_fun2脚本
#!/bin/bash
sample_txt="global varible"
foo() {
local sample_txt="local varible"
echo "Function foo is executing"
echo $sample_txt
}
echo "script starting"
foo
echo $sample_txt
exit 0
运行结果如下:
[root@localhost root]# ./demo_fun2
script starting
Function foo is executing
local varible
global varible
例:编写一函数add求两个数的和,这两个数用位置参数传入,最后输出结果。
(1)编辑代码
[root@localhost bin]#vi test16
#!/bin/sh
add( )
{
 a=$1
 b=$2
 z=`expr $a + $b`
 echo "The sum is $z"
}
add  $1  $2 
(2)修改权限
  [root@localhost bin]#chmod +x test16
(3)程序运行结果
[root@localhost bin]# ./test16  10  20
The sum is 30
注意:函数定义完成后必须同时写出函数的调用,然后对此文件进行权限设定,再执行此文件。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值