Shell

变量

  • 定义变量变量和等号之间不能有空格, 变量定以后可从新被定义。
variableNumber=100
variableName="value"
variableName="othervalue"

使用readonly可将变量定义为只读变量,只读变量的值不能被改变

url="baidu.com"
readonly url
url="google.com" # ./test.sh: line 4: url: readonly variable
  • 使用变量时要在变量前面加美元符号($)
name="yjzhang"
echo $name
echo ${name}

变量名外的花括号可加可不加,目的是告诉解释器识别变量的边界,通常加上。

  • 删除变量时用unset variable_name,变量删除后不能再使用,unset不能删除只读变量
  • 某些字符的变量有特殊含义,这样的变量被称为特殊变量
变量 含义
$0 当前脚本的文件名
$n 传递给脚本或函数的参数,n是一个数字,表示第几个参数,例如,第一个参数是$1,第二个参数是$2
$# 传递给脚本或函数的参数个数
$@ 传递给脚本或函数的所有参数。被双引号("")包含时,与$*稍有不同,下面将会讲到。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前shell进程ID,对于shell脚本,就是这些脚本所在的进程ID。
  • 如果表达式中包含特殊字符,shell会进行替换。
a=10
echo -e "value of a is $a \n" # value of is 10

这里的-e表示对转义字符进行替换,如果不适用-e则会原样输出。echo的命令-E选项禁止转义,默认也是不转义的,使用-n宣扬可以禁止插入换行符。

  • `command`命令替换是指shell可以先执行命令,将输出结果暂时保存,在适当的地方输出。
  • 变量替换可以根据变量的状态(是否为空,是否定义等)来改变他的值
形式 说明
${var} 变量本来的值
${var:-word} 如果变量var为空或已被删除,那么返回word,但不改变var的值。
${var:=word} 如果变量var为空或已被删除(unset),那么返回word,并将var的值设置为word。
${var:?message} 如果变量var为空或已被删除(unset),那么将消息message送到标准错误输出,可以用来检测变量var是否可以被正常赋值。若此替换出现在shell脚本中,那么脚本将停止运行。
${var:+word} 如果变量var被定义,那么返回word,但不改变var的值。

运算符

  • 算术运算符,原生bash不支持简单的数学运算,可以使用expr来实现。
a=10
b=20
val=`expr $a + $b`
echo "value: $val"
运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等,用于比较两个数字,相同返回true [ $a == $b ] 返回 false。
!= 不相等,用于比较两个数字,不相同则返回true [ $a != $b ] 返回 true。

表达式和运算符之间要有空格。条件表达式要放在方括号之间,并且要有空格,例如[$a==$b]是错误的,必须写成[ $a = $b ]。

  • 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。
-ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。
  • 布尔运算符
运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
  • 字符串运算符
a="abc"
b="efg"
运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -z $a ] 返回 true。
-str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

字符串

  • 字符串可用单引号,双引号,还可以不用引号
str='this is a string'
name='yjzhang'
str="hello, \"$name\"! \n"
echo str # hello, yjzhang!
  • 单引号里的任何字符串都会原样输出,单引号字符串中的变量是无效的,
    单引号字符串中不能出现单引号(对单引号使用转义符后也不行)
  • 双引号可以有变量
    双引号里可以出现转义字符
  • 拼接字符串
name="yjzhang"
test="hello, "name" !"
test_1="hello, ${name} !"
echo $test $test_1
  • 获取字符串长度
