当前位置: 首页 > article >正文

Class2(2020):Shell基础(二)——Shell脚本设计基础

本系列博客为MIT的《Missing in CS Class》的课程笔记。

Class2(2020):Shell基础(二)——Shell脚本设计基础

注:若无特殊说明,本文中带有[]的部分均为可选参数

脚本文件

  • 脚本语言为解释执行,其运行需有解释器,如Python。
  • Shell是一种脚本语言,其文件扩展名为.sh
  • 脚本文件的首行一般为#! <shell_name>,符号#!被称为shebang,其规定该脚本以何种Shell解释器执行。一般采用env(/usr/bin/env)程序,到$PATH中查找某种解释器在何位置,如#!/usr/bin/env shell
  • 若同一行有多条命令,用;分隔
  • 执行脚本:分为子Shell执行与当前Shell执行。若为子Shell执行,在不使用export的情形下,脚本中定义的各种变量、函数、环境都不会被带回当前Shell;若为当前Shell执行则反之,可在后续命令中调用脚本中定义的变量、函数等内容。
    • ./<script_name>.sh:仅当该脚本有可执行权限(x)时,根据shebang中规定的解释器,创建一个独立子Shell以执行该脚本
    • <shell_name> ./<script_name>.sh:无论该脚本是否有可执行权限,忽略shebang,以<shell_name>创建一个独立子Shell以执行该脚本
    • source ./<script_name>.sh. ./<script_name>.sh:无论该脚本是否有可执行权限,忽略shebang,直接在当前Shell中执行该脚本,相当于将脚本中进行的修改注入到当前Shell。

变量

  • 变量赋值:Shell与其他多数脚本语言一致,变量无需定义,直接赋值即可。右值可为数字、字符串、其他变量、数组、命令替换等。<name>=<value>
    注意赋值中各符号间不能有任何空格。

  • 变量可被重新赋值使用。

  • 变量使用:$<name>

  • 删除变量:unset <name>

  • 输出:

    • echo:如echo $a

    • 格式化输出:printf <format_string> [arg_list],与C中相同

  • Shell定义了一些保留变量

    • $0:脚本名
    • $1-$9:脚本执行的第 i i i 项参数。类似于C中main函数的形参argv[]
    • $@:所有参数
    • $#:参数数量。类似于C中main函数的形参argc
    • $$:当前脚本的PID(进程识别码)
    • $?:上条程序的返回值。
    • !!:上条包含所有参数的完整命令。如执行命令后被返回Permission Denied,使用sudo !!即可重新提升执行
    • $_:上条命令的最后一项参数。如:mkdir 1cd $_

数组、字符串

  • Shell只支持一维数组,所有value都会被视为字符串处理

    • 初始化:<array_name>=(<value1>,<value2>,...)

    • 赋值:<array_name>[<index>]=<value>

    • 随机访问:${<name>[<index>]}。特别的,<idx>@时,代表取数组中所有元素。

  • 关系数组:相当于Python中的dic(字典)、C++中的map。与普通数组不同,关系数组必须声明后才能使用。

    • 声明:declare -A <array_name>

    • 初始化:declare -A <array_name>=(["<key1>"]="<value1>" ["<key2>"]="<value2>" ...),其中<key>必须唯一。

    • 赋值:<array_name>["<key>"]="<value>"

  • 字符串:

    • 单引号包围的字符串:被视为字符串字面常量,所有内容将被原样存储,变量也不会被替换。如echo '$a':输出$a
    • 双引号包围的字符串:正常替换变量。如echo "$a":输出:b
    • 字符串长度:${#<name>}

命令替换、进程替换

  • 命令替换:$(<command>)<command>命令的stdout替换$(<command>)本身。如:

    today=$(date) #将输出赋值给变量
    echo "$today"
    
    for i in $(ls) ; do #遍历文件
    	echo "$i"
    done
    
    cd $(ls)
    
  • 进程替换:

    • 输出重定向:<(<command>),将<command>stdout写入临时文件中,可作为其他命令的文件读入。例:

      diff <(ls <dir1>) <(ls <dir2>)
      
    • 输入重定向:>(<command>),将其他命令的stdout写入临时文件中,由<command>读取。效果等价于管道符|

流程控制

选择结构

if…fi

注意Shell中的分支不可为空,若不需要就不要写对应的分支。注意在每个<condition>后都需加then

  • 单分支结构:if then ... fi

    if <condition> ; then
    	<command>
    fi
    
  • 双分支结构:if then ... else ... fi

    if <condition> ; then
    	<command>
    else
    	<command>
    fi
    
  • 多分支结构:if then ... elif then ... else ... fi

    if <condition> ; then
    	<command>
    elif <condition> ; then
    	<command>
    else
    	<command>
    fi
    

<condition>为布尔表达式时的两种表示形式:

  • [<bool_expression>]-eq:判断两个数字是否相等;-ne:判断两个数字是否不相等;-lt:判断数字是否小于;-le:判断数字是否小于等于;-gt:判断数字是否大于;-ge:判断数字是否大于等于。
  • ((<bool_expression>)):算术专用的布尔表达式,直接使用关系运算符即可。
case...esac
case <variable> in
    <pattern>)
    	<command>
        ;;
    [
    *) #相当于default
    	<command>
        ;;
    ]
