网站设计规划方案,婚庆网站建设需求分析,威海哪里可以做网站,珠海建站模板搭建shell基础知识
shell中的多行注释
:EOF
read
echo $REPLY # read不指定变量#xff0c;则默认写入$REPLY
EOF
# :EOF ...EOF 多行注释#xff0c;EOF可以替换为#xff01;# 等文件目录和执行目录
echo $0$0 # ./demo.sh
echo $0的realpath$(realpath…shell基础知识
shell中的多行注释
:EOF
read
echo $REPLY # read不指定变量则默认写入$REPLY
EOF
# :EOF ...EOF 多行注释EOF可以替换为# 等文件目录和执行目录
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 var89 # 只读变量 数组定义
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 # 遍历数组的keybaidu \n jd
for i in ${var_url_array[*]} ; do echo $i; done # 遍历数组的值www.baidu.com \n jingdong.comtest1(){echo 接收到的参数列表$newarr($)echo 新数组的值为${newarr[*]}return $newarr # 不建议这样写其实只能返回数组第一个元素的整数值
}
# shell脚本调用也不能传入数组所以建议直接在脚本中定义数组
arr(10 2 3)
test1 ${arr[*]}
echo $?#接收到的参数列表10 2 3
#新数组的值为10 2 3
#10shell内置变量
$MACHTYPE机器类型 $OSTYPE操作系统类型 $HOSTNAME当前主机名 $HOME当前用户家目录 $USER当前用户名 $UID当前用户ID $SHELL当前shell的路径 $PWD当前目录 $IFS字段分隔符 $RANDOM随机数 $SECONDSshell 脚本启动的秒数 $FUNCNAME当前函数的名称
特殊参数变量
$0 --脚本名称 $n --位置参数 $# --参数个数 $* --所有参数 $ --所有参数 不加双引号时$* 、$相同都是独立字符串加上双引号时$*是将所有参数作为整个字符串而$是将每个参数作为独立字符串
特殊状态变量
$? – 退出状态码 $! – 上一个后台运行的程序的进程id $$ – 当前脚本的pid $_ – 上一个命令的最后一个参数
shell内置命令
date
date %Y-%m-%d %H:%M:%S
# 2024-11-18 19:14:02tee
# 同时写入标准输出和文件。
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 21|tee a.txt # 将标准错误也写入a.txt文件
tee -i a.txt # 从键盘获取输入写入文件-i不会被ctrlc打断可用ctrld打断echo和printf
echo -e \n hello # 支持转义字符
echo -n hello # 不换行
printf hello \t world # printf默认支持转义默认不换行
printf %d %s %.2f 24 hello 4.5678 # 24 hello 4.57exec 和 eval
eval pwd # eval可以将字符串作为命令执行
exec date # exec 执行命令后退出相当于自动执行一次exitcat 重定向
cat b.txt EOF
first
second
third
EOFlocal
function func(){
local nameinside var
}
# 默认情况下函数内部定义的变量也属于全局变量。但是只要在变量名前加local关键字该变量就会变成局部变量。trap
用于捕获和处理信号
#!/bin/bash
# 定义错误处理函数将错误信息记录到日志文件
handle_error() {echo $(date): $BASH_COMMAND failed with exit code $?
}
# 设置 ERR 信号处理函数
trap handle_error ERR EXIT
# 其他代码逻辑
ls none.txt
# 运行 ./demo.sh
# ls: 无法访问none.txt: 没有那个文件或目录
# 2024年 11月 22日 星期五 21:30:53 CST: ls none.txt failed with exit code 0
# 2024年 11月 22日 星期五 21:30:53 CST: ls none.txt failed with exit code 0捕获了ERR信号同时也捕获了EXIT信号所以打印了2遍这里打印的退出码是0其实是因为执行$(date)命令成功。
#!/bin/bash
trap cleanup INTcleanup() {echo Caught interrupt signal. Cleaning up...
}echo Press CtrlC to interrupt me!
while true; do sleep 1; donedeclare
declare [/-] [选项] 变量名 其中表示取消设置-表示设置。 声明变量类型在默认情况下Linux中的变量是弱类型即默认都是字符串类型。使用declare可以声明变量的类型例如使用-i选项将变量作为整数处理。参考
declare -i data1 data2 res
data110
data220
res$data1$data2
echo $res # 30 如果不声明那结果是1020declare i data # 去掉整数属性
declare -r nametest # 声明只读变量
namezyy # 报错bash: name: 只读变量
readonly a1 # 也是定义只读变量declare -a arr(1 2)
#对于索引数组来说declare是否声明似乎并无差别索引数组顺序固定
declare -A b([apple]1 [boy]2 [cat]3)
# 但对于关联数组则必须使用declare -A声明关联数组顺序不定demo(){echo demo function
}
declare -f demo
# declare -f 函数名 显示函数的名称和定义代码 -F是只显示函数名称declare -x APP“mail” -x代表声明环境变量完全等同于export。
export
直接执行export命令会显示所有环境变量 export APP“mail” 其实相当于 declare -x APP“mail”设置后在当前shell及其子shell中共用该环境变量。直接定义变量a1是不能在子shell中共用的。
set
set -xe
echo $var
ls none.txt
echo hello
# 运行./demo.sh
# echo# ls none.txt
# ls: 无法访问none.txt: 没有那个文件或目录-x 代表打印每一行的执行结果 -e代表遇到错误就退出bash默认遇到错误会接着执行 还有-u如果指定了未定义的变量会报错退出
set first second third
echo $1
# 运行./demo.sh param1
# first
# set 会重新赋值给位置参数env
env --显示所有环境变量包括自己脚本中编写的export的变量 export --显示所有环境变量和env查询出的变量一致
declare --显示所有变量包括全局变量包括环境变量、局部变量 set --显示所有变量和declare查询出的变量一致
ps --forest
ps -ef --forest --展示父进程和子进程的关系
()开启子shell
利用括号开启子she11的理念以及检查在she11脚本开发中经常会用子she11进行多进程的处理提高程序并发执行效率。
echo $BASH_SUBSHELL
0 # 0表示当前shell
(pwd;echo $BASH_SUBSHELL)
/home/xxx/Desktop
1 # 1 嵌套一层shell
(pwd;(echo $BASH_SUBSHELL))
/home/xxx/Desktop
2 # 2 嵌套2层shell
{} # 代表当前shell执行tr 转换和压缩
echo 1234abcd|tr 12 34 # 3434abcd
echo 1234abcd|tr [0-9] d # ddddabcd
echo 1234abcd|tr [a-z] [A-Z] # 1234ABCD
echo 1234abcd|tr 1234 [A*]C # AAACabcd
echo 1234abcd|tr 1234 AC # ACCCabcd
echo 1234abcd|tr -t 1234 AC # AC34abcd
# 以上这种由set1转换为set2是一一对应的如果个数对不上默认重复set2的最后一个字符。加上-t可以避免重复而不替换;echo 1234abcd|tr -d [:digit:] # abcd
echo 1234abcd|tr -dc [:digit:] # 1234
# -d 删除匹配的字符-dc 保留匹配的字符相当于反选并且-c删除了末尾的换行符echo aaa123bbbb123|tr -s ab # a123b123
echo aaa123bbbb123|tr -s 123 ccc # aaacbbbbc
# -s 代表压缩第一个命令是对a和b字符压缩第二个命令是先将123替换为ccc再对ccc字符压缩mkdir
mkdir a/{b, c} 指定目录下同时创建多个文件夹mkdir -p xx/xxx 代表无父目录可直接创建
解压和压缩
tar czf a.tar.gz 1.txt 2.txttar xzf a.tar.gz -C 目录 都可以加-v显示具体过程
sort和uniq
cat file|sort # 默认按ASCII码排序
cat file|sort -u # 去重排序
echo -e 2\n1\n-9|sort -n # 按数字排序
sort -r # 反向排序
sort -k2 file # 按第二列排序
uniq # 按行去重只会对相邻重复的行去重
uniq -d file # 列出重复的行
uniq -u file # 列出不重复的行
uniq -c # 统计行的重复次数
# 实现对文件中获取重复行的重复次数
sort example.txt | uniq -ic # -i 不区分大小写curl
curl -s -I http://example.com | grep HTTP
# -s 安静模式不打印错误信息、进度信息、网速等
# -I 发送一个 HEAD 请求仅请求页面的 HTTP 头部信息当仅需检查状态码时HTTP/1.1 200 OK可使用此命令。shell内置和外置命令
内置命令通过compgen -b 查看 “type 命令” 可以判断是内置还是外置命令 内置命令在系统启动时就加载入内存常驻内存执行效率更高但是占用资源如pwd 外置命令系统需要从硬盘中读取程序文件再读入内存加载一定会开启子进程执行
shell循环
# 循环读取test.txt中的每一行
while read x
doecho input is $x
donetest.txtuntil [ ${i:0} -gt 10 ]
dolet iecho $i
done # 1 2 ... 10 11while循环在条件为真时继续执行条件为假时停止。 until循环在条件为假时继续执行条件为真时停止。
for((i0;i5;i));do echo $i;done
for i in {0..4};do echo $i;done
for i in $(seq 0 4);do echo $i;done
for i in 0 1 2 3 4;do echo $i;done
# 0 1 2 3 4num3
if (($num3));then echo succ;elif (($num3));then echo bigger;else echo smaller;fi
# succshell计算
普通计算
res$((1067))
num10
let numnum10
echo $num # 20
expr 10 9 # 19
# expr支持模式匹配判断是否以.jpg为后缀返回非0就是符合要求的冒号代表计算匹配的字符长度
expr taohua.jpg : .*\.jpg # 10
expr taohua.jpg : .* # 10
expr length taohua.jpg # 10
# bc命令计算123..1000
echo {1..1000}|tr |bc
# []计算
echo $[10-9] # 1需要注意的是双小括号、let、expr、中括号只能进行整数计算而bc可以支持小数计算。awk也可用于计算虽然不是专门做计算的。
echo 2.4 4.5|awk {print $1$2} # 6.9shell应用
统计字符串长度
# 方式一
nameKatherine Pierce
echo ${#name}# 方式二
echo $name|wc -L# 方式三
expr length $name# 方式四
echo $name|awk {print length($0)}统计命令执行时间
time for i in {1..3000};do str1seq -s : 100;echo ${#str1}/dev/null;done
# real 0m5.143s 实际执行时间
# user 0m3.506s 用户态执行时间
# sys 0m1.692s 内核态执行时间一般shell内置命令和语法执行效率最高因为底层都是用C实现尽量减少管道符实现
获取目录下的所有文件的完整路径
# demo.sh
#!/bin/bashfunction get_file(){for file in ls $1dodir_file$1/$fileif [ -d $dir_file ]thenget_file $dir_fileelseecho $dir_filefidone
}
get_file $1# ./demo.sh /home/uos 打印目录下所有的文件字符串截取
nameKatherine Pierce
echo ${name:2} # therine Pierce
echo ${name:2:3} # the 截取3个字符
echo ${name:2:-3} # therine Pie 如果是负数则截取到-3的位置处
nameKatherine therce
echo ${name#*th} # erine therce 左边开始匹配删除最短匹配
echo ${name##*th} ## erce 左边开始匹配删除最长匹配
echo ${name%th*} ## Katherine 右边开始匹配删除最短匹配
echo ${name%%th*} ## Ka 右边开始匹配删除最长匹配
echo ${name/th/boy} ## 仅替换第一个Kaboyerine therce
echo ${name//th/boy} ## 替换所有匹配Kaboyerine boyerce
# cut命令也可用于截取字符
echo $name|cut -c 3-5 # the -c按字符位置切割扩展变量
# 如果param变量为空则word赋给$res不会给$param注意如果param不为空则不进行相关处理
res${param:-word}
# 这里的冒号可以省略有时候看到这样的写法也是可以的 ${BASE_SOURCE-$0}# 如果param变量为空则word赋给$res和$param注意如果param不为空则不进行相关处理
res${param:word}# 如果param变量为空word作为stderr错误输出否则输出变量值 ${param:?word}
${age:?无变量错误}
# bash: age: 无变量错误# 如果param变量为空什么都不做否则word返回 ${param:word}
age10
echo ${age:jk}
# jk# 按目录查找文件这样实现避免dir_path变量未赋值时报错
find ${dir_path:-./} -name *.png待补充
参考
shell课程shell数组