Shell脚本(1)
Shell(1)
变量
Bash脚本中变量可以分为字符串、数字、数组等等,较为常用的还是字符串
命名规范
- 只包含字母、数字和下划线: 变量名可以包含字母(大小写敏感)、数字和下划线 _,不能包含其他特殊字符。
- 不能以数字开头: 变量名不能以数字开头,但可以包含数字。
- 避免使用 Shell 关键字: 不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
- 使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母,例如 PI=3.14。
- 避免使用特殊符号: 尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。
- 避免使用空格: 变量名中不应该包含空格,因为空格通常用于分隔命令和参数。
定义# 注意不能有空格
# str = "abc"是错误的写法
str="abc"
str='abc'
digit=12
declare -i digit=12
array=(1 2 3 4 5)
declare -A associate_array=(["A"]="1" ["B"]="2" ["C"]="3")
引用str="abc"
digit=12
array=(1 2 3 4 5)
# 获得变量的值/引用变量需要使用$
# 字符串变量
echo $str
# >>> abc
echo $digit
# >>> 12
echo ${array[@]}
# >>> 1 2 3 4 5
# 对于可能有歧义的变量名字需要使用{}括起来
str="abc"
# 如果不使用{}将会把strabc识别为一个变量
echo "${str}abc"
# >>> abcabc
echo $str
# >>> abc
字符串
在Bash脚本中经常使用的一种变量,具有最主要的特征
单引号与双引号的区别# 1.单引号中无法识别变量名
name="yangman"
str1="I love ${name}"
str2='I love ${name}'
echo $str1
# >>> I love yangman
echo $str2
# >>> I love ${name}
# 2.单引号无法使用单引号(即使转义)
str1="myname \"\'"
str2='myname \"\''
echo $str1 \'
# 显而易见,即使转义了单引号也会引起后续问题,必须只能成对出现
# 3.二者都可以使用拼接操作
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1
# >>> hello, runoob ! hello, runoob !
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
# >>> hello, runoob ! hello, ${your_name} !
计算字符串长度str="abc"
echo ${#str}
# >>> 3
echo ${#str[0]}
# >>> 3
# 注意这里虽然使用了索引
# 但是字符串实则为不可迭代/不可索引的对象!!!
字符串切片操作str="1234567"
# string:index[:length]
echo ${str:1}
# >>> 234567
echo ${str:1:3}
# >>> 234
查找子串echo $(expr index "string" io)
# 找到string串中第一次出现i或者o的位置
数组
数组由索引的类型分为两大类
- 整数索引数组,顾名思义,索引都是整数的数组
- 关联数组,索引可以是字符串也可是整数
数组定义# 除了和一般变量定义外
# 数组支持直接通过下标赋值
# 索引数组索引不要求连续
new_array[0]="1"
new_array[1]="2"
new_array[6]="3"
new_array[10]="6"
# 关联数组需要声明
declare -A associ_array
associ_array["A"]="1"
associ_array["B"]="1"
associ_array["D"]="1"
associ_array["SD"]="1"
数组索引
- 正常语言的索引,通过下标取值
echo ${array[index]}
计算数组长度# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
length=${#array_name[n]}
列出所有元素array=(1 2 3 4 5)
# 1.列出所有的value
echo ${array[@]}
# >>> 1 2 3 4 5
# 实际表现为 "1" "2" "3" "4" "5"
echo ${array[*]}
# >>> 1 2 3 4 5
# 实际表现为 "1 2 3 4 5"
# 意味着一个是可迭代的,一个不是可迭代的
for i in ${array[@]}; do
echo $i
done
# >>> 1
# >>> 2
# >>> 3
# >>> 4
# >>> 5
for i in ${array[*]}; do
echo $i
done
# >>> 1 2 3 4 5
# 列出所有的key
# 都是可迭代的
echo ${!array[@]}
# >>> 0 1 2 3 4
echo ${!array[*]}
# >>> 0 1 2 3 4
符号
Shell类
$()
- 将其中的字符识别为shell命令,并将结果作为返回值
echo $(ls)
var=$(ls)
for i in $var;do
echo $i
done反引号
- 同上,转义为命令并返回结果
echo `ls`
var=`ls`()
- 开启一个shell子进程,其内部变量不影响当前进程
# 子 Shell
(a=10; echo $a) # 输出 10
echo $a # 输出空,因为子 Shell 中的变量不影响父 Shell
# 数组
arr=(1 2 3)
echo ${arr[1]} # 输出 2
算术类
- 对于整数类型或者纯数字的字符串
(())
- 支持所有c语言支持的运算符
- 算术拓展,在其中可以直接使用各种运算符并且不需要引用变量
a=5
b=10
((a++))
((c = a + b))
echo $c
# >>> 16 - 支持运算符
运算符 | 说明 | 示例 |
---|---|---|
+ |
加法 | (( a = 5 + 3 )) |
- |
减法 | (( a = 5 - 3 )) |
* |
乘法 | (( a = 5 * 3 )) |
/ |
整数除法(只返回整数部分) | (( a = 5 / 2 )) (结果 2 ) |
% |
取模 | (( a = 5 % 2 )) (结果 1 ) |
** |
幂运算 | (( a = 2 ** 3 )) (结果 8 ) |
++ |
自增 | (( a++ )) 或 (( ++a )) |
-- |
自减 | (( a-- )) 或 (( --a )) |
= |
赋值 | (( a = 10 )) |
+= |
加法赋值 | (( a += 2 )) |
-= |
减法赋值 | (( a -= 2 )) |
*= |
乘法赋值 | (( a *= 2 )) |
/= |
除法赋值 | (( a /= 2 )) |
%= |
取模赋值 | (( a %= 2 )) |
== |
等于 | (( a == b )) |
!= |
不等于 | (( a != b )) |
> |
大于 | (( a > b )) |
< |
小于 | (( a < b )) |
>= |
大于等于 | (( a >= b )) |
<= |
小于等于 | (( a <= b )) |
&& |
逻辑与 | (( a > 3 && b < 5 )) |
|| | 逻辑或 | (( a > 3 ||b < 5 )) |
! |
逻辑非 | (( !a )) |
& |
按位与 | (( a & b )) |
| | 按位或 | (( a |b )) |
^ |
按位异或 | (( a ^ b )) |
<< |
左移 | (( a << 1 )) |
>> |
右移 | (( a >> 1 )) |
$(())
- 也是算术拓展,但是这里是返回了值,不能像上面一样内部赋值
a=5
b=10
a=$((a + 1))
c=$((a + b))
echo $c
# >>> 16$[]
- 同上,但是已经过时,尽量补药使用
比较类
[]
- test比较方法的简写
- 对于数字比较(纯数字的字符串)
- 支持
==
、!=
- 支持
-gt
、-lt
、-eq
、-ne
、-ge
、le
- 支持
!
、-o
、-a
,不能直接支持&&
、||
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
# if [ $a -lt 100 ] && [ $b -gt 15 ]
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a 小于 100 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 100 或 $b 大于 100 : 返回 false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a 小于 5 或 $b 大于 100 : 返回 true"
else
echo "$a 小于 5 或 $b 大于 100 : 返回 false"
fi
- 支持
- 对于字符串比较
- 支持
=
、!=
!!!!!!!此处只有一个= - 支持
-z
、-n
、$
- 支持
\>
、\<
字符串排序 - 需要注意比较时字符串会默认去除引号,所以保险起见需要加上引号
a="abc"
b="efg"
if [ "$a" = "$b" ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
if [ "$a" != "$b" ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
if [ -z "$a" ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ "$a" ]
then
echo "$a : 字符串存在且不为空"
else
echo "$a : 字符串为空/不存在"
fi
- 支持
- 文件测试
-e
-r
-x
-w
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
[[]]
- 替代
[]
,在字符串、文件、正则方面 - 扩展条件测试是 Bash 的扩展测试命令,用于 字符串比较、文件测试 和 逻辑运算,比
[]
更强大。 - 支持运算符(包含
[]
)
运算符 | 说明 | 示例 |
---|---|---|
== |
字符串相等 | [[ $str == "hello" ]] |
&& |
逻辑与 | [[ $a -gt 3 && $b -lt 5 ]] |
|| | 逻辑或 | [[ $a -gt 3 ||$b -lt 5 ]] |
> |
字典序 | [[ "b" > "a" ]] |
< |
字典序 | [[ "a" < "b" ]] |
(())
- 替代
[]
,在数值比较方面 - 用于数值比较