bash简介
bash是Linux的一种Shell,Linux的Shell种类很多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
bash也就是 Bourne Again Shell,在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
#!告诉系统气候路径所指定的程序即是解释此脚本文件的Shell程序,不可省略。
新建的shell脚本要加可执行权限,执行命令的文件名前要加./,否则系统会去PATH里找脚本文件,从而因找不到该文件而报错。
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
基本语法
1.变量
定义变量——不加$符号,变量名和等号之间不能有空格。
赋值两种方式:直接赋值、通过linux命令赋值
name="summer"
for file in `ls /etc`
或
for file in $(ls /etc)
使用变量——需要加$符号,可以加花括号括起来(推荐)
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
变量操作
- 设置只读变量:变量前加 readonly
- 删除变量:变量前加 unset
2.字符串
字符串可以用单引号、双引号也可以不用引号
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
双引号的优点:
拼接字符串
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
输出结果
hello, runoob ! hello, runoob !
hello, runoob ! hello, ${your_name} !
获取字符串长度
变量前加一个#号
string="abcd"
echo ${#string} # 输出 4
提取字符串
字符串索引从0开始,${string:1:4} 表示字符串从第2个字符开始截取4个字符
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找子字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
3.数组
支持一维数组,不支持多维数组,下标0开始编号。
定义数组:括号表示,空格分开
array_name=(value0 value1 value2 value3)
或者
array_name=(
value0
value1
value2
value3
)
还可以单独定义数组的各个分两,可以不使用下标,下标范围无限制
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
读取数组:
使用 @ 符号可以获取数组中的所有元素,例如:
获取数组长度:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
关联数组(大概可以理解为python中的dict)
声明
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"
echo ${site["runoob"]}
‘#’和‘@’用于访问数组全部内容,数组前加!号获取键值,数组前加#号用于获取数组长度。
#!/bin/bash
declare -A site
site["google"]="www.google.com"
site["runoob"]="www.runoob.com"
site["taobao"]="www.taobao.com"
echo "数组的元素为: ${site[*]}"
echo "数组的元素为: ${site[@]}"
echo "数组的键为: ${!site[*]}"
echo "数组的键为: ${!site[@]}"
echo "数组元素个数为: ${#site[*]}"
echo "数组元素个数为: ${#site[@]}"
数组的元素为: www.google.com www.runoob.com www.taobao.com
数组的元素为: www.google.com www.runoob.com www.taobao.com
数组的键为: google runoob taobao
数组的键为: google runoob taobao
数组元素个数为: 3
数组元素个数为: 3
4.注释
单行注释用#号
多行注释:
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
5.传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
#!/bin/bash
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
执行上述脚本并输出,可见执行的文件名为0号参数,后面依次为参数1,2,3
$ chmod +x test.sh
$ ./test.sh 1 2 3
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3
6.运算符
算数运算符
关系运算符
布尔运算符
逻辑运算符
注意有两层中括号
字符串运算符
文件测试运算符
7.echo命令
-e 开启转义
echo -e "OK! \n" # -e 开启转义
echo "It is a test"
显示命令执行结果,用反引号`把命令括起来
Thu Jul 24 10:08:46 CST 2014
8.test命令
用于检查某个条件是否成立,可以进行数值、字符和文件三个方面的测试。
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
代码中的 [] 执行基本的算数运算
9.流程控制
条件判断
if condition
then
command1
command2
...
commandN
fi
末尾的 fi 就是 if 倒过来拼写
if else 的 [...] 判断语句中大于使用 -gt,小于使用 -lt。
if [ "$a" -gt "$b" ]; then
...
fi
如果使用 ((...)) 作为判断语句,大于和小于可以直接使用 > 和 <。
if (( a > b )); then
...
fi
for循环
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
while循环
while condition
do
command
done
#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
until循环
until循环执行一系列命令直至条件为true时停止。
until condition
do
command
done
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
case...esac多选择语句,每个case分支用右圆括号开始,用两个分号;;表示break。esac(case反过来)作为结束标记。
如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
跳出循环
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
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
10.函数
定义函数
[ function ] funname [()]
{
action;
[return int;]
}
说明:
- 1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255),函数返回值在调用该函数后通过 $? 来获得
函数参数
注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
#!/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 !
11.输入/输出重定向
需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1
这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。
12.文件包含
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
#!/bin/bash
#使用 . 号来引用test1.sh 文件
. ./test1.sh
# 或者使用以下包含文件代码
# source ./test1.sh
echo "菜鸟教程官网地址:$url"
注:被包含的文件 test1.sh 不需要可执行权限
参考:https://www.runoob.com/linux/linux-shell.html