您的位置:首页 > 运维架构 > Shell

Shell Script基本语言

2015-07-10 09:47 495 查看
第一个shell script程序

#!/bin/bash
# Program:
#    this is a test shell script
# 2015/07/10    zhubinqiang     Fitst release
echo "Welcome to shell script!"


脚本第一行 指定/bin/bash解释器执行,虽然以#开头 但不是注释

#开头的是单行注释

注释

# 这是单行注释1
# 这是单行注释2


Shell里面没有多行注释,小技巧实现多行注释

COMMENT_BLOCK=
if [ $COMMENT_BLOCK ]; then
===========================
echo "comment1"
echo "comment2"
echo "comment3"
===========================
fi


变量

a=15
version1=$(uname -r)
version2=`uname -r`
echo $a
echo ${version1}
echo $version2
PATH="$PATH:$HOME/bin"
export PATH
unset a


变量名=变量, 两边没有空格的。 空格在shell中有特殊用途,分开的话会解释成【命令 参数 参数】的形式

变量名区分大小写。 name 与 Name 是两个变量

变量有空格的话要用单引号” 或 双引号 “” 将变量内容结合起来

上式中$a 与 ${a} 是相同效果的。使用${a} 避免出错

‘${a}’ 是强引用 输出${a}。”${a}”是弱引用,输出变量值

export 使变量成为环境变量

unset 取消变量

shell变量是不区分类型的,变量值都是字符串。Bash允许整数比较和运算操作,但变量中只有数字

算术运算

算术运算符

操作符描述
+加法运算
-减法运算
*乘法运算
/除法运算
%求余运算
**幂运算
+=加等于
-=减等于
*=乘等于
/=除等于
%=取模等于

let 运算

a=1
let a=a+1
echo $a           # 2
let a+=1
echo $a           # 3
let "a = a + 2"
echo $a           # 5


$((…))运算

a=1
a=$((a+1))
echo $a


expr 运算

a=1
b=`expr $a + 1`
echo $b


if … else … 判断语句

a="hello"
if [ "$a" == "hello" ]; then
echo "Hello, how are you."
elif [ "$a" == "" -o "$a" == '?' ]; then
echo "what?"
elif [ "$a" == 'y' ] || [ "$a" == 'Y' ]; then
echo "Yes"
else
echo "I don't understand you."
fi


[ 左右两边有一个空格, == 左右两边有一个空格,] 左边有一个空格

算术与字符串测试

操作描述操作描述
算术比较中括号[…]结构字符串比较中括号[…]结构
-eq等于=/==等于
-ne不等于!=不等于
-lt小于\<小于(ASCII) *
-le小于等于
-gt大于\>大于(ASCII)*
-ge大于等于
-z字符串为空
-n字符串不为空
算术比较双括号((…))结构条件判断
>大于-a两个条件同时成立
>=大小于等于-o任何一个条件成立
<大于!
<=小于等于
*如果在双中括号[[ … ]]测试中的话,那么不需要转义符\

文件测试

操作描述操作描述
-e文件是否存在-s文件大小不为0
-f是一个标准文件
-d是一个目录-r文件具有读的权限
-h文件是一个符号链接-w文件具有写的权限
-L文件是一个符号链接-x文件具有执行权限
-b文件是一个块设备
-c文件是一个字符设备-g设置了sgid标记
-p文件是一个管道-u设置了suid标记
-S文件是一个socket-k设置了”粘贴位”
-t文件与一个终端相关联
-N从这个文件最后一次被读取之后,它被修改过F1 -nt F2文件F1比文件F2新
-O这个文件的宿主是你F1 -nt F2文件F1比文件F2旧
-G文件的组id与你所在的组相同F1 -nt F2文件F1和F2都是同一个文件的硬链接
!“非”(翻转上边的测试结果)

Case

像C语言中的switch… case…

a="hello"
case $a in
"hello")
echo "Hello, how are you." ;;
"")
echo "what?" ;;
*)
echo "I don't understand you." ;;
esac


while 循环

i=0
s=0
while [ "$i" -le 100 ];do
s=$((s+i))
i=$((i+1))
done
echo "1 + 2 + 3 + ... + 100 = $s"


until 循环

i=0
s=0
until [ "$i" -gt 100 ]; do
s=$((s+i))
i=$((i+1))
done
echo "1 + 2 + 3 + ... + 100 = $s"


for 循环

for i in Tom Jack John; do
echo $i
done

for i in $(seq 1 5); do
echo $i
done

for i in {1..5}; do
echo $i
done

for((i=0; i<5; i++)); do
echo $i
done


数组

array=(5 4 3 2 1)
echo ${array[0]}     # 第一个元素

