Appearance
Shell编程基础
从第一行开始
- 此行称为shebang (sharp(#) + bang(!)的意思),指引操作系统运行文件
#!/bin/bash
或#!/bin/zsh
是指定特定的程序来执行
shell
#!/bin/bash
#!/bin/zsh
变量
- shell默认变量全都是字符串
变量赋值及引用
- 使用变量无需事先声明
- 命名遵循
<tt>[a-zA-Z_][a-zA-Z0-9_]+
,即大小写字母数字和下划线组成(不能以数字开头) - 等号的左右都不能有空格
- 引用时须变量前加
$
- 引用时变量可能会与其他文字混淆
shell
varname="val1"
num=2
echo "This is the $numnd" #由于可能引起歧义,使用符号{}来区分
echo "This is the {$num}nd" #放歪了 ,勿手残
echo "This is the ${num}nd" #加在$所引用的变量前
变量算术
- 由于变量都是字符串,那么直接尝试加肯定不会如意
shell
var=1
var=$var+1
echo ${var} # 这里的输出是"1+1"
“好孩子写法”----C语言风格
shell
var=0
((var += 1))
((var++))
echo ${var} # 2
((var = var * var))
echo ${var} # 4
let 'var=var/3' #整数除法,向0舍入,1
echo ${var} # 1
echo $((var+=2)) # 3
var=$((var-1))
echo $var # 2
甚至有人用expr之类的外部程序,杀鸡焉用牛刀。。
shell
var=1
var=$(expr "$var"+1)
echo $var #然而输出是"1+1"
echo var=`expr "$var"+1`
echo $var #然而是"1+1+1"
流程控制
if语句
[-f "./test.sh"]
判读是否是一个文件[-x "/bin/ls"]
判断是否存在并有可执行权限[-n "$var"]
判断变量是否有值"$a"=="$b"
判断相等
shell
if [ -f "./ins.sh" ]; then
echo "yes"
elif [ -f "./test.sh" ]; then
echo "no"
else
echo "other"
fi
&&
和||
shell中的
&&
和||
没有任何优先级,仅仅先读先行
熟悉C/C++语言可能回喜欢如下表达
如果左式为真 , 则执行右式
shell
[-f "/etc/shadow"] && echo "This Computer uses shadow passwords"
当然也可以使用
||
操作,规则也与C/C++相同
shell
#!/bin/bash
message=/var/spool/folder/message
[ -r "$message" ] || { echo "can not read this message"; exit 1; }
echo "$message has message from:"
grep "^From " $message
case语句
case [...] in ... esac
语句不同于C/C++语言的swicth case
,shell语言中一切皆字符串如下例子
shell
#!/bin/bash
printf "Input integer number: "
read num
case $num in
1) echo "Monday"
;;
2) echo "Tuesday"
;;
3) echo "Wednesday"
;;
4) echo "Thursday"
;;
5) echo "Friday"
;;
6) echo "Saturday"
;;
7) echo "Sunday"
;;
*) echo "error"
esac
模版如:
shell
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
.
.
.
*)
default ;;
esac
例如:
shell
#!/bin/bash
printf "Input integer number: "
read num
case $num in
1)
echo "Monday"
;;
2)
echo "Tuesday"
;;
3)
echo "Wednesday"
;;
4)
echo "Thursday"
;;
5)
echo "Friday"
;;
6)
echo "Saturday"
;;
7)
echo "Sunday"
;;
*)
echo "error"
esac
其中
case
,in
,esac
是shell关键字expression是表达式,pattern表示匹配模式,匹配到则执行到
;;
才停止
- 执行到
esac
关键字case in
直接终止
smartunzip
shell
#!/bin/bash
ftype="$(file "$1")"
case "$ftype" in
"$1: Zip archive"*)
unzip "$1" ;;
"$1: gzip compressed"*)
gunzip "$1" ;;
"$1: bzip2 compressed"*)
bunzip2 "$1" ;;
*)
echo "File $1 can not be uncompressed with smartunzip" ;;
esac
运行
smartunzip articles.zip
可以解压三种类型文件
select循环语句
select循环语句是bash的一种扩展应用,擅长交互式场合
shell
#!/bin/bash
echo "What is your favourite OS?"
select var in "Linux" "Gnu Hurd" "Free BSD" "Other"; do
break;
done
echo "You have selected $var"
while/for循环
在shell中,可以使用如下循环:
shell
while ... ; do
...
done
如下for循环
shell
#!/bin/bash
for var in A B C ; do
echo "var is $var"
done
下面是一个实用的脚本showrpm,其功能是打印一些RPM包的统计信息:
shell
#!/bin/bash
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 ...
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in "$@"; do
if [ -r "$rpmpackage" ];then
echo "=============== $rpmpackage =============="
rpm -qi -p $rpmpackage
else
echo "ERROR: cannot read file $rpmpackage"
fi
done
数组
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
与大部分编程语言类似,数组元素的下标由 0 开始。
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
array_name=(value1 value2 ... valuen)
读取数组元素值的一般格式是:
${array_name[index]}
Bash 支持关联数组,可以使用任意的字符串、或者整数作为下标来访问数组元素。
declare -A array_name
创建一个关联数组site,并创建不同键值
shell
declare -A site=(["google"]="www.google.com" ["runoob"]="www.runoob.com" ["taobao"]="www.taobao.com")
- 使用
@
或*
可以获取数组中的所有元素 - 获取数组长度的方法与获取字符串长度的方法相同
${array[*]}
或${array[@]}
函数
用户定义函数,在shell脚本中可以随便调用
shell
#!/bin/bash
example_func(){
example_code;
...
}
参数,参数处理见上
shell
#!/bin/bash
funWithFib(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithFib 1 1 2 3 5 8 13 21 34 55 89 144
特殊符号
参数处理
参数 | 说明 |
---|---|
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数 |
$$ | 当前脚本运行的进程ID号 |
$! | 后台最后一个进程ID号 |
$@ | 同$*但是使用时加引号,并在引号中返回每个参数 |
$- | 显示shell使用的当前选项,与set命令功能相同 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表示有错误。 |
'' 和 "" | 使用引号防止通配符的扩展 |
关系运算符
关系运算符 | 说明 |
---|---|
-eq | 相等 |
-ne | 不相等 |
-gt | 大于 |
-lt | 小于 |
-ge | 大于等于 |
-le | 小于等于 |
布尔运算符
布尔运算符 | 说明 |
---|---|
! | 非 |
-o | 或 |
-a | 与 |
字符串运算符
字符串运算符 | 说明 |
---|---|
= | 字符串是否相等 |
!= | 字符串是否不相等 |
-z | 字符串长度是否为0 |
-n | 字符串长度是否不为0 |
$ | 字符串是否不为空 |
操作符
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(不是目录、设备文件) | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit) | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0) | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在 | [ -e $file ] 返回 true。 |
其他检查符:
-S
判断某文件是否socket-L
检查文件是否存在并且是一个符号链接
重定向
命令 | 说明 |
---|---|
command > file | 将输出重定向到 file。 |
command < file | 将输入重定向到 file。 |
command >> file | 将输出以追加的方式重定向到 file。 |
n > file | 将文件描述符为 n 的文件重定向到 file。 |
n >> file | 将文件描述符为 n 的文件以追加的方式重定向到 file。 |
n >& m | 将输出文件 m 和 n 合并。 |
n <& m | 将输入文件 m 和 n 合并。 |
<< tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 |