文章目录
变量
环境变量
环境变量用于初始化shell的启动环境,是系统定义的变量。
常用的环境变量有下面几种
可以使用env命令来查看所有的环境变量,也可以直接echo查看某个环境变量的值
位置变量
我们可以使用shift命令来将参数左移,语法如下
shift 表示移动的位数
每次左移一位
#!/bin/bash
echo $@
shift 1
echo $@
shift 1
echo $@
shift 1
echo $@
特殊变量
$n :表示输入的第n个参数,当超过十的时候需要用大括号括起来,如${10}
$# :获取输入参数的个数
$? :获取上一条命令的执行状态,如果为0则说明执行成功,为1则说明执行失败。当然也可以用于获取函数返回值
$$ :获取当前进程的pid
$@ :代表当前命令行中所有的参数,不过它会把每个参数区分对待
$* :代表当前命令行中所有的参数,不过它会把所有参数当成一个整体
自定义变量
定义变量的方式很简单,只需要给它赋值进行,并且不需要指明类型
变量名=值
当需要删除变量的时候,可以使用unset命令
unset 变量名
如果想要声明常量,可以使用readonly关键字,但是需要注意,常量不可被unset
readonly 变量名
我们还可以通过export命令将局部变量升级为环境变量
export 变量名
注意事项
- 等号两边不能有空格
- 如果变量名中存在空格时需要以单引号或者双引号括起来,否则会被当成命令
- bash中变量会被默认视为字符串类型,无法直接进行算数运算
数组
定义数组
数组名=( 元素1 元素2 元素3 ...... )
# 元素前后以空格为间隔
显示数组的所有元素
echo ${数组名[@]}
显示数组的元素个数
echo ${#数组名[@]}
显示数组的第i个元素
echo ${数组名[i]}
例如
将参数作为数组元素,查看数组中的内容
#!/bin/bash
arr=( $@ )
echo ${arr[@]}
echo ${#arr[@]}
echo ${arr[5]}
I/O
printf / echo
shell中的输出命令有printf和echo两种,printf是从C语言中模仿而来,所以它可以指定类型、对其方式等属性。
echo 输出
printf 输出
同时echo输出时会自带换行,而printf则需要自己手动加入\n
read
read用于从终端获取输入
语法如下
read (选项)(参数)
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)。
实例:从终端获取一个值并输出
#!/bin/bash
read -p "请输入参数:" str
echo $str
算术运算
shell中存在两种算术运算的命令,分别是let和expr
let
let的语法如下
let 变量名=值
let 变量名=变量名+值
需要注意的是,当有变量加入运算的时候不需要在变量前面加$
通常为了简便,我们也会使用两个圆括号let
((算术式)) # 不需要空格
我们通常以以下两种方式来获取计算结果
$((运算式)) 或 $[运算式]
expr
expr用来计算表达式,每一个运算符之间要有空格,并且当有变量加入时需要加上$
expr + , - , \*, /, %
条件判断
test
在shell中我们通常利用test来进行条件判断,当结果为真时返回0,失败时返回1
语法如下:
test 判断内容
不过我们通常都会以方括号的形式进行简写,如下
[ 判断条件 ] # 需要注意的是条件前后需要有空格
常用判断条件
- 判空
-n :非空(nonzero)
-z :为空(zero)
- 字符串之间比较
= :字符串相同 != :字符串不同
- 整数之间比较
-eq :等于(equal) -ne :不等于(Not equal)
-lt :小于(less than) -le :小于等于(less equal)
-gt :大于(greater than) -ge :大于等于(greater equal)
- 判断文件权限
-r :有读的权限(read)
-w :有写的权限(write)
-x :有执行的权限(execute)
- 判断文件类型
-f :文件存在并且是一个常规的文件(file)
-e :文件存在(existence)
-d :文件存在并是一个目录(directory)
流程控制
if
if用于进行逻辑判断,语法格式如下
if test 条件 # 或者使用[ 条件 ]
then
# 执行的命令
elif test 条件 # 进行其他的分支判断
then
# 执行的命令
else # 剩余的情况
# 执行的命令
fi
例如判断输入的数字是否大于十
#!/bin/bash
a=$1
if [ $a -lt 10 ]
then
echo "less than 10"
elif [ $a -gt 10 ]
then
echo "greater than 10"
else
echo "equal than 10"
fi
case
case用于进行分支选择,语法格式如下
case $变量名 in
"值A")
# 执行分支A
;;
"值B")
# 执行分支B
;;
"值C")
# 执行执行分支C
;;
*)
# 如果不为以上值,则执行缺省分支
;;
esac
注意事项
- case行必须以in结尾,每个值必须要用双引号包含,并以右括号结束
- ;;代表分支的结束,类似于C中的break
- *)代表缺省模式,类似于C中的default
例如以下使用情况
#!/bin/bash
a=$1
case $a in
"1")
echo "11111111111"
;;
"2")
echo "22222222222"
;;
"3")
echo "33333333333"
;;
*)
echo "default"
;;
esac
shell中的循环控制主要有for,while,until三种
for
shell中的for循环有两种语法,一种是我们传统的C语言for,另一种则类似C++中的范围for
# 语法1
for ((初始值; 循环条件; 变量变化))
do
# 执行命令
done
# 语法2
for 变量 in 数组或者区间
do
# 执行命令
done
分别进行演示
计算1到100的累加和
#!/bin/bash
i=0
sum=0
for ((i=0; i<=100; i++))
do
sum=$[$sum+$i]
done
echo $sum
计算输入的参数之和
#!/bin/bash
sum=0
for i in $@
do
sum=$[$sum+$i]
done
echo $sum
while
while的逻辑是当判断条件为真时执行循环
语法如下
#!/bin/bash
while [ 判断条件为真则执行 ]
do
# 执行命令
done
until
until与while刚好相反,如果判断条件为假,则until继续执行
语法如下
#!/bin/bash
until [ 判断条件为假则执行 ]
do
# 执行命令
done
函数
系统函数
系统自建的函数库在路径 /etc/init.d/functions中
常用的主要有basename和dirname两种,用于解析文件的路径
basename通常用于获取文件名,它会找到最后一个/的位置,并删除前面所有字符
basename 文件路径 [可选: 删除的字符]
例如
dirname主要用于获取路径名,它会去掉文件名,然后返回剩余的部分
dirname 文件路径
自定义函数
shell中也允许自定义函数,语法如下
function 函数名() #括号中不能填任何东西
{
# 执行命令
# 返回值
}
注意事项
- 括号中不能填任何参数,传参可以直接通过 $变量名的形式传递,返回值可以使用特殊变量 $? 获取。如果没有声明返回值,则以函数最后一条命令的结果作为返回值
- shell脚本是逐行运行的,所以必须先声明函数才能调用
获取两个数相加的结果
function add()
{
echo $[$1+$2]
}
read -p "请输入参数A: " a
read -p "请输入参数B: " b
add $a $b