len=${#array[*]}     # 数组长度
for((i=0; i<$len; i++));do
echo ${array[$i]}
done

for i in ${!array[@]}; do
echo ${array[$i]}
done


函数

函数定义

function function_name {
command...
}

function function_name() {
command...
}

function_name() {
command...
}


使用函数

function sayHello() {
local name=$1
echo "Hello $name"
return 0
}

sayHello "Tom"


return返回的是状态码。 0 表示成功, 非0表示失败。

如果要返回值用echo

function sum(){
local a=$1
local b=$2
local s=$((a+b))
echo $s
}

s=`sum 2 3`
echo $s


用shift 获取参数

function sum(){
local a=$1
shift
local b=$1
local s=$((a+b))
echo $s
}

s=`sum 2 3`
echo $s


I/O操作

终端输入,并赋值

read -p "Your name(within 30s):" -t 30 named
echo $named


输出多行

cat << EOF
comment1
comment2
comment3
EOF


I/O重定向

COMMAND > filename             # 重定向stdout到文件filename
COMMAND 1> filename            # 重定向stdout到文件filename
COMMAND >> filename            # 重定向stdout并追加到文件filename
COMMAND 1>> filename           # 重定向stdout并追加到文件filename
COMMAND 2> filename            # 重定向stderr到文件filename
COMMAND 2>> filename           # 重定向stderr并追加到文件filename
COMMAND &> filename            # 将stdout和stderr都重定向到filename
COMMAND &>> filename           # 将stdout和stderr都重定向并追加到filename
COMMAND > filename 2>&1        # 将stdout和stderr都重定向到filename
COMMAND >> filename 2>&1       # 将stdout和stderr都重定向并追加到filename


管道操作

COMMAND1 | COMMAND2 | COMMAND3
cat /etc/passwd | grep "root" | awk -F":" '{print $1}'


管道操作是由前面的stdin传递过来的。 stderr不会传过去

特殊Shell变量

变量含义
$0脚本名字
$1位置参数 #1
$9位置参数 #9
${10}位置参数 #10
$#位置参数的个数
“$*”所有的位置参数(作为单个字符串)
“$@”位置参数的个数(作为独立的字符串)
${#*}传递到脚本中的命令行参数的个数
${#@}传递到脚本中的命令行参数的个数
$?返回值
$$脚本的进程IP(PID)
$-传递到脚本中的标志(使用set)
$_之前命令的最后一个参数
$!运行在后头的最后一个作业的进程ID(PID)
“∗”要用引号引起来,否则默认为”*” 要用引号引起来,否则默认为”@”

系统环境变量

变量含义
$IFS保存了用于分割输入参数的分割字符,默认识空格
$HOME当前用户的根目录路径
$PATH可执行文件的搜索路径
$PS1第一个系统提示符
$PS2第二个系统提示符
$PWD当前工作路径
$EDITOR系统的默认编辑器名称
$BASH当前Shell的路径字符串
$EUID“有效”用户ID

字符串操作

表达式描述
${#string}$string的长度
${string:position}在$string中,从position开始提取字串
${string:position:length}在$string中,从position开始取长度为length的字串
${string#substring}从变量$string的开头,删除最短匹配$substring的字串
${string##substring}从变量$string的开头,删除最长匹配$substring的字串
${string%substring}从变量$string的结尾,删除最短匹配$substring的字串
${string%%substring}从变量$string的结尾,删除最长匹配$substring的字串
${string/substring/replacement}使用$replacement,代替第一个匹配的$substring
${string//substring/replacement}使用$replacement,代替所有匹配的$substring
${string/#substring/replacement}如果$string的前缀匹配$substring,那么就用$replacement来代替匹配的$substring
${string/%substring/replacement}如果$string的后缀匹配$substring,那么就用$replacement来代替匹配的$substring
expr match “$string” ‘$substring’匹配$string开头的$substring*的长度
expr “$string” : ‘$substring’匹配$string开头的$substring*的长度
expr index “$string” $substring在$sttring中匹配到$substring的第一个字符出现
expr substr $string $position $length在$string中从位置$position开始提取长度为$length的字串
expr match “$string” ‘\{$substring}\’在$string的开头位置提取$substring*
expr “$string” : ‘\($substring)\’从$string的开头位置提取$substring*
expr match “$string” ‘.*\($substring)\’从$string的结尾提取$substring*
expr “$string” : ‘.*\($substring)\’从$string的结尾提取$substring*
* $substring 是一个正则表达式

结构汇总

操作描述
中括号
if [ Condition ]测试结构
if [[ Condition ]]扩展的测试结构
Array[1]=element1数组初始化
[a-z]正则表达式的字符范围
大括号
${variable}参数替换
${!variable}间接变量引用
{ command1; command2; … commandN; }代码块
{string1, string2, string3}大括号扩展
小括号
( command1; command2 )子shell中执行的命令组
Array=(element1 element2 emement3)数组初始化
result=$(COMMAND)在子shell中执行命令,并将结果赋值给变量
>(COMMAND)进程替换
<(COMMAND)进程替换
双小括号
(( var = 78 ))整型运算
var=$(( 20 + 5 ))整型运算,并将结果赋值给变量
引号
“$variable”“弱”引用
‘string’“强”引用
后置引用
result=`COMMAND`在子shell中运行命令,并将结果赋值给变量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: