SHELL编程语法
变量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` "
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` "
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/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"
# ./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
# ./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
# ./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 –e "\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
# ./2test.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
BYE
移除捕获
要移除捕获使用破折号作为命令和想要恢复正常行为的信号列表
trap – 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"
# ./2test.sh
Loop #1
Loop #2
Loop #3
Loop #4
Loop #5
removed the trip
如果在移除捕获之前接收到信号,仍然将会根据trap命令处理该信号
# ./2test.sh
Loop #1
^CBYE
数组
环境变量的一个非常好的特性就是能够当作数组使用。数组是能保存多个值的变量。数组中的值既可以分别引用也可以作为整体引用。
数组名和索引来表示数组中的变量
索引的表达方式
数字索引 array
a, a... a
bash 4.0之后开始支持关联数组可以指定一个字串当索引
a, a
declare -a 定义数组
declare -A 定义关联数组
数组赋值
要为某个环境变量设置多个值只需将它们列出在圆括号中各值以空格分隔
# test=(1 two 3 4) 一次对一个数组元素赋值
# a=$RANDOM 按索引赋值
# a=(=green =orange =yellow) 数组的访问
用索引访问数组中的元素 ARRAY
整个数组 ${$array[@]}或者${$array
[*]}
数组的长度
${#array
[*]}或者${#array[@]}
从数组中挑选某元素
${ARRY[@]:offset:number}
切片机制
offset: 是指偏移量
number取出元素的个数
${array[@]:3:4} 取出从第4个元素开始的4个元素array array array array
${ARRAY[@]:offset}取出偏移量后的所有元素
${ARRAY[@]}: 取出所有元素
打印九九乘法表
#!/bin/bash
for i in {1..9};do
for ((j=1;j
页:
[1]