变量
特殊变量
echo "id:$$" #当前进程id
echo "script name $0" #当前脚本名
echo "parm length $#" #参数数量
echo "parm[1]=:$1" #第1个参数
echo "all parm $*" #所有参数
echo "all parms $@" #所有参数
echo $? #上一个命令的退出状态
echo $*
echo $@
变量
#变量名和等号间不能有空格
valX=1
echo "$valX"
#变量重新赋值
valX=2
echo $valX
#帮助识别边界,推荐给所有变量添加花括号
valX="3"
echo ${valX}
varR=1
#只读变量,不能再赋值
readonly varR
#删除变量,但是不能删除只读变量
unset valX
#保存命令的输出结果,适当地方输出,注意这里是反引号
DATE=`date`
echo $DATE
变量替换
num="num"
echo ${num} #变量本来的值
echo ${num:+"yes"} #如果变量已经定义,返回后面值,不修改变量
unset num
echo ${num:-"null"} #如果为空或已删除,返回后面的值,但是不改变变量
# echo ${num:?"error"} 如果为空或已删除,将后面的值作为标准错误输出,会终止程序
echo ${num:="ok"} #如果为空或已删除,返回后面的值,并修改
echo "val \n val"
#对转义字符进行替换,否则原样输出
echo -e "val \n val"
输入
#echo "hello,please input your number:"
# read parY
# echo "hello ,$parY"
shell运算符
# 原生bash 不支持简单的数学运算,但是可以通过其它命令实现,比如awk,expr
#表达式,运算符之间必须要有空格
ans=`expr 2 + 3`
echo $ans
echo `expr 2 - 3`
echo `expr 2 / 3`
echo `expr 2 \* 3`
echo `expr 2 % 3`
expr 算术运算符
运算符 | 说明 |
---|---|
+ | 加法 |
– | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余 |
= | 赋值 |
== | 相等.用于比较两个数字,相同则返回 true。 |
!= | 不相等,用于比较两个数字,不相同则返回 true。 |
关系运算
a=1
b=2
if [ $a -gt $b ]
then
echo "$a > $b "
else
echo "$a <= $b"
fi
运算符 | 说明 | |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | |
-ne | 检测两个数是否相等,不相等返回 true。 | [ |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | |
-ge | 检测左边的数是否大等于右边的,如果是,则返回 true。 | |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 |
布尔运算符
运算符 | 说明 |
---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true. |
-o | 或运算,有一个表达式为 true 则返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 |
文件检测运算符
pat=""
if [ $# -gt 0 ]
then
pat=$1
else
echo "please input file path:"
read pat
fi
if [ -e $pat ]
then
echo '$pat exists'
else
echo "$pat not exists"
exit
fi
运算符 | 说明 |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 |
-p file | 检测文件是否是具名管道,如果是,则返回 true。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 |
-r file | 检测文件是否可读,如果是,则返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 |
数组
# 定义数组
arr=(1 2 3)
array=(
"c"
"c++"
"python"
"c#"
)
#单独赋值
array[4]="java"
array[7]="shell"
# 访问元素
echo ${array[7]}
# 所有值
echo ${array[*]}
echo ${array[@]}
# 数组元素个数
length=${#array[*]}
size=${#array[@]}
echo $length ,$size
# 单个元素长度
echo ${#array[7]}
echo语句
x=1
# 显示字符串
echo "hello "
# 显示变量
echo $x
# 与其它值连接需要用括号
echo "${x}+1="
# 转义字符,换行再换行
echo "ok\n"
# 显示不换行
echo "ko\c"
# 显示重定向
# echo "world" > mFile
echo '$x\c\t\n'
# 显示命令执行结果
echo `date`
printf 语句
- 默认不换行
- printf 不加括号
- format-string 可以没有引号,但是最好加上,双引号单引号都一样
- 参数多于格式控制符时,format-string可以复用
- arguments 使用空格分隔,不用逗号
# 双引号
printf "%d %s\n" 1 "hello"
# 单引号
printf '%d %s\n' 2 "world"
# 省略引号
printf %s\n abcde
# format-string 复用
printf "%s\n" "hello" "world"
printf "%s %s %s\n" a b c d e f g
printf "Time:%s\n" `date`
if 语句
x=1
y=2
if [ $x -gt $y ]
then
printf "%d > %d \n" $x $y
else
printf "%d <= %d\n" $x $y
fi
if [ $# -eq 0 ]
then
echo "arg num = 0"
fi
if [ 2 == 1 ]
then
echo "2 = 1"
elif [ 2 -gt 1 ]
then
echo "2 > 1"
elif [ 2 -lt 1 ]
then
echo "2 < 1"
else
echo "error"
fi
if [ 2 -gt 1 ] ; then echo "2 >=1" ; else echo "2<1";fi;
if test 2 -gt 1
then echo "yes"
else
echo "no"
fi
case 语句
- 取值后面必须为关键字in
- 每个模式以右括号结束
- 匹配取值后执行命令直到遇到 ;;
- 每个模式都要有 ;;
num
echo "please input n num:"
read num
case $num in
1)
echo "select 1"
echo "good choose"
;;
2)
echo "select 2"
;;
3)
echo "select 3"
;;
*)
echo "you do not select 1-3"
;;
esac
option=${1}
case $option in
-f)
FILE=${2}
echo "file name is $FILE"
;;
-d)
DIR=${2}
echo "dir name is $DIR"
;;
*)
echo "correct useage : [-f file] | [-d dir]"
exit
;;
esac
echo "input your num:"
read num
case $num in
1|2|3)
echo " 1 or 2 or 3"
;;
4)
echo "4"
;;
*)
echo "error"
;;
esac
for循环
for i in 1 2 3
do
echo $i
done
## 遍历当前目录下所有shell脚本文件
for i in ./*.sh
do
echo $i
done
while 循环
条件满足才执行
count=0
while [ $count -lt 5 ]
do
count=`expr $count + 1`
echo $count
done
echo "type ctrl + d to end"
echo "enter your msg :"
while read FILE
do
echo "input msg $FILE"
done
until 循环
条件满足就结束
a=0
until [ $a -gt 5 ]
do
echo $a
a=`expr $a + 1`
done
break 与 continue
echo "input num until num <= 0"
while :
do
read num
if [ $num -gt 0 ]
then
echo "$num > 0"
else
break
fi
done
echo "exit input"
# break 1 跳出最里面一层循环 2,3...类似
# break 跳出当前的所有循环(最里层
for i in 1 2 3
do
for j in 4 5 6
do
if [ $i -eq 1 -a $j -eq 4 ]
then
break
else
echo "break $i $j"
fi
done
done
# continue n 跳过本次循环,从里到外第n层
# continue 跳过本次循环(最里层
for i in 1 2 3
do
for j in 4 5 6
do
if [ $i -eq 1 -a $j -eq 4 ]
then
continue 2
else
echo "continue $i $j"
fi
done
done
函数
# 定义函数
function hello(){
echo "hello world"
}
# 可以不用 function 关键字
say(){
echo "yes"
}
# 函数调用不需要括号
say
hello
add(){
echo "please input a:"
read a
echo "please input b:"
read b
return `expr $a + $b`
}
add
# 函数只能返回整数值,一般用于判断函数是否执行成功
# 再调用函数的语句后面紧跟着 用 $? 获取返回值
ret=$?
echo "sum :$ret"
# 删除函数
unset -f add
函数参数
function print(){
echo "parameter 1 :[ $1 ]"
echo "parameter 2 :[ ${2} ]"
# 参数位置大于9 不能通过 $10 的形式
echo "parameter 10 : [ ${10} ]"
# 参数个数
echo "parameter num : $# "
# 所有参数
echo "all parameter : $* "
}
print 1 2 3
包含文件
e1.sh
echo "i am e1"
function print(){
echo "print"
}
main.sh
# 包含文件,被包含的文件不一定要有执行权限
source ./e1.sh
# 也可以
# . ./e1.sh
print