类似于 C/C++中的 if…else语句
单层if
命令格式
if condition
then
语句一
语句二
...
fi
例如:
#! /bin/bash
a=3
b=4
if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ]
then
echo ${a}在范围内
fi
单层if-else
命令格式:
if condiotion
then
语句一
语句二
...
else
语句一
语句二
...
fi
例如:
#! /bin/bash
a=3
b=4
if ! [ "$a" -lt "$b" ]
then
echo ${a}不小于${b}
else
echo ${a}小于${b}
fi
多层if-elif-elif-else
命令格式
if condition
then
...
elif condition
then
...
else
...
fi
例如:
#1 /bin/bash
a=4
if [ $a -eq 1 ]
then
echo ${a}等于1
elif [ $a -eq 2 ]
then
echo ${a}等于2
elif [ $a -eq 3 ]
then
echo $a等于3
else
echo 其他
fi
类似于C/C++中的 Switch 语句
命令格式:
case $变量名称 in
值1)
语句一
...
;; #类似于C++中的break
值2)
语句一
...
;;
*) #类似于C++中的default
语句一
...
;;
esac
例如:
#1 /bin/bash
a=4
case $a in
1)
echo $a等于1
;;
2)
echo $a等于2
;;
3)
echo $a等于3
;;
*)
echo 其他
;;
esac
命令格式
for val in val1 val2 val3
do
语句一
语句二
...
done
例如1:输出sun 20 tong,每个元素占一行
#1 /bin/bash
for i in sun 20 tong
do
echo "$i"
done
例如2:输出当前路径下的所有文件名,每个文件名占一行
#1 /bin/bash
for file in `ls`
do
echo $file
done
示例3:输出1-10之间的数字(seq命令只支持数字)
#1 /bin/bash
for i in $(seq 1 10)
do
echo $i
done
示例4:使用 {1…10} 或者 {a…z}
#1 /bin/bash
for i in {a..z}
do
echo $i
done
命令格式
for((expression; condition; expression))
do
语句一
语句二
...
done
示例:输出1-10,每个数占一行
#1 /bin/bash
for ((i=1; i<=10; i++))
do
echo $i
done
命令格式
while condition
do
...
done
例如:文件结束符为 ctrl + d ,输入文件结束符后 read命令返回 false
#1 /bin/bash
while read name
do
echo $name;
done
当条件为真时结束,命令格式
until condition
do
...
done
例如:当用户输入yes或者YES时结束,否则一直等待读入
#1 /bin/bash
until [ "${word}" == "yes" ] || [ "${word}" == "YES" ]
do
read -p "please input yes or YES to stop this commod: " word
done
跳出当前的一层循环,注意与C/C++不同的是:break不能跳出case语句
例如:
#1 /bin/bash
while read name
do
for ((i=1; i<=10; i++))
do
case $i in
8)
break;
;;
*)
echo $i
;;
esac
done
done
每次读入非EOF的字符串,会输出一遍1-7
该程序可以输入 ctrl + d 文件结束符来结束,也可以直接用 ctrl + c 来杀掉该程序
跳出当前循环,与C++一样
示例:输出 1-10 之间的所有奇数
#1 /bin/bash
for ((i=1; i<=10; i++))
do
if [ `expr $i % 2` -eq 0 ]
then
continue
fi
echo $i
done
如果terminal可以打开该程序,可以输入 ctrl + c 直接杀掉该程序即可
如果打不开该程序,可以直接关闭进程:
关闭进程:
bash中的函数类似于C++中的函数,但是return的返回值与C++不同,返回的是 exit code(退出状态,0表示正常退出,取值为0-255)
如果想要获取函数的输出结果,可以通过 echo 输出到sdout 中,然后通过 $(function_name) 来获取sdout中的结果
函数中的 return 值可以通过 $? 来获取
命令格式:
[function] func_name(){ # funtion关键字可以省略
...
}
不获取 return 值和 sdout 值
例如:
#1 /bin/bash
func(){
name=sun
echo "hello $name"
}
func #调用函数,不需要加 ()
获取 return 值和 sdout 值:不写return值时,默认 return 0
例如:
#1 /bin/bash
func(){
name=sun
echo "hello $name"
return 123
}
output=$(func) #sdout
ret=$? #exit code
echo "output = $output"
echo "ret = $ret"
函数的输入参数
在函数内,$1 表示第一个输入的参数,$2 表示第二个输入参数,…
注意:函数内的 $0 仍然是文件名,而不是函数名
例如:
#! /bin/bash
# 递归计算 $1 + ($1 - 1) + ($1 -2) + ... + 0
func(){
if [ $1 -le 0 ]
then
echo 0
return 0
fi
sum=$(func $(expr $1 - 1))
echo $(expr $sum + $1)
}
echo $(func 10)
这里面为什么只输出最后结果55,而不输出其他值呢?因为 echo 函数后面有 $ ,就会截获 sdout 里面的值,使得 echo 找不到 sdout 里的数据从而不能输出
函数内的局部变量
可以在函数内部定义局部变量,作用范围仅在当前函数内,可以递归函数中定义局部变量
命令格式:
local 变量名=变量值
例如:
#! /bin/bash
func(){
local name=sun
echo $name
}
func
echo $name
exit命令用来退出当前 shell 进程,并返回一个退出状态;使用 $? 可以接受这个退出状态
exit命令可以接受一个整数值作为参数,代表退出状态,如果不指定,默认退出状态是0
exit退出状态只能是一个介于0-255之间的整数,其中0表示成功退出,其他值都表示失败
例如:
#! /bin/bash
if [ $# -ne 1 ] #如果传入参数等于1,则正常退出
then
echo "arguments not vaild"
exit 1
else
echo "arguments vaild"
exit 0
fi
acs@fb883ed03006:~$ ./test.sh 25 #传入一个参数
arguments vaild
acs@fb883ed03006:~$ echo $?
0
acs@fb883ed03006:~$ ./test.sh #传入0个参数
arguments not vaild
acs@fb883ed03006:~$ echo $?
1
每个进程默认打开三个文件描述符
可以用文件重定向将这三个文件重定向到其他文件中
重定向命令列表
命令 | 说明 |
---|---|
command > file | 将 stdout 重定向到 file 中 |
command < file | 将 stdin 重定向到 file 中 |
command >> file | 将 stdout 以追加的方式重定向到 file 中 |
command n > file | 将文件描述符 n 重定向到 file 中 |
command n >> file | 将文件描述符 n 以追加的方式重定向到 file 中 |
输入和输出重定向
#! /bin/bash
echo -e "hello \c" > output.txt #将stdout重定向到output.txt中
echo "world" >> output.txt #将字符串追加到output.txt文件中
read str < output.txt #从output.txt文件中读取字符串
echo $str #输出结果:hello world
同时重定向stdin和stdout
#! /bin/bash
read a
read b
echo $(expr "$a" + "$b")
创建output.txt文件,里面内容为
3
4
执行命令:
acs@fb883ed03006:~$ ./test.sh < input.txt > output.txt #从output.txt中读取内容,并输入到input.txt文件中
-bash: input.txt: No such file or directory
acs@fb883ed03006:~$ ./test.sh < output.txt > input.txt
acs@fb883ed03006:~$ cat input.txt
7
类似于C++中的 include 操作,bash也可以引入其他文件中的代码
语法形式:
. file #注意点和文件名之间有一个空格
#或者
source filename
例如:先创建一个 test1.sh,内容为
#! /bin/bash
name=sun
然后创建 test2.sh脚本,内容为
#! /bin/bash
source test1.sh #或者 . test1.sh
echo my name is: $name
输出结果:my name is: sun