shell基础知识
shell中的多行注释
shell
:<<EOF
read
echo $REPLY # read不指定变量,则默认写入$REPLY
EOF
# :<<EOF ...EOF 多行注释,EOF可以替换为!# 等
文件目录和执行目录
shell
echo '$0='$0 # ./demo.sh
echo '$0的realpath='$(realpath $0) # 完整路径
echo '$0的父目录='$(dirname $(realpath $0)) # 文件的父目录
echo "BASH_SOURCE="${BASH_SOURCE} # ./demo.sh
echo "BASH_SOURCE的realpath="$(realpath ${BASH_SOURCE}) # 完整路径
echo '文件执行目录:'`pwd` # 执行目录
当使用bash或./执行时,0和{BASH_SOURCE}是一样的,但是通过.或source命令执行脚本时,$0就变为了/bin/bash ,无法达到想要的效果;
- BASH_SOURCE
如果你有一个脚本 script1.sh 调用了 script2.sh,而 script2.sh 又调用了 script3.sh,那么在 script3.sh 中,BASH_SOURCE 数组将包含以下路径:
BASH_SOURCE[0] 将是 script3.sh 的路径。
BASH_SOURCE[1] 将是 script2.sh 的路径。
BASH_SOURCE[2] 将是 script1.sh 的路径。
shell变量
变量赋值
var='hello word'
unset var # 删除变量,不能删除只读变量
readonly var=89 # 只读变量
数组定义
shell
var_array=(value1 value2 value3) # 普通数组
declare -A var_url_array=(['baidu']='www.baidu.com' ['taobao']='www.taobao.com' ['jd']='jingdong.com') # 关联数组
echo ${var_array} # value1
echo ${var_url_array} # 空
echo ${var_array[1]} # value2
echo ${var_url_array["taobao"]} # www.baidu.com
echo ${var_array[*]} # value1 value2 value3
echo ${var_array[@]} # value1 value2 value3
echo ${var_url_array[*]} # www.baidu.com jingdong.com www.taobao.com
echo ${var_url_array[@]} # www.baidu.com jingdong.com www.taobao.com
echo ${#var_array[1]} # 6 计算数组下标元素的长度
echo ${#var_array[*]} # 3 计算数组的长度
echo ${#var_url_array[*]} # 3
echo ${#var_url_array["taobao"]} # 14
echo ${!var_array[*]} # 0 1 2 获取数组的key
echo ${!var_url_array[*]} # baidu jd taobao 获取数组的key
echo ${var_array[@]:0:2} # value1 value2 切片访问,从0下标开始,长度是2
echo ${var_url_array[@]:1:2} # www.baidu.com jingdong.com
echo ${var_array[@]/value/num} # num1 num2 num3 数组内容替换
echo ${var_url_array[@]/www/} # .baidu.com jingdong.com .taobao.com
# 以上4条命令,同样可以指定下标,就是对数组下标元素操作
unset var_array[0]
echo ${var_array[*]} # value2 value3
unset var_url_array["taobao"]
echo ${var_url_array[*]} # www.baidu.com jingdong.com
# 需要注意的是,var_array删除下标0之后,并不会重置下标
echo ${!var_array[*]} # 1 2
var_array[7]=78
echo ${!var_array[*]} # 1 2 7
echo ${var_array[*]} # value2 value3 78
var_array+=(10 20)
echo ${var_array[*]} # value2 value3 78 10 20
var_array=(${var_array[*]} 1 2 3)
echo ${var_array[*]} # value2 value3 78 10 20 1 2 3
unset var_array # 删除整个数组
for i in ${!var_url_array[*]} ; do echo $i; done # 遍历数组的key:baidu \n jd
for i in ${var_url_array[*]} ; do echo $i; done # 遍历数组的值:www.baidu.com \n jingdong.com
shell
test1(){
echo "接收到的参数列表:$@"
newarr=($@)
echo "新数组的值为:${newarr[*]}"
return $newarr # 不建议这样写,其实只能返回数组第一个元素的整数值
}
# shell脚本调用也不能传入数组,所以建议直接在脚本中定义数组
arr=(10 2 3)
test1 ${arr[*]}
echo $?
#接收到的参数列表:10 2 3
#新数组的值为:10 2 3
#10
shell内置变量
$MACHTYPE:机器类型
$OSTYPE:操作系统类型
$HOSTNAME:当前主机名
$HOME:当前用户家目录
$USER:当前用户名
$UID:当前用户ID
$SHELL:当前shell的路径
$PWD:当前目录
$IFS:字段分隔符
$RANDOM:随机数
$SECONDS:shell 脚本启动的秒数
$FUNCNAME:当前函数的名称
特殊参数变量
$0 --脚本名称
$n --位置参数
$# --参数个数
$* --所有参数
$@ --所有参数;
不加双引号时,\* 、@相同,都是独立字符串;加上双引号时,\*是将所有参数作为整个字符串,而@是将每个参数作为独立字符串;
特殊状态变量
$? -- 退出状态码
$! -- 上一个后台运行的程序的进程id
-- 当前脚本的pid
$_ -- 上一个命令的最后一个参数
### shell内置命令
##### date
```shell
date +'%Y-%m-%d %H:%M:%S'
# 2024-11-18 19:14:02
```
##### tee
```shell
# 同时写入标准输出和文件。
echo "hello"|tee a.txt # 写入a.txt文件,同时也会到标准输出,-a参数代表追加;
echo "hello world"|tee a.txt b.txt c.txt # 同时重定向到多个文件;
lsblk|tee a.txt > /dev/null # 这样可以不到标准输出
lsblk 2>&1|tee a.txt # 将标准错误也写入a.txt文件;
tee -i a.txt # 从键盘获取输入写入文件,-i不会被ctrl+c打断,可用ctrl+d打断;
```
##### echo和printf
```shell
echo -e "\n hello" # 支持转义字符
echo -n "hello" # 不换行
printf "hello \t world" # printf默认支持转义,默认不换行
printf "%d %s %.2f" 24 hello 4.5678 # 24 hello 4.57
```
##### exec 和 eval
```shell
eval "pwd" # eval可以将字符串作为命令执行
exec date # exec 执行命令后退出,相当于自动执行一次exit
```
##### cat 重定向
```shell
cat > b.txt <