【Bash/Shell】知识总结

文章目录

  • [1. 总体认识](#1. 总体认识)
    • [1.1. Shell概述](#1.1. Shell概述)
    • [1.2. 第一个Shell脚本](#1.2. 第一个Shell脚本)
    • [1.3. 注释](#1.3. 注释)
  • [2. 变量](#2. 变量)
    • [2.1. 定义变量](#2.1. 定义变量)
    • [2.2. 使用变量](#2.2. 使用变量)
    • [2.3. 只读变量](#2.3. 只读变量)
    • [2.4. 删除变量](#2.4. 删除变量)
    • [2.5. 变量类型](#2.5. 变量类型)
      • [2.5.1. 字符串变量](#2.5.1. 字符串变量)
      • [2.5.2. 整数变量](#2.5.2. 整数变量)
      • [2.5.3. 数组变量](#2.5.3. 数组变量)
      • [2.5.4. 环境变量](#2.5.4. 环境变量)
      • [2.5.5. 特殊变量](#2.5.5. 特殊变量)
  • [3. 输出](#3. 输出)
    • [3.1. echo命令](#3.1. echo命令)
    • [3.2. printf命令](#3.2. printf命令)
  • [4. 运算符](#4. 运算符)
    • [4.1. 运算表达式](#4.1. 运算表达式)
    • [4.2. 条件表达式](#4.2. 条件表达式)
      • [4.2.1. 关系运算符](#4.2.1. 关系运算符)
      • [4.2.2. 逻辑运算符](#4.2.2. 逻辑运算符)
      • [4.2.3. 字符串运算符](#4.2.3. 字符串运算符)
      • [4.2.4. 文件测试运算符](#4.2.4. 文件测试运算符)
  • [5. 流程控制](#5. 流程控制)
    • [5.1. 条件语句](#5.1. 条件语句)
      • [5.1.1. if语句](#5.1.1. if语句)
      • [5.1.2. case多选择语句](#5.1.2. case多选择语句)
    • [5.2. 循环语句](#5.2. 循环语句)
      • [5.2.1. for循环](#5.2.1. for循环)
      • [5.2.2. while循环](#5.2.2. while循环)
      • [5.2.3. 无限循环](#5.2.3. 无限循环)
      • [5.2.4. until循环](#5.2.4. until循环)
      • [5.2.5. 跳出循环](#5.2.5. 跳出循环)
  • [6. 函数](#6. 函数)
  • [7. 输入输出重定向](#7. 输入输出重定向)
  • [8. 文件包含](#8. 文件包含)
  • [9. 常用shell命令](#9. 常用shell命令)
    • [9.1. alias](#9.1. alias)

1. 总体认识

1.1. Shell概述

  • Shell是一个用C语言编写的程序,这个程序提供了一个界面,用户通过这个界面可以访问操作系统内核的服务。
  • Shell既是一种命令 语言,又是一种解释型的程序设计语言
  • Shell脚本(shell script),是一种为shell编写的脚本程序
  • Shell编程只要有一个能编写代码的文本编辑器 和一个能解释执行的脚本解释器就可以了。
  • Linux的Shell种类众多,常用的有Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)等等,其中Bourne Again Shell是Bourne Shell的增强版本 ,兼容性更好,且提供了更多的特性和功能。由于易用和免费,Bash是大多数Linux系统默认的Shell

1.2. 第一个Shell脚本

  • 文件名:test.sh

    bash 复制代码
    #!/bin/bash
    echo "Hello World!"
    • shell脚本名:*.sh
    • 第一行使用#!指定解释器路径。
    • 第二行echo语句的作用是在终端显示指定内容。
  • 运行Shell脚本

    • 作为可执行程序
    bash 复制代码
    chmod +x ./test.sh  # 使脚本具有执行权限
    ./test.sh  			# 执行脚本
    • 作为解释器参数
    bash 复制代码
    bash test.sh

1.3. 注释

  • 单行注释:以#开头的行会被解释器忽略。
  • 多行注释
bash 复制代码
:<<EOF
Here文档中的内容不会被执行
EOF

: << delimiter
    document
delimiter

:'
冒号代表空命令,后面的内容不会执行
'

2. 变量

变量是存储的数据值的名称

2.1. 定义变量

bash 复制代码
variable=value
  • 注意:变量名和等号之间不能有空格
  • 变量命名要求:
    • 只由字母、数字和下划线组成,不能以数字开头。
    • 避免使用Shell关键字。
    • 习惯上,常量的变量名通常使用大写字母

2.2. 使用变量

bash 复制代码
variable=value
echo $variable
echo ${variable}
  • 变量名外面的花括号是可选的,加花括号是为了帮助解释器识别变量的边界

  • 已定义的变量,可以被重新定义

    bash 复制代码
    variable=value1
    echo $variable
    variable=value2
    echo $variable

2.3. 只读变量

bash 复制代码
variable=value
readonly variable

2.4. 删除变量

bash 复制代码
variable=value
unset variable
  • 变量被删除后不能再次使用。
  • unset 命令不能删除只读变量。

2.5. 变量类型

2.5.1. 字符串变量

bash 复制代码
str1=hello
str2='hello'
str3="hello"
  • 变量通常被视为字符串。

  • 可以使用单引号 ' 或双引号 " 来定义字符串

  • 单引号字符串的限制

    • 单引号字符串里的任何字符都会原样输出,不能进行变量值的替换。
    • 单引号字符串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
  • 双引号字符串

    bash 复制代码
    name="world"
    str="\"Hello,$name! \"\n"
    echo -e $str
    • 双引号字符串中可以进行值的替换。
    • 双引号字符串中可以出现转义字符。
    • 使用echo语句显示\n要添加参数-e
  • 拼接字符串

bash 复制代码
name="world"

# 使用双引号
str1="hello, "$name"!"
str2="hello, $name!"	# 推荐

# 使用单引号
str3='hello, '$name'!'
  • 获取字符串的长度
bash 复制代码
str="hello"
echo ${#str}
echo ${#str[0]}
  • 提取子字符串
bash 复制代码
str="Hello, World!"
echo ${str:1:4}	# 输出ello
  • 查找子字符串
bash 复制代码
str="Hello, World"

# 获得字符l,o第1次出现时,已经读取的字符串部分
x=${str%%[lo]*}		# x的值为He
# x的长度加1即为首次出现指定字符的索引
echo $((${#x}+1))	# 输出3

2.5.2. 整数变量

bash 复制代码
declare -i intvar=3
typeset -i intvar=3

这样的声明告诉Shell将intvar视为整数,如果尝试将非整数值赋给它,Shell会尝试将其转换为整数。

2.5.3. 数组变量

  • 数组变量可以在一个变量中存储多个值。

  • 整数索引数组

    bash 复制代码
    array1=(1 2 3 4 5)
    array2=(
    	"1"
    	2
    	"hello"
    )
    array3[0]=value0
    array3[2]=value2
    • 可以不使用连续的下标,而且下标的范围没有限制。
    • 索引数组元素:${数组名[索引]}
    • 获取所有元素:${数组名[*]}${数组名[@]},两者的区别是后者常用于迭代。
    • 获取数组的长度:${#数组名[*]}${#数组名[@]}
    • 获取数组单个元素的长度:${#数组名[索引]}
  • 关联数组

    bash 复制代码
    declare -A asarray
    asarray["name"]="John"
    asarray["age"]=30
    
    declare -A site=(
    	["google"]="www.google.com"
    	["baidu"]="www.baidu.com"
    )
    • 键可以是任意的字符串或者整数
    • 键是唯一的
    • 使用键访问关联数组元素:数组名[键]
    • 获得所有值:${数组名[*]}${数组名[@]},两者的区别是后者常用于迭代。
    • 获得所有键:${!数组名[*]}${!数组名[@]},两者的区别是后者常用于迭代。
    • 获得数组长度:${#数组名[*]}${#数组名[@]}

2.5.4. 环境变量

  • 环境变量是由操作系统或用户设置的特殊变量,用于配置Shell的行为和影响其执行环境。

  • PATH变量包含了操作系统搜索可执行文件的路径

  • 将路径添加PATH

    bash 复制代码
    export PATH=${your_path}:$PATH
    • 直接在终端执行是临时设置
    • 要永久设置则须写入配置文件
      • 当前登陆用户配置文件:~/.bashrc
      • 所有用户的配置文件:/etc/profile
      • 写入后要重新加载:source ${config_path}
  • 添加其他环境变量与PATH变量类似

2.5.5. 特殊变量

特殊变量 作用
$0 脚本名称
$1, $2, ... 脚本参数
$# 传递给脚本的参数数量
$* 以一个单字符串接收所有向脚本传递的参数
$@ 以"$1" " 2 " ... " 2" ... " 2"..."n" 的形式接收所有参数,常用于迭代
$? 上一个命令的退出状态,0表示没有错误,其他任何值表明有错误。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同。

3. 输出

3.1. echo命令

  • 命令格式
bash 复制代码
echo string
  • 显示普通字符串
bash 复制代码
echo "It is a test"
echo It is a test
  • 显示转义字符
bash 复制代码
echo "\"It is a test\""
echo \"It is a test\"
  • 显示变量
bash 复制代码
# 标准输入中读取一行(不允许转义)到变量name
read -r name
echo "$name is good!"
  • 显示换行
bash 复制代码
echo -e "OK! \n" # -e 开启转义
echo "******"
  • 显示不换行
bash 复制代码
echo "OK! \n" # 原样输出\n
echo "******"
echo -e "OK! \c" # -e 开启转义,但不换行
echo "******"
  • 原样输出字符串
bash 复制代码
echo '$name\"'
  • 显示命令执行结果
bash 复制代码
echo "Date: $(date)"

3.2. printf命令

  • printf命令模仿C程序库里的printf()函数。
  • 命令格式
bash 复制代码
printf  format-string  [arguments...]
  • 格式化字符串参照C语言
  • 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string被重用
  • 如果没有arguments,那么%sNULL代替,%d0代替
  • 格式化字符串中的%b格式
    • 用于参数中存在\n时,输出换行。用%s会原样输出\n
    • 仅在%b格式下,\c可以抑制(不显示)输出结果中任何结尾的换行字符,而且其后的所有内容全部忽略。用%s会原样输出\c

4. 运算符

4.1. 运算表达式

  • 运算表达式的使用

    bash 复制代码
    val=$((2 + 2))
    echo "$val"
    • $((...))中不用考虑空格的问题,变量不用加$号。

    • 支持的运算

      运算符 含义 举例
      + 加法 $((a + b))
      - 减法 $((a - b))
      * 乘法 $((a * b))
      / 除法 $((a / b))
      % 取余 $((a % b))
      ++ 自增,与C++相同 $((a++))
      -- 自减,与C++相同 $((a--))
      = 赋值,右值作为结果 $((a = b))
      == 比较相等,相等为1,否则为0 $((a - b))
      != 比较不相等,不相等为1,否则为0 $((a - b))
      > 比较大于,大于为1,否则为0 $((a - b))
      < 比较小于,小于为1,否则为0 $((a - b))
      >= 比较大于等于,大于等于为1,否则为0 $((a - b))
      <= 比较小于等于,小于等于为1,否则为0 $((a - b))

4.2. 条件表达式

  • 条件表达式的使用

    bash 复制代码
    a=2
    b=1
    
    if test $a -eq $b
    then
        echo "相等"
    elif [ $a -ge $b ]
    then
        echo "大于"
    elif (($a < $b))
        echo "小于"
    else
    		echo "错误"
    fi
    • 条件表达式通常用于流程控制中
    • 条件判断可以使用test 条件表达式
    • 条件判断可以使用[ 条件表达式 ],注意要有空格
    • 条件判断可以使用((条件表达式)),此时可以不用考虑空格

4.2.1. 关系运算符

只支持数字,不支持字符串

运算符 含义 举例
-eq 检测两个数是否相等,相等返true。 [ $a -eq $b ]
-ne 检测两个数是否不相等,不相等返回true。 [ $a -ne $b ]
-gt 检测两个数是否大于右边的,如果是,则返回true。 [ $a -gt$b ]
-lt 检测两个数是否小于右边的,如果是,则返回true。 [ $a -lt $b ]
-ge 检测两个数是否大于等于右边的,如果是,则返回true。 [ $a -ge $b ]
-le 检测两个数是否小于等于右边的,如果是,则返回true。 [ $a -le $b ]

4.2.2. 逻辑运算符

优先级:! > && > ||,存在短路运算。

运算符 含义 举例
&& 逻辑与运算 [[ $a -lt 100 && $b -gt 15 ]]
` `
! 逻辑非运算 [[ ! $a -lt 100 ]]

4.2.3. 字符串运算符

运算符 含义 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ]
!= 检测两个字符串是否不相等,不相等返回 true。 [ $a != $b ]
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ]
-n 检测字符串长度是否不为0,不为0返回 true。 [ -n $a ]
$ 检测字符串是否不为空,不为空返回 true。 [ $a ]

4.2.4. 文件测试运算符

用于检测Unix文件的各种属性。

运算符 含义 举例
-b 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ]
-c 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ]
-d 检测文件是否是目录,如果是,则返回 true。 [ -d $file ]
-f 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ]
-g 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ]
-k 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ]
-p 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ]
-u 检测文件是否设置了SUID位,如果是,则返回 true。 [ -u $file ]
-r 检测文件是否可读,如果是,则返回 true。 [ -r $file ]
-w 检测文件是否可写,如果是,则返回 true。 [ -w $file ]
-x 检测文件是否可执行,如果是,则返回 true。 [ -x $file ]
-s 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ]
-e 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ]
-S 判断某文件是否 socket。 [ -S $file ]
-L 检测文件是否存在并且是一个符号链接。 [ -L $file ]

5. 流程控制

5.1. 条件语句

5.1.1. if语句

  • 最展开的格式
bash 复制代码
if 条件判断
then
	命令1
	命令2
	...
elif 条件判断
then
	命令1
	命令2
	...
else
	命令1
	命令2
	...
fi
  • 写成一行要加分号分隔
bash 复制代码
if 条件判断; then 命令; fi
if 条件判断; then
	命令1
	命令2
	...
fi

5.1.2. case多选择语句

bash 复制代码
case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
    *)
    command1
    command2
    ...
    commandN
    ;;
esac

5.2. 循环语句

5.2.1. for循环

  • 最展开的格式
bash 复制代码
for var in item1 item2
do
	命令1
	命令2
	...
done
  • 写成一行要加分号分隔
bash 复制代码
for var in item1 item2; do 命令1; 命令2; done

5.2.2. while循环

  • 一般格式
bash 复制代码
while 条件判断
do
	命令1
	命令2
	...
done
  • 循环读取键盘输入
bash 复制代码
while read -r site
do
    echo "是的!$site 是一个好网站"
done

5.2.3. 无限循环

bash 复制代码
while true
do
	命令
done

5.2.4. until循环

先执行,再判断

bash 复制代码
until 条件判断
do
    命令
done

5.2.5. 跳出循环

  • break是跳出本级循环
  • continue跳出本次循环

6. 函数

  • 格式
bash 复制代码
function funname [()]
{
	action
	[return int;]
}

[ function ] funname ()
{
	action
	[return int;]
}
  • 所有函数在使用前必须定义。
  • 调用函数仅使用其函数名即可。
  • 返回值
    • 如果不return语句,将以最后一条命令运行结果作为返回值。
    • 只能返回0-255
    • 函数返回值在调用该函数后通过$?来获得。
  • 函数参数与脚本的命令行参数相同

7. 输入输出重定向

  • 文件描述符

    • 0表示标准输入(STDIN)
    • 1表示标准输出(STDOUT)
    • 2表示标准错误输出(STDERR)
  • 空设备文件nul(指向/dev/null)

  • 输出重定向到文件,覆盖原文件。

    bash 复制代码
    command > file
  • 输出以追加的方式重定向到文件

    bash 复制代码
    command >> file
  • 合并标准输出和标准错误输出,并重定向到文件

    bash 复制代码
    command > file 2>&1
  • 错误输出重定向到文件

    bash 复制代码
    command 2> file
  • 将输入重定向为文件

    bash 复制代码
    command < file
  • Here文档:将输入重定向为两个分隔符之间的内容

    bash 复制代码
    command << delimiter
        document
    delimiter
  • 对标准输入和标准输出都进行重定向

    bash 复制代码
    command < file1 > file2
  • 屏蔽命令输出

    bash 复制代码
    command > nul
    command > /dev/null

8. 文件包含

bash 复制代码
. filename	# 注意有空格
source filename

上述语句会先执行指定shell脚本,但是保留shell脚本执行结束会清理的变量等内容

9. 常用shell命令

9.1. alias

  • 用于设置指令的别名
  • 语法
bash 复制代码
alias [别名]="[指令名称]"
  • 注意多条指令用分号分隔
相关推荐
笑稀了的野生俊1 天前
在服务器中下载 HuggingFace 模型:终极指南
linux·服务器·python·bash·gpu算力
weixin_307779132 天前
Hive集群之间迁移的Linux Shell脚本
大数据·linux·hive·bash·迁移学习
shimly1234562 天前
bash 脚本比较 100 个程序运行时间,精确到毫秒,脚本
开发语言·chrome·bash
小哈龙3 天前
裸仓库 + Git Bash 搭建 本地 Git 服务端与客户端
开发语言·git·bash
阿巴~阿巴~4 天前
Linux基本命令篇 —— alias命令
linux·服务器·bash
Ven%16 天前
掌握Bash脚本编写:从服务启动脚本到语法精要
linux·服务器·开发语言·chrome·bash
阿乾之铭17 天前
推送项目到GitHub
ssh·github·bash
张紫娃18 天前
bash 命令行 |
开发语言·bash
先做个垃圾出来………20 天前
Bash (Bourne Again SHell)
开发语言·chrome·bash
Eric.Lee202123 天前
ubuntu 系统 多条命令通过 bash 脚本执行
linux·ubuntu·bash