shell基础

本文详细介绍了Shell脚本的基础知识,包括基本语法、变量类型、环境变量管理、数值计算、条件比较、循环语句、函数和数组的使用。重点讲解了变量处理、算术运算符、shebang(解释器指令)以及如何在不同环境下检测和使用子shell。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Shell脚本基础

1.shell基本语法

shell脚本语言属于弱类型语言,无需声明变量类型,直接定义使用。

  • Windows中存在.bat批处理文件
  • Linux中常用*.sh脚本文件

shell编程,尽量使用linux内置的命令,内置的操作,和内置的函数,效率最高,尽可能减少管道符的操作

  • 每次调用bash/sh解释器执行脚本,都会开启一个子shell,因此不保留当前的shell变量
  • 调用source或者点 .符号,只在当前shell环境加载脚本,因此保留变量
  • 通过./script去执行脚本,是指定shebang,通过解释器运行,也是开启子shell运行命令

Shebang

#Shebang指的是文本文件的第一行前两个字符 #!
在Unix系统中,程序会分析shebang后面的内容,作为解释器的指令,例如
  • 以#!/bin/sh开头的文件,程序在执行时会调用/bin.sh,也就是bash解释器

  • 以#!/usr/bin/python开头的文件,代表指定python解释器去执行

  • 以#!/usr/bin/env解释器名称,是一种在不同平台上都能正确找到解释器的办法

  • 可以通过pstreeps -ef -forest命令检查进程树

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

()小括号里面的命令表示在子shell执行

检测是否在子shell环境中
$BASH_SUBSHELL          #返回0,表示命令在当前shell环境执行的,返回其n,表示在当前shell下的第n个子shell执行的

2.变量

环境变量

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

检查系统环境变量的命令
set          #输出当前shell会话的所有变量
env         #只显示全局变量
declare   #输出所有变量,像set
export    #显示和设置环境变量
expr       #进行数值和字符串表达式的求值和处理

撤销环境变量的命令
unset name  #删除变量或函数name

设置只读变量
readonly   #当前shell结束,只读变量失效

引号变量
''    #单引号变量,不识别特殊语法
""   #双引号变量,能识别特殊符号
``    #执行命令,并将命令的输出作为字符串插入到命令行中或者赋值给变量
  • 每个用户都有自己的环境配置文件,~/.bash_profile ,~/.bashrc,且以个人配置文件,优先加载变量,读取,以个人的优先生效
  • 当你需要给所有用户都使用某个变量,写入全局即可/etc/profile

环境变量初始化与加载顺序

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

位置参数变量

shell的位置参数变量,用在如脚本,函数传递参数使用

$0   #获取shell脚本文件名,以及脚本路径
$n   #获取shell脚本的第n个参数,n在1~9之间,大于9要写,${10},参数空格隔开
$#   #获取执行的shell脚本后面的参数总个数
$*    #获取shell脚本所有参数
$@  #获取shell脚本所有参数

#不加" "时,$*和$@没有区别,加" "时
$*的作用是接收所有参数为单个字符串
$@的作用是接收所有参数为独立字符串

特殊状态变量

脚本执行完毕后会返回一个数字id,称为返回值

$?   #上一个命令执行状态返回值,0成功,非0失败
$$   #当前shell脚本的进程号
$!   #获取上一次后台进程的PID
$_   #取得上一次执行的命令的最后一个参数

man bash   
搜索Special Parameters  #查找使用手册

基础语法

