变量
bash shell 使用一种称为环境变量的特性来存储关于shell会话和工作环境的信息环境变量的名字由此而来。该特性还允许你将数据存储在内存中以便于在shell中运行的程序或脚本访问它们。这是一种便捷的、用于存储持久性数据的方式这些数据可以标识用户账户、系统、shell或任何需要存储的内容的特性。
bash shell中共有两种类型的环境变量
本地变量: 只在创建它们的shell中可见
# test=”testing” #设置本地环境变量
# echo $test
全局变量: 在shell会话和该shell中产生的任何子进程中都可见。
# printenv # 查看所有已设置的全局环境变量
# echo $VAR_NAME 查看某个环境变量的值
全局环境变量的设置
# test=”this is a test variable” # 先创建一个本地环境变量
# export test # 然后将它导出到全局环境变量
移除环境变量
# unset VAR_NAME
# unset test
在子进程中移除全局环境变量时只对子进程有效在父进程中全局环境变量仍然存在
特殊变量
$$: Shell本身的PIDProcessID
$!: Shell最后运行的后台Process的PID
$?: 最后运行的命令的结束代码返回值
$-: 使用Set命令设定的Flag一览
$*: 所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$@: 所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$#: 添加到Shell的参数个数
$0: Shell本身的文件名
$1$n: 添加到Shell的各参数值。$1是第1参数、$2是第2参数…
bash编程条件判断
脚本开头第一行#! shabang指定脚本使用的解释器
#!/bin/bash
#!/bin/sh
#/usr/bin/python
#!/bin/sed
#!/bin/awk
其他行#号开头或者#号之后的内容表示注释在””,’’和转义符\结合使用的#号表示”#”字符本身
if语句的使用格式
if CMD then CMD fi 或者 if CMD; then CMD fi
#!/bin/bash if [ $UID -eq 0 ]; then cat /etc/shadow fi
上面的例子如果是root用户则查看/etc/shadow 文件内容。
if还可以这样用
if CMD; then CMD1 else CMD2 fi
表示如果if后跟的条件为真则执行CMD1否则执行CMD2
#!/bin/bash if [ $UID -eq 0 ]; then cat /etc/shadow else echo "need root." exit 1 fi
如果为root用户则查看/etc/shadow否则提示退出
if语句还可以嵌套
if TEST1; then if TEST2; then CMD1 fi else CMD2 fi
也可以使用多分支if语句
if TEST1;then CMD elif TEST2; then CMD2 elif TEST3; then CMD3 … elif TESTn; then CMDn fi
写一个脚本判断输入的参数是文件还是目录给出相应的提示
#!/bin/bash if [ $# -ne 1 ]; then echo "Usage: `basename $0` [FILE|DIRECTORY]" exit 5 fi if [ -f $1 ];then echo "$1 is a file" elif [ -d $1 ]; then echo "$1 is a directory." else echo "Usage: `basename $0` [FILE|DIRECTORY]" exit 5 fi
bash编程循环语句
for循环语句
for var in list do commands done
list中放着变量值的列表变量var遍历列表中的每一个值去一次值执行一次循环直到遍历结束为止。通常用于循环次数已知的情况。
for还有另外一种使用格式
for ((初始条件;测试条件;修改表达式)); do
循环体
done
求100以内的正整数之和
#!/bin/bash declare -i sum=0 i {1..100} let sum+=$i done echo "$sum" #!/bin/bash declare -i sum=0 ((i=1;i <= 100; i++)); let sum+=$i done echo "$sum"
两种格式的for循环都可以
while循环
使用格式
while TESTdo commands done
当测试条件为真进入循环条件为假则退出循环
until循环
使用格式
until TEST; do commands done
当条件为假时进入循环为真时退出循环
用while循环和until循环求100内的正整数之和
#!/bin/bash declare -i sum=0 declare -i var=1 [ $var -le 100 ]; let sum+=$var let var++ done echo "$sum" #!/bin/bash declare -i var=1 declare -i sum=0 until [ $var -gt 100 ];do let sum+=$var let var++ done echo "$sum"
case语句
有多个测试条件时用case语句比if语句结构更清晰
case $VAR in PATTERN1) commands ;; PATTERN2) commands ;; … PATTERNn) commands ;; *) commands ;; esac
上面是case语句的使用格式PATTERN使用文件名通配只是使用|表示或者。a|b
bash函数
定义函数
function name { commands } name() { commands }
函数调用函数名出现的地方会被自动替换为函数。
返回值
函数的执行结果返回值代码的输出
函数中的打印语句echo, print
函数中调用的系统命令执行后返回的结果
执行状态返回值
函数体中最后一次执行的命令状态结果
自定函数执行状态的返回值return #
函数应用举例:服务脚本
#!/bin/bash # # chkconfig: 2345 67 34 # srvName=$(basename $0) lockFile=/var/lock/subsys/$srvName start() { if [ -f $lockFile ];then echo "$srvName is already running." return 1 else touch $lockFile [ $? -eq 0 ] && echo "Starting $srvName OK." return 0 fi } stop() { if [ -f $lockFile ];then rm -f $lockFile &> /dev/null [ $? -eq 0 ] && echo "Stop $srvName OK" && return 0 else echo "$srvName is not started." return 1 fi } status() { if [ -f $lockFile ]; then echo "$srvName is running." else echo "$srvName is stopped." fi return 0 } usage() { echo "Usage: $srvName {start|stop|restart|status}" return 0 } case $1 in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) usage exit 1 ;; esac
循环控制
break命令: 命令式在处理过程中跳出循环的一种简单方.可以使用break命令退出任何类型的循环,包括while循环和until循环.
1、跳出单循环
shell执行break命令式它试图跳出当前正在处理的循环
#!/bin/bash i {1..5}; [ $i -eq 3 ];then break fi echo "$i" done echo "the loop is completed" [root@bogon ~]# ./3test.sh 1 2 the loop is completed
当i去3时执行break跳出了for循环。
2、跳出内循环
使用多循环时 break命令自动终止所在的最里面的内部循环
3、跳出外循环
可能有时处于内循环但需要停止外循环。break命令包括单独的命令行参数值 break n
n表明要跳出的循环级别。默认情况下n是1代表跳出当前循环。如果将n设置为2break命令将停止外循环的下一级循环
#!/bin/bash i {1,2,3}; echo "outer loop $i" ((j=1; j < 100; j++)); [ $j -gt 4 ]; then break 2 fi echo "inner loop $j" done done [root@bogon ~]# ./4test.sh outer loop 1 inner loop 1 inner loop 2 inner loop 3 inner loop 4
continue命令是一种提前停止循环内命令,而不完全终止循环的方法。这就允许在循环中设置shell不执行命令的条件。
#!/bin/bash for ((i=1;i < 15; i++));do if [ $i -gt 5 ] && [ $i -lt 10 ]; then continue fi echo "$i" done [root@bogon ~]# ./5test.sh 1 2 3 4 5 10 11 12 13 14
信号捕获:
Linux使用信号与系统上运行的进程进行通信。常用的信号
1 SIGHUP 挂起进程
2 SIGINT 中断进程
3 SIGQUIT 停止进程
9SIGKILL 无条件终止进程
15 SIGTERM 如果可能的话终止进程
17 SIGSTOP 无条件停止但不终止它
18 SIGTSTP 停止或暂停进程但不终止它
19 SIGCONT 重新启动停止的进程
默认情况下bash shell会忽略它接受的任何SIGQUIT3和SIGTERM5信号以防止交互的shell意外终止
捕获信号
trap: 可以在信号出现时捕获信号和执行其他命令
trap CMDs SIGNALs
#!/bin/bash trap "echo testing" SIGINT SIGTERM echo "This is a test script." declare -i $var=1 [ $var -le 10 ]; echo "Loop $var" sleep 5 let var++ done echo �Ce "\033[31mEND\033[0m"
捕获脚本退出
除了在shell脚本中捕获信号之外还可以在shell脚本退出时捕获它们。这是一种在shell完成作业时执行命令的便捷方式。
#!/bin/bash trap "echo BYE" EXIT declare -i var=1 [ $var -le 5 ] echo "Loop #$var" sleep 2 let var++ done [root@bogon ~]# ./2test.sh Loop #1 Loop #2 Loop #3 Loop #4 Loop #5 BYE
移除捕获
要移除捕获使用破折号作为命令和想要恢复正常行为的信号列表
trap �C SIGNAL
#!/bin/bash trap "echo BYE" EXIT declare -i var=1 while [ $var -le 5 ] do echo "Loop #$var" sleep 2 let var++ done trap - EXIT echo "removed the trip" [root@bogon ~]# ./2test.sh Loop #1 Loop #2 Loop #3 Loop #4 Loop #5 removed the trip
如果在移除捕获之前接收到信号,仍然将会根据trap命令处理该信号
[root@bogon ~]# ./2test.sh Loop #1 ^CBYE
数组
环境变量的一个非常好的特性就是能够当作数组使用。数组是能保存多个值的变量。数组中的值既可以分别引用也可以作为整体引用。
数组名和索引来表示数组中的变量
索引的表达方式
数字索引 array[index]
a[0], a[1]... a[n]
bash 4.0之后开始支持关联数组可以指定一个字串当索引
a[car], a[apple]
declare -a 定义数组
declare -A 定义关联数组
数组赋值
要为某个环境变量设置多个值只需将它们列出在圆括号中各值以空格分隔
# test=(1 two 3 4)
一次对一个数组元素赋值
# a[0]=$RANDOM
按索引赋值
# a=([0]=green [3]=orange [2]=yellow)
数组的访问
用索引访问数组中的元素 ARRAY[index]
整个数组 ${$array[@]}或者${$array[*]}
数组的长度
${#array[*]}或者${#array[@]}
从数组中挑选某元素
${ARRY[@]:offset:number}
切片机制
offset: 是指偏移量
number取出元素的个数
${array[@]:3:4} 取出从第4个元素开始的4个元素array[3] array[4] array[5] array[6]
${ARRAY[@]:offset}取出偏移量后的所有元素
${ARRAY[@]}: 取出所有元素
打印九九乘法表
#!/bin/bash for i in {1..9};do for ((j=1;j<=$i;j++));do let val=$i*$j valu[$j]="${i}x${j}=$val" done echo ${valu[@]} done [root@bogon scripts]# ./chengfabiao.sh 1x1=1 2x1=2 2x2=4 3x1=3 3x2=6 3x3=9 4x1=4 4x2=8 4x3=12 4x4=16 5x1=5 5x2=10 5x3=15 5x4=20 5x5=25 6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36 7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49 8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64 9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81