(最近很喜欢的一张图)
前言
最近有点摆了属于是,稍微懒一下就会发现,懒起来真香,嘿嘿。
本文还是从语法到实践都过一遍。后面可能还有一篇文章用于深入了解shell的一些原理。
一、流程控制
if 语句
注意1:在shell中,不可以在分支中有空语句。也就是说,如果一个分支没有逻辑,就不要写else
错误示例,下面这种写法是错误的
if ...
then ...
else 空
fi
if else语法格式
if condition
then
command1
command2
...
commandN
else
command
fi
if else-if else
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
注意点2
if else 中的判断语句中 如果condition使用的
是 [...] 大于必须使用 -gt 小于必须使用 -lt
如果是 ((...)) 可以使用 > < 或者 -gt -lt
示例
编写一个shell脚本,要求判断输入参数是大于100,还是小于100,实现如下:
需要注意的点:
- 参数要从
$1开始传,$0是代表文件名 ((...))中可以使用>,<;中括号是不可以使用的。
循环语句
for 循环
for 语法一 for 变量 in
for 变量 in 列表
do
command
done
例子1:输出1到5
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
结果如下:
例子2:输出一段话中的每个单词
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
结果如下
for 语法二 常见写法
这种写法也是很多语言类似的
for((command1;condition;doAfterloop))
do
command
done
这里的command1一般是变量初始化操作
condition一般是判断语句
doAfterloop一般是要进行下一个循环时要进行的操作
举个栗子
#!/bin/bash
for((i=0;i<5;i++))
do
echo $i
done
↑有没有发现一个问题:for中的判断语句i是没有加上$的。shell中的变量一般都是要加上$的,这里是个例外,当然加上了也没关系。
有一个点需要注意
从 ubuntu 6.10 开始,ubuntu 就将先前默认的 bash shell 更换成了dash shell,其表现为 /bin/sh 链接倒了 /bin/dash 而不是传统的 /bin/bash。
可以通过 ls -l /bin/*sh 命令看到:
所以在使用 sh 命令执行脚本的时候实际使用的是 dash,而 dash 不支持这种 C 语言格式的 for 循环写法。
解决方法: 使用 bash 代替 sh 运行脚本:
bash test.sh
while循环
while语法
while(( ... ))
do
command
done
举个栗子
#!/bin/bash
a=5
while(( $a > 0 ))
do
a=$(( $a-1 ))
echo $a
done
注意运算的方式: $(()) 或者 $[] 或者 expr ` `
再举个例子
可以用于输入读取
echo '按下 <CTRL-D> 退出'
echo -n '输入你最喜欢的网站名: '
while read FILM
do
echo "是的!$FILM 是一个好网站"
done
until 循环
语法
until condition
do
command1
...
commandN
done
如果 condition是false 那么就执行里面的语句
如果是true就跳出语句
举例
#!/bin/bash
a=5
until [ $a -lt 1 ]
do
echo "当前数字是$a"
a=$[ $a - 1 ]
done
注意一个点:这里面的大于小于 不能用> <要用-lt -gt
case...esac
后面那个结束符其实就是case反过来。 这个也非常简单,类似于swich..case
语法如下
case 变量 in
模式1) command1
;;
模式2)
command2
;;
模式3)
command3
;;
...
*)
commandN
;;
esac
注意:语法中 如果不在指定的模式,那么可以用默认的模式来捕获,就是*)来指定默认语句。
示例:
#!/bin/bash
read a
case "$a" in
"one") echo 'this is one';;
"two") echo 'this is two';;
*) echo 'this is default';;
esac
这个示例需要注意:read 后面是一个变量名。对于字符串case后面的变量需要加上 双引号。对应的case模式需要加上双引号,否则无法达到目标效果(我一个个试的。。。)。
跳出流程 break,continue
这里对于循环和 case而言,用于跳出流程控制。 非常简单,举两个例子吧。 continue例子
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字: "
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的!"
continue
echo "游戏结束"
;;
esac
done
break例子
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read aNum
case $aNum in
1|2|3|4|5) echo "你输入的数字为 $aNum!"
;;
*) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
break
;;
esac
done
二、函数
其实这个本质就是指令封装。 类似于大多数语言的函数或者mysql中的存储过程,为了提高代码复用与可读性,减少重复代码工作量。
定义函数
shell中函数的定义格式如下:
[ function ] funname [()]
{
action;
[return int;]
}
说明:
- 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
下面的例子定义了一个函数并进行调用:
示例
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
输出结果:
-----函数开始执行-----
这是我的第一个 shell 函数!
-----函数执行完毕-----
下面定义一个带有return语句的函数:
示例
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
输出类似下面:
这个函数会对输入的两个数字进行相加运算...
输入第一个数字:
1
输入第二个数字:
2
两个数字分别为 1 和 2 !
输入的两个数字之和为 3 !
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
带参数的函数示例:
示例
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
输出结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
另外,还有几个特殊字符用来处理参数:
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本或函数的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 |
| $- | 显示Shell使用的当前选项,与set命令功能相同。 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
函数中几个注意的点
如何获得函数的返回值?
使用$?用来代替刚刚执行的函数的结果。
注意:调用的$? 和上一条函数调用的语句紧接着。中间不能有其他语句。这是因为$?仅对上一条语句有效。
举个栗子
#!/bin/bash
function1(){
return 3;
}
function1
echo $?
function1
echo "中间插一句"
echo $?
结果如下:
3
中间插一句
0
函数返回值的true和false
与C语言不同的是 shell中 0 表示true,0以外其他数字表示false;
还是举个例子
#!/bin/bash
func(){
return $1
}
if func $1
then
echo "这是0 是true"
else
echo "false"
fi
这个脚本可以用来印证上面结论。
后续内容
本文比较详细说了剩下的一些shell脚本的基本语法,总体而言,其实还是比较基础和简单的,这些基本够用了,但是写起脚本来,还是错误一堆?不知道怎么下手?
所以后面的文章主要围绕以下几个点写
- 总结写shell脚本时常用到的Linux命令。
- 写shell常用的骚操作以及常见错误写法。
- shell的深入理解和原理相关内容。
本文基本原创,部分图文来自网络,如有错误,请指点。