${变量}     #返回变量值
${#变量}    #返回变量长度,字符长度
${变量:start}  #返回变量 start数值 之后的字符,且包含start的数字
${变量:start:length}  #提取start之后的 length 限制的字符

#删除
${变量#word}   #从变量开头删除最短匹配的word子串
${变量##word}  #从变量开始,删除最长匹配的word
${变量%word}   #从变量结尾删除最短匹配的word
${变量%%word}  #从变量结尾删除最长匹配的word

#替换
${变量/pattern/string}   #用string代替第一个匹配的pattern
${变量//pattern/string}  #用string代替所有的pattern
变量的处理
${var:-word}  #如果var不存在或为空,则返回默认值word
${var:=word}  #如果var不存在或为空,则将其赋值为默认值word
${var:+word}  #如果var不存在或为空,不输出任何内容,否则输出word
${var:?word}  #如果var为空,word当作错误信息输出,否则输出变量值,用于设置变量为空导致错误时,返回的错误信息

特殊符号

${vars}   #取出变量结果
$()         #再括号中执行命令,且拿到命令的执行结果
``           #再括号中执行命令,且拿到命令的执行结果
( )          #开启子zhell执行结果
$vars     #取出变量结果

3.数值计算

Shell中常见的算术运算符号

算术运算符意义(*表示常用)
+、-加法(或正号)、减法(或负号)*
*、/、%乘法、除法、取余(取模)*
**幂运算*
++、–增加或减少,可前置也可放在变量结尾*
!、&&、||逻辑非(取反)、逻辑与(and)、逻辑或(or)*
<、<=、>、>=比较符号(小于、小于等于、大于、大于等于)
==、!=、=比较符号(相等、不相等、对于字符串"="也可以表示相当于)*
<<、>>向左位移,向右位移
~、|、&、^按位取反、按位异或、按位与、按位或
=、+=、-=、*=、/=、%=赋值运算符,例如a+=1相当于a=a+1*
++a  #先计算+1,然后再赋值给a
a++  #先对变量a进行操作,再进行+1

Shell中常见的算术运算符命令

运算操作符与运算命令意义
( ( ) )用于整数运算的常用运算符,效率很高
let用于整数运算,类似于“( ( ) )”
expr可用于整数运算,当还有很多其他额外的功能
bcLinux下的一个计算机程序(适合整数及小数运算)
$[ ]用于整数运算
awkswk既可以用于整数运算,也可以用于小数运算
declare定义变量值和属性,-i参数可以用于定义整形变量,做运算

双小括号“(( ))”的操作方法

运算操作符与运算命令意义
((i=i+1))此种书写方法与运算后赋值法,即将i+1的运算结果赋值给变量i。注意,不能用"echo ((i=i+1))"的形式输出表达式的值
i=$((i+1))可以在"(( ))"前加$符,表示将表达式运算后赋值给i
((8>7&&5==5))可以进行比较操作,还可以加入逻辑与和逻辑或,用于条件判断
echo $((2+1))需要直接输出运算表达式的运算结果时,可以在“(( ))”前加$符

expr计算

可以执行基本数学运算和字符串处理的命令
#计算处理
result=$(expr 10 + 5)
echo $result   # 输出 15
result=$(expr 10 \> 5)
echo $result   # 输出 1

#字符串处理
length=$(expr length "Hello, World!")
echo $length   # 输出 13
length (计算字符串长度)
index(查找子字符串的位置)
substr(截取子字符串)

#模式匹配(正则表达式)
:    #冒号,计算字符串的字符数量
.*   #任意的字符串重复0次或者多次
使用方式
expr 字符串 ":" ".*"

let计算

#执行算术表达式并将结果赋值给变量
num1=10
num2=20
let sum=num1+num2
echo $sum   # 输出 30
#shell不支持直接运算,必须加let

awk计算

echo "3.2 2.2" | awk '{print $1+$2}'
# 5.4
echo "3.2 2.2" | awk '{print ($1+4*$2)}'
# 12

中括号计算

num=5
res=$[num+4]  # 9
res=$[num*4]  # 20
res=[num%4]   # 1

计算{1…100}之和

#bc计算
echo {1..100}|tr " " "+"|bc

#seq计算
seq -s "+" 100|bc

#(( ))计算
echo $((`seq -s "+" 100`))

#expr计算,expr是接收多个参数计算的
#expr接受以空格分割的,多个参数
#Linux下构造参数命令 xargs
seq -s " + " 100 | xargs expr

4.条件比较

1.条件测试

条件测试语法说明
语法1:text<表达式>这是利用test命令进行条件测试表达式的方法,test命令和“<测试表达式>”之间至少有一个空格
语法2:[<表达式>]这是通过单中括号进行条件测试表达式的方法,和test命令的用法相同,[]的边界和内容之间至少有一个空格
语法3:[[<表达式>]]这是通过双中括号进行条件测试表达式的方法,是比test和单中括号更新的语法格式。它的边界和内容之间至少有一个空格
语法4:((<表达式>))这是通过(( ))双小括号进行条件测试表达式的方法,一般用于if语句里,它两端不需要有空格

text命令测试评估一个表达式,如果条件为真,那么命令执行状态码结果就为0,否则就是不为0,可通过$?取值

  • A && B,当A成立,并且执行B
  • A | | B,当A不成立的时候,才会执行B
语法参数:
. 关于某个文件名的【类型】侦测(存在与否)
#针对文件类型判断真假
-e  该【文件名】是否存在?
-f  该【文件名】是否为文件(file)-d  该【文件名】是否为目录(directory)#判定字符串的数据
-z  字符串为空,就为真,否则为假
-n  字符串有内容,为真,否则为假
#查看是否有文件执行权限
-w  侦测该文件名是否有【可写】的属性
-r  侦测该文件名是否有【可读】的属性
-x  侦测该文件名是否有【执行】的属性
  • 条件测试中使用变量,必须添加双引号
  • 中括号,前后的空格必须有
  • ls /etc/init.d/查看sehll自带的脚本,学习大神如何写脚本

2.字符串比较测试

常用字符串测试操作符说明
-n"字符串"若字符串的长度不为0,则为真,即表达式成立,n = no zero
-z"字符串"若字符串的长度为0,则为真,即表达式成立,z = zero
“串1” = “串2”若字符串1等于字符串2,则为真,即测试表达式成立,可用“==”代替“=”
“串1” != “串2”若字符串1不等于字符串2,则为真,即表达式成立,但不能用“!==”代替“!=”
=      #判断是否相等
!=   #判断是否不等
!     #非,与结果的反义
  • 对于字符串变量的比较
  • 变量要添加双引号
  • 使用=号的值判断时,=左右两边也必须有空格

3.数值比较测试

在[]以及text中使用的比较符号在(( ))和[[]]使用的比较符号说明
-eq==或=相等,全拼为equal
-ne!=不相等,全拼为not equal
-gt>大于,全拼为greater than
-ge>=大于等于,全拼为greater equal
-lt<小于,全拼为less than
-le<=小于等于,全拼为less equal
#在中括号中,使用数学比较符号,要在前面添加转移符号
在text和[]语法中,支持-eq此类写法,以及支持> < = !=

#双中括号是对单中括号的补充,它还支持正则处理
在双中括号中,不需要转移符号了

逻辑判断符号

在[ ]和test中使用的操作符在[[ ]]和(( ))中使用的操作符说明
-a&&and,与,两端都为真,则结果为真
-o| |or,或,两端有一个为真,则结果为真
!!not,非,两端相反,则结果为真

4.各测试表达式符号的对比

测试表达式符号text[ ][[ ]](( ))
边界是否需要空格需要需要需要不需要
逻辑操作符!、-a、-o!、-a、-o!、&&、||!、&&、||
整数比较操作符-eq、-gt、-ge、-lt、-le-eq、-gt、-ge、-lt、-le-eq、-gt、-ge、-lt、-le或=、>、>=、<、<==、>、>=、<、<=
字符串比较操作符=、==、!==、==、!==、==、!==、==、!=
是否支持通配符匹配不支持不支持支持不支持

5.语句

循环语句

for循环

#用于迭代遍历一个列表或集合,并执行相应的操作
for 变量名 in 列表
do
    循环体,执行相应的操作
done

while循环

#在条件为真时循环执行一段代码块,直到条件为假为止
while 条件
    do
       命令
done 

until循环

#当条件为假时循环执行一段代码块,直到条件为真为止
until 条件
     do
        命令
done

条件语句

if语句

#[ ] 左右两边都要有空格
if [ xx ]
    then
       执行条件为真时的命令或代码块
     elif  #或者
       执行条件为真时的命令或代码块
      fi
     else
       执行条件为假时的命令或代码块
fi
参数:
-n  #对字符串判断,如果字符串为空,条件不成立
-ne #不等于的意思
-le #小于等于
-lt #小于

case语句

#根据变量的不同取值执行不同的代码块,类似于多分支的条件判断。
case 变量 in
模式1)
    # 模式1匹配时执行的代码
    ;;
模式2)
    # 模式2匹配时执行的代码
    ;;
*)
    # 所有模式都不匹配时执行的代码
    ;;
esac

6.函数和数组

函数

函数的特点,类似alias别名一样,可以简化Linux命令的操作,让整个命令更易读,更易用

  • 函数,就是将需要执行的shell命令组合起来,成一个函数体
  • 还得给这个函数体起一个名字,称为函数名
  • 以后想执行这个函数,就调用函数名
  • 使用函数,可以增加程序可读性,易读性,容易管理
  • 将相同的程序,定义,封装成一个函数,能够减少程序的代码数量,提高开发效率
# 标准shell函数定义
function 函数名( ){
     函数体
     return 返回值
}

#偷懒写法,当使用function关键字时候,可以省略括号
function 函数名( ){
     函数体
     return 返回值
}

#超级懒人写法,必须有括号
函数名( ){
    函数体
    return 返回值
}
  • 执行shell函数,直接写函数名即可,无需添加其他内容
  • 函数必须先定义再执行,shell脚本自上而下加载
  • 函数体内定义的变量,称为局部变量
  • 函数体内需要添加return语句,作用是退出函数,且赋予返回值给调用该函数的程序,也就是shell脚本
  • return语句和exit不同(return只能写在函数中,exit是shell内置命令,用于退出shell环境)
    • return是结束函数的执行,返回一个值
    • exit是结束shell环境,返回一个值给当前的sehll
  • 函数如果单独写入一个文件里,需要用source读取
  • 函数内,使用local关键字,定义局部变量

数组

一维数组

# 声明数组
fruits=("apple" "banana" "orange" "grape")

# 访问数组元素
echo ${fruits[0]}   # 输出 "apple"
echo ${fruits[1]}   # 输出 "banana"

# 获取数组长度
echo ${#fruits[@]}  # 输出 4

# 输出所有数组元素
for i in "${fruits[@]}"
do
  echo $i
done

关联数组

不同于普通的索引数组,关联数组的元素是通过键来访问而不是通过索引

# 用declare -A 声明关联数组colors
declare -A assoc_array

# 或者直接赋值
assoc_array=([key1]=value1 [key2]=value2 [key3]=value3)

# 给关联数组赋值
assoc_array[key4]=value4

# 访问关联数组元素
echo ${assoc_array[key1]}  # 输出 "value1"

# 获取关联数组长度
echo ${#assoc_array[@]}    # 输出关联数组元素的个数

# 输出所有关联数组元素
for key in "${!assoc_array[@]}"
do
  echo "$key: ${assoc_array[$key]}"
done
  • 在声明关联数组时,需要使用declare -A命令进行声明,表示这是一个关联数组。
  • 赋值给关联数组时,可以使用[key]=value的语法,或者直接在声明时赋值。
  • 当访问关联数组的元素时,使用${assoc_array[key]}的语法,其中key是要访问的键。
  • 使用${!assoc_array[@]}可以获取关联数组所有的键。

ay

或者直接赋值

assoc_array=([key1]=value1 [key2]=value2 [key3]=value3)

给关联数组赋值

assoc_array[key4]=value4

访问关联数组元素

echo ${assoc_array[key1]} # 输出 “value1”

获取关联数组长度

echo ${#assoc_array[@]} # 输出关联数组元素的个数

输出所有关联数组元素

for key in “ ! a s s o c a r r a y [ @ ] " d o e c h o " {!assoc_array[@]}" do echo " !assocarray[@]"doecho"key: KaTeX parse error: Expected '}', got 'EOF' at end of input: {assoc_array[key]}”
done


- 在声明关联数组时,需要使用`declare -A`命令进行声明,表示这是一个关联数组。
- 赋值给关联数组时,可以使用`[key]=value`的语法,或者直接在声明时赋值。
- 当访问关联数组的元素时,使用`${assoc_array[key]}`的语法,其中`key`是要访问的键。
- 使用`${!assoc_array[@]}`可以获取关联数组所有的键。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值