esac

类似于C中的switch,顺次进行匹配。case...esac并没有原生的default,因此在结尾使用通配符*对未匹配内容进行匹配。

<pattern>中若有多个匹配规则,用|(或)连接,如1|2|3。可使用通配符、字符集([])。

循环结构

for
for <variable> in <object> ; do
	<command>
done
  • 传入列表:

    for i in 1 2 3 4 5 ; do
    	echo "$i"
    done
    
  • 传入范围序列$(seq)(相当于Python的range(),注意Shell的seq的左闭右闭区间):

    for <variable> in $(seq <start> <end> [<foot>]) ; do
    	<command>
    done
    
  • 传入花括号{<start>..<end>}:等价于$(seq <start> <end>)$

    for <variable> in {<start>..<end>} ; do
    	<command>
    done
    
while
while <condition> ; do
    <command>
done

<condition>为真时,循环执行循环体

until
until <condition> ; do
    <command>
done

<condition>为假时,循环执行循环体,直到<condition>为真

跳转语句

  • continue:跳出循环的当前轮
  • break:跳出整个循环

函数

  • 函数定义
function_name() {
    <command>
    [return ...]
}

function function_name {
    <command>
    [return ...]
}
  • 函数调用
function_name [argv,...]

http://www.kler.cn/a/525201.html

相关文章:

  • 動態住宅IP提升網站訪問成功率
  • js小游戏---2048(附源代码)
  • 《使用通道 Transformer 进行多尺度特征融合,引导热图像超分辨率》学习笔记
  • Java创建项目准备工作
  • 【教学类-89-01】20250127新年篇01—— 蛇年红包(WORD模版)
  • Vscode的AI插件 —— Cline
  • jEasyUI 转换 HTML 表格为数据网格
  • 【深度学习】图像分类数据集
  • Kafa分区策略实现
  • fpga系列 HDL:XILINX Vivado Vitis 高层次综合(HLS) 实现 EBAZ板LED控制(下)
  • 前端力扣刷题 | 2:hot100之 双指针
  • Web3 如何赋能元宇宙,实现虚实融合的无缝对接
  • 论“0是不存在的”
  • H3CNE-27-链路聚合(L3)
  • 使用shell命令安装virtualbox的虚拟机并导出到vagrant的Box
  • 正则表达式入门
  • DeepSeek的崛起与全球科技市场的震荡
  • C++并发编程指南03
  • 【JavaWeb】利用IntelliJ IDEA 2024.1.4 +Tomcat10 搭建Java Web项目开发环境(图文超详细)
  • 商品信息管理自动化测试
  • 落地基于特征的图像拼接
  • 研发的立足之本到底是啥?
  • 跨平台物联网漏洞挖掘算法评估框架设计与实现文献综述之Gemini
  • 我的求职之路合集
  • zsh安装插件
  • Vue演练场基础知识(七)插槽