shell基础用法

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 ,无法达到想要的效果;

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 <3));then echo bigger;else echo smaller;fi # succ ``` ### shell计算 ##### 普通计算 ```shell res=$((10+67)) num=10 let num=num+10 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命令,计算1+2+3+..+1000 echo {1..1000}|tr " " "+"|bc # []计算 echo $[10-9] # 1 ``` 需要注意的是,双小括号、let、expr、中括号只能进行整数计算,而bc可以支持小数计算。awk也可用于计算,虽然不是专门做计算的。 ```shell echo 2.4 4.5|awk '{print $1+$2}' # 6.9 ``` ### shell应用 ##### 统计字符串长度 ```shell # 方式一: name="Katherine Pierce" echo ${#name} # 方式二: echo $name|wc -L # 方式三: expr length "$name" # 方式四: echo $name|awk '{print length($0)}' ``` ##### 统计命令执行时间 ```shell time for i in {1..3000};do str1=`seq -s ":" 100`;echo ${#str1}>/dev/null;done # real 0m5.143s 实际执行时间 # user 0m3.506s 用户态执行时间 # sys 0m1.692s 内核态执行时间 ``` 一般shell内置命令和语法,执行效率最高,因为底层都是用C实现,尽量减少管道符实现; ##### 获取目录下的所有文件的完整路径 ```shell # demo.sh #!/bin/bash function get_file(){ for file in `ls $1` do dir_file=$1/$file if [ -d $dir_file ] then get_file $dir_file else echo $dir_file fi done } get_file $1 # ./demo.sh /home/uos 打印目录下所有的文件 ``` ##### 字符串截取 ```shell name="Katherine Pierce" echo ${name:2} # therine Pierce echo ${name:2:3} # the 截取3个字符 echo ${name:2:-3} # therine Pie 如果是负数,则截取到-3的位置处 name="Katherine 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按字符位置切割 ``` ##### 扩展变量 ```shell # 如果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} age=10 echo ${age:+jk} # jk # 按目录查找文件,这样实现避免dir_path变量未赋值时报错 find ${dir_path:-./} -name "*.png" ``` ### 待补充 ### 参考 1. [shell课程;](https://www.bilibili.com/video/BV1t24y1j7m8/) 2. [shell数组](https://blog.csdn.net/cailirong123/article/details/130572401)

相关推荐
独行soc1 小时前
2025年渗透测试面试题总结-字某跳动-安全研究实习生(三面)(题目+回答)
linux·服务器·安全·web安全·面试·职场和发展
爱吃烤鸡翅的酸菜鱼2 小时前
Java【网络原理】(3)网络编程续
java·运维·服务器·网络
daizikui2 小时前
LVS+Nginx接入层架构图
服务器·nginx·lvs
movee6 小时前
一台低配云主机也能轻松愉快地玩RDMA
linux·人工智能·后端
饭九钦vlog7 小时前
机器人匹诺曹机制,真话假话平衡机制
服务器·经验分享·新浪微博
kyle~7 小时前
linux根目录
linux·服务器
QuiteCoder7 小时前
【Linux】软硬连接与动静态库
linux·运维·服务器
꧁༺朝花夕逝༻꧂8 小时前
Linux基础--用户管理
linux·运维
鹿屿二向箔9 小时前
72MHz的MCU能支持多大频率的传感器数据采样率?
服务器·网络·单片机
酥暮沐9 小时前
K8S 集群搭建——cri-dockerd版
linux·容器·kubernetes