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)

相关推荐
watl05 分钟前
【Android】unzip aar删除冲突classes再zip
android·linux·运维
赵大仁40 分钟前
在 CentOS 7 上安装 Node.js 20 并升级 GCC、make 和 glibc
linux·运维·服务器·ide·ubuntu·centos·计算机基础
vvw&1 小时前
Docker Build 命令详解:在 Ubuntu 上构建 Docker 镜像教程
linux·运维·服务器·ubuntu·docker·容器·开源
冷冰鱼1 小时前
【问题实录】服务器ping不通win11笔记本
运维·服务器
wayuncn1 小时前
web服务器之云主机、物理机租用、服务器托管的区别
运维·服务器
冷曦_sole1 小时前
linux-21 目录管理(一)mkdir命令,创建空目录
linux·运维·服务器
最后一个bug1 小时前
STM32MP1linux根文件系统目录作用
linux·c语言·arm开发·单片机·嵌入式硬件
聚名网1 小时前
服务器如何划分空间?
运维·服务器
dessler2 小时前
Docker-Dockerfile讲解(二)
linux·运维·docker
卫生纸不够用2 小时前
子Shell及Shell嵌套模式
linux·bash