Shell语言
定义
- Shell:计算机壳层,区别于“计算机内核”。指“为使⽤者提供操作界⾯”的软件,⽤于接收⽤⼾命
令,调⽤相应的应⽤程序。
- Shell脚本:为shell设计的⼀种脚本语⾔,⽅便进⾏复杂逻辑的shell命令的调⽤。
语法
hello world
echo 'hello world'
echo "hello world"
var="hello world"
echo $var
- 赋值号=左右不能有空格
单引号与双引号的区别
var="world"
echo "hello $var"
echo 'hello $var'
- 单引号原样输出字符串,双引号会解析变量
将命令的结果赋值给变量
- 反引号 ``
- $()
var=`cat hhh.txt`
var=$(cat hhh.txt)
只读变量
readonly常量
#!/bin/bash
const="const"
readonly const
const="var"
- 不能修改常量
删除变量
var="hello"
echo $var
>>hello
unset var
echo $var
>>
变量作用域
全局变量
- 可以在当前shell会话中使⽤
#!/bin/bash
function func(){
var="hello"
}
func
echo $var
变量var在函数外仍能读取
局部变量
- 只能在函数内部使⽤
#!/bin/bash
function func(){
local var="hello"
}
func
echo $var
环境变量
var="hello"
export var
- export的变量仅在当前shell和子shell中可见,需要在任何shell中可见需要修改环境变量参数
位置参数
shell脚本使⽤$n的形式接收调⽤脚本时给脚本传递的参数,这种变量形式叫做位置参数
#!/bin/bash
echo $1 $2 $3
- shell脚本的函数使用位置参数代替形参实参的功能
#!/bin/bash
function func(){
echo $1
}
func "123"
shell脚本中的特殊变量
| 变量 | 含义 |
|---|---|
| $0 | 当前脚本的文件名 |
| $n(n≥1) | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。 |
| $# | 传递给脚本或函数的参数个数。 |
| $* | 传递给脚本或函数的所有参数。 |
| $@ | 传递给脚本或函数的所有参数。当被双引号” “包含时,$@ 与 $* 稍有不同,我们将在《Shell $*和$@的区别》一节中详细讲解。 |
| $? | 上个命令的退出状态,或函数的返回值,我们将在《Shell $?》一节中详细讲解。 |
| $$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
$*和$@的区别
当 $* 和 $@ 不被双引号” “包围时,它们之间没有任何区别,都是将接收到的每个参数看做⼀份数据,彼此之间以空格来分隔。
但是当它们被双引号” “包含时,就会有区别了:
- ”$*“会将所有的参数从整体上看做⼀份数据,⽽不是把每个参数都看做⼀份数据。
- ”$@”仍然将每个参数都看作⼀份数据,彼此之间是独⽴的。
#!/bin/bash
echo 'print each param from $*'
for var in "$*"
do
echo "$var"
done
echo 'print each param from $@'
for var in "$@"
do
echo "$var"
done
字符串
获取字符串长度
${#string_name}
var=hello
echo ${#var}
字符串截取
| 格式 | 说明 |
|---|---|
| ${string: start :length} | 从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。0起始 |
| ${string: start} | 从 string 字符串的左边第 start 个字符开始截取,直到最后。0起始 |
| ${string: 0-start :length} | 从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。1起始 |
| ${string: 0-start} | 从 string 字符串的右边第 start 个字符开始截取,直到最后。1起始 |
| ${string#*chars} | 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。星号是通配符,表示任意长度字符串 |
| ${string##*chars} | 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。 |
| ${string%*chars} | 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
| ${string%%*chars} | 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。 |
数组
定义
arr=(20 56 "shell")
nums[6]=88
ages=([3]=24 [5]=19 [10]=12)
使用数组
- 获取数组元素
${array_name[index]}
- 获取全部元素
${nums[*]}
${nums[@]}
- 获取数组长度
${#nums[*]}
${#nums[@]}
- 拼接合并数组
array_new=(${array1[@]} ${array2[@]})
array_new=(${array1[*]} ${array2[*]})
- 删除数组/数组元素
unset array_name[index]
unset array_name
循环
- 迭代器形式
#!/bin/bash
arr=(1 2 3 4 5 6 7 8 9)
for item in ${arr[@]}
do
echo $item
done
- while
#!/bin/bash
i=0
sum=0
while((i < 10))
do
((sum=sum+i))
((i++))
done
echo $sum
#!/bin/bash
index=0
arr=(1 2 3 4 5 6 7 8 9)
while ((index < ${#arr[*]}))
do
echo ${arr[index]}
((index++))
done
- until
#!/bin/bash
i=0
sum=0
until ((i>=10))
do
((sum=sum+i))
((i=i+1))
done
echo $sum
内建命令
- 由bash自身提供的命令,而不是文件系统中的某个可执行文件
- 类似于关键字保留字
| bash | : | . | [ | alias | bg | bind |
| break | builtin | cd | command | compgen | complete | continue |
| declare | dirs | disown | echo | enable | eval | return |
| exec | exit | export | fc | fg | getopts | set |
| hash | help | history | jobs | kill | let | shift |
| local | logout | popd | printf | pushd | pwd | shopt |
| read | readonly | source | suspend | test | times | trap |
| type | typeset | ulimit | umask | unalias | unset | wait |
数学计算
| 运算操作符/运算命令 | 说明 |
|---|---|
| (( )) | 用于整数运算,效率很高,推荐使用。 |
| let | 用于整数运算,和 (()) 类似。 |
| [$] | 用于整数运算,不如 (()) 灵活。 |
| expr | 可用于整数运算,也可以处理字符串。比较麻烦,需要注意各种细节,不推荐使用。 |
| bc | Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。 |
| declare -i | 将变量定义为整数,然后再进行数学运算时就不会被当做字符串了。功能有限,仅支持最基本的数学运算(加减乘除和取余),不支持逻辑运算、自增自减等,所以在实际开发中很少使用。 |
if语句
#!/bin/bash
read a
read b
if (($a == $b))
then
echo "a == b"
else
echo "a != b"
fi
#!/bin/bash
read a
if (($a == 1)); then
echo "one"
elif (($a == 2)); then
echo "two"
elif (($a == 3)); then
echo "three"
fi
test命令
test expression
简写等同于
[ expression ]
- 比较符号
1. #!/bin/bash
2. read age
3. if test $age -le 2; then
4. echo "婴儿"
5. elif test $age -ge 3 && test $age -le 8; then
6. echo "幼儿"
7. elif [ $age -ge 9 ] && [ $age -le 17 ]; then
8. echo "少年"
9. elif [ $age -ge 18 ] && [ $age -le 25 ]; then
10. echo "成年"
11. elif test $age -ge 26 && test $age -le 40; then
12. echo "青年"
13. elif test $age -ge 41 && [ $age -le 60 ]; then
14. echo "中年"
15. else
16. echo "老年"
17. fi
test相关选项
| 文件类型判断 | |
|---|---|
| 选 项 | 作 用 |
| -b filename | 判断文件是否存在,并且是否为块设备文件。 |
| -c filename | 判断文件是否存在,并且是否为字符设备文件。 |
| -d filename | 判断文件是否存在,并且是否为目录文件。 |
| -e filename | 判断文件是否存在。 |
| -f filename | 判断文件是否存在,井且是否为普通文件。 |
| -L filename | 判断文件是否存在,并且是否为符号链接文件。 |
| -p filename | 判断文件是否存在,并且是否为管道文件。 |
| -s filename | 判断文件是否存在,并且是否为非空。 |
| -S filename | 判断该文件是否存在,并且是否为套接字文件。 |
| 文件权限判断 | |
| 选 项 | 作 用 |
| -r filename | 判断文件是否存在,并且是否拥有读权限。 |
| -w filename | 判断文件是否存在,并且是否拥有写权限。 |
| -x filename | 判断文件是否存在,并且是否拥有执行权限。 |
| -u filename | 判断文件是否存在,并且是否拥有 SUID 权限。 |
| -g filename | 判断文件是否存在,并且是否拥有 SGID 权限。 |
| -k filename | 判断该文件是否存在,并且是否拥有 SBIT 权限。 |
| 文件比较 | |
| 选 项 | 作 用 |
| filename1 -nt filename2 | 判断 filename1 的修改时间是否比 filename2 的新。 |
| filename -ot filename2 | 判断 filename1 的修改时间是否比 filename2 的旧。 |
| filename1 -ef filename2 | 判断 filename1 是否和 filename2 的 inode 号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
与数值比较相关的 test 选项
| 选 项 | 作 用 |
|---|---|
| num1 -eq num2 | 判断 num1 是否和 num2 相等。 |
| num1 -ne num2 | 判断 num1 是否和 num2 不相等。 |
| num1 -gt num2 | 判断 num1 是否大于 num2 。 |
| num1 -lt num2 | 判断 num1 是否小于 num2。 |
| num1 -ge num2 | 判断 num1 是否大于等于 num2。 |
| num1 -le num2 | 判断 num1 是否小于等于 num2。 |
与字符串判断相关的 test 选项
| 选 项 | 作 用 |
|---|---|
| -z str | 判断字符串 str 是否为空。 |
| -n str | 判断宇符串 str 是否为非空。 |
| str1 = str2 str1 == str2 | =和==是等价的,都用来判断 str1 是否和 str2 相等。 |
| str1 != str2 | 判断 str1 是否和 str2 不相等。 |
| str1 > str2 | 判断 str1 是否大于 str2。\>是>的转义字符,这样写是为了防止>被误认为成重定向运算符。 |
| str1 < str2 | 判断 str1 是否小于 str2。同样,\<也是转义字符。 |
与逻辑运算相关的 test 选项
| 选 项 | 作 用 |
|---|---|
| expression1 -a expression | 逻辑与,表达式 expression1 和 expression2 都成立,最终的结果才是成立的。 |
| expression1 -o expression2 | 逻辑或,表达式 expression1 和 expression2 有一个成立,最终的结果就成立。 |
| !expression | 逻辑非,对 expression 进行取反。 |
文档信息
- 本文作者:Ling He
- 本文链接:https://GoggleHe.github.io/2024/03/03/Shell/
- 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)