str="abcd"
echo ${#str} # 输出 4
  • 提取子字符串
str="Today the weather was good"
echo ${str:1:4} # 输出 oday
  • 查找子字符串
str="Today the weather was good"
echo `expr index "$str" is`

数组

  • 定义数组时数组元素可以用“空格”符隔开,也可以单独定义数组元素。
array=(value0 value1 value2)
 #或者
array1=(
value0
value1
vlaue2
)
 # 或者
array2[0]=value0
array2[1]=value1
array2[2]=vlaue2
  • 读取元素的一般格式是:${array[index]},使用@或*可以获取数组中的所有元素${array[*]}${array[@]}

  • 获取数组长度的方法与获取字符串长度的方法相同

# 取得数组元素的个数
length=${#array{@}} 
#或者
length=${#array{*}}
# 取得数组单个元素的长度
lengthn=${#array[n]}

关系运算

  • if else 语句
a=10
b=20
if [ $a == $b ]
then
echo "a is equal to b"
fi # if ... fi
# 最后必须以fi来结尾闭合,fi就是if倒过来拼写。

if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi # if ... else ... fi

if [ $a == $b ]
then
echo "a is equal to b"
elif [ $a -gt $b ]
then
echo "a is greater than b"
elif [ $a -lt $b ]
then
echo "a is less than b"
else
echo "None of the condition met"
fi # if ... elif ... fi

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi 
# if ... else 语句可以与test命令结合使用,test命令用于检查某个条件是否成立,与方括号([])类似。

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;
# if ... else 语句也可以写成一行,以命令的形式运行
  • case esac语句
case 值 in # case  in  关键字
模式1)  # 每个模式必须以右括号结束
    command1
    command2
    command3
    ;; # ;; 相当于break
模式2)
    command1
    command2
    command3
    ;;
*) # 如果没有匹配的模式,使用*捕获该值
    command1
    command2
    command3
    ;;
esac

# 例如:
echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in 
1) echo 'You select 1'
;;
2) echo 'You select 2'
;;
3) echo 'You select 3'
;;
4) echo 'You select 4'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac
  • for循环
for 变量 in 列表 # 列表是一组值(数字,字符串等)组成的序列,每个值通过空格分隔。
do
    command1
    command2
    ...
    commandN
done

for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done

for str in 'This is a string' # 顺序输出字符串中的字符
do
echo $str
done

# 显示主目录下以.bash开头的文件
for FILE in $HOME/.bash*
do
echo $FILE
done
  • while循环
while command
do
   Statement(s) to be executed if command is true
done

COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done

# 用于读取键盘信息,直到按<Ctrl-D>结束循环
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo "Yeah! great film the $FILM"
done
  • until循环
    until循环执行一系列=命令直至条件为true时停止,until循环与while循环在处理方式上刚好相反。
until command
do
   Statement(s) to be executed until command is true
done
  • break和continue命令
    break命令可以跳出所有循环
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done

break nn是个整数,表示跳出第几层循环。

for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done

continue只是跳出当前循环

while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done

continue后面也可以跟一个数字,表示跳出第几层循环。

NUMS="1 2 3 4 5 6 7"

for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done

函数

  • 函数的基本格式
function_name () { 
    list of commands 
    [ return value ]
}

函数的返回值可以显示增加return语句,如果不加。会将最后一条命令运行结果作为返回值。
函数返回值只能是赠书,一般用来表示函数是否执行成功,0表示成功,其他表示失败。
如果一定要返回字符串,可以先定义一个变量,用来接收函数的计算结果。

funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
$?表示函数的返回值
}
funWithReturn # 调用函数只需要给出函数名,不需要加括号
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"

删除函数可以使用unset .f命令

$unset .f function_name

如果想要直接从终端调用函数,可以将函数定义在主目录下的.profile文件,这样每次登录后,在命令提示符后面输入函数名就可以立即调用。

  • 函数参数
    在函数内部,通过$n的形式来获取参数的值,$1表示第一个参数,$2表示第二个参数。
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !" # 参数个数
echo "The string of the parameters is $* !" # 传递给函数的所有参数,与$@相似,
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

$10不能获取第十个参数,获取第十个参数要用${10},当n>=10时,需要用${n}来获取参数。

输入输出重定向

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
命令 说明
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 之间的内容作为输入。

文件包含

包含脚本有两种方式

. filename
source filename

简单起见,一般使用点号(.)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容

  • 基础 头文件 #!/bin/bash 或者#!/bin/sh #!约定的标记,如IOS的Import 执行文件时需...
    ZMJun阅读 1,230评论 1 2
  • Bash内置基本变量 PWD : 显示当前的工作目录 OLDPWD : 显示上一次的工作目录 ~:用户家目录 - ...
    魏镇坪阅读 1,520评论 0 6
  • 0.linux启动的步骤 设备加电----》BIOS自检-----》grub引导启动-----》加载内核----》...
    萌面大叔2阅读 776评论 0 1
  • 行李箱再也塞不下任何东西了,书包也是前所未有的丰满。 紫色的行李箱,绿色的双肩包,红色的我,出发了。 凌晨五点的小...
    酒的酒窝阅读 222评论 0 2
  • 计划赶不上变化,事情永远都是三分钟热度,每次在事情还没发生之前,我相信大部分都是信誓旦旦,但真到事情突如其来之时,...
    杨博峰阅读 219评论 0 2