Shell脚本和编程

260 阅读7分钟

学习Shell的价值

  1. linux
  2. nodejs基础
  3. 编译docker脚本

01 shell基础概念

终端

teletypewrite

终端模拟器

构成:解释器和编程语言

02 语法和命令

命令

Shell是一种用于交互式命令行界面的程序,也是一种脚本语言。在Linux和Unix系统中,常用的Shell是Bash。Shell命令是通过在命令行输入命令来执行的,常用的命令包括:

  1. cd:切换当前工作目录。
  2. ls:列出当前目录中的文件和子目录。
  3. cp:复制文件或目录。
  4. mv:移动或重命名文件或目录。
  5. rm:删除文件或目录。
  6. mkdir:创建一个新目录。
  7. rmdir:删除一个空目录。
  8. touch:创建一个新文件或更新一个已有文件的最后访问时间和修改时间。
  9. cat:显示文件内容。
  10. grep:在文件中查找指定的字符串。
  11. chmod:修改文件或目录的权限。
  12. ps:列出当前正在运行的进程。
  13. kill:终止一个正在运行的进程。
  14. top:显示系统资源使用情况和进程信息。

除了这些基本命令,Shell还支持管道、重定向、通配符等高级用法,可以用于自动化任务和批处理。Shell脚本可以实现复杂的逻辑和流程控制,是系统管理和软件开发中重要的工具。

shell管道(|)可以将一个命令的输出作为另一个命令的输入,实现命令之间的串联操作。例如,使用ls命令查看当前文件夹中的文件,然后使用grep命令查找其中包含“test”的文件名:

ls | grep test

重定向(>)可以将命令的输出重定向到文件中,或者从文件中读取内容作为命令的输入。例如,将echo命令的输出重定向到文件中:

echo "hello world" > hello.txt

通配符(*)可以匹配文件名中的任意字符。例如,使用ls命令查看当前文件夹中所有以“.txt”结尾的文件:

ls *.txt

变量

Shell中的自定义变量使用语法为:变量名=变量值,例如:my_var="Hello, World!"。在之后的脚本中,可以通过$my_var来引用这个变量的值。

而环境变量则是由操作系统或用户设置的全局变量,可以在不同的Shell进程中共享。设置环境变量的语法为:export 变量名=变量值,例如:export PATH=$PATH:/usr/local/bin。这里的PATH是一个特殊的环境变量,表示可执行文件的搜索路径。通过这种方式,我们可以将/usr/local/bin添加到PATH中,使得系统能够自动搜索和执行这个目录下的可执行文件。

运算符

关于Shell的运算符和引用,有以下几个知识点:

  1. 算术运算符:+、-、*、/、%等,用于进行数值计算。
  2. 比较运算符:-eq、-ne、-gt、-lt、-ge、-le等,用于比较数值的大小关系。
  3. 逻辑运算符:&&、||、!等,用于进行逻辑运算,例如判断多个条件是否成立。
  4. 字符串运算符:=、!=、-z、-n等,用于判断字符串的相等性、非相等性、长度等。
  5. 引用:符号用于引用变量,例如符号用于引用变量,例如VAR表示引用名为VAR的变量的值。
  6. 命令替换:反引号或者$()用于执行命令,并用其输出结果来替换命令本身。

判断命令

Shell中的判断命令通常用于在脚本中测试条件,并根据测试结果执行不同的命令或操作。以下是一些常用的Shell判断命令及其用法:

  1. test命令:test命令用于测试条件,并根据测试结果返回0或1。可以使用test命令检查文件是否存在、检查变量是否为空等。例如,要检查文件是否存在,可以使用以下命令:

if test -e /path/to/file then echo "File exists" else echo "File does not exist" fi

  1. 命令:[ ] 命令是test命令的一种简写形式。它可以使用与test命令相同的测试条件。例如,以下两个命令是等效的:

if test -e /path/to/file then echo "File exists" fi if [ -e /path/to/file ] then echo "File exists" fi

  1. [[ ]] 命令:[[ ]] 命令是test命令的一种扩展形式,支持更多的测试条件。例如,可以使用[[ ]]命令判断字符串是否相等、判断变量是否为数字等。以下是一个使用[[ ]]命令的示例:

if [[ "str1"=="str1" == "str2" ]] then echo "Strings are equal" fi

分支语句

在shell编程中,常用的分支语句有if语句和case语句。它们的知识点包括:

  1. if语句:if语句用于根据条件执行不同的操作。它的语法格式为:

if condition then command1 command2 ... else command3 command4 ... fi

其中,condition是一个条件表达式,如果它的值为true,则执行then语句块中的命令,否则执行else语句块中的命令。

  1. case语句:case语句用于根据不同的条件执行不同的操作。它的语法格式为:

case variable in pattern1) command1 command2 ... ;; pattern2) command3 command4 ... ;; *) command5 command6 ... ;; esac

其中,variable是一个变量,pattern1、pattern2是不同的模式,如果variable匹配某个模式,则执行对应模式下的命令。如果没有任何模式匹配variable,则执行默认的命令。

循环语法

循环语法是编程中常用的一种结构,Shell 也提供了多种循环结构来实现不同的需求。以下是 Shell 中常用的循环语法:

  1. for 循环:for 循环可以遍历一组数据,并对每个数据执行相同的操作。for 循环的语法如下:

for 变量名 in 取值列表 do 循环体 done

  1. while 循环:while 循环可以在满足某个条件的情况下一直执行循环体。while 循环的语法如下:

while [ 条件判断语句 ] do 循环体 done

  1. until 循环:until 循环与 while 循环的执行条件相反,只有在条件不满足的情况下才会执行循环体。until 循环的语法如下:

until [ 条件判断语句 ] do 循环体 done

  1. select 循环:select 循环可以在多个选项中进行选择,并执行相应的操作。select 循环的语法如下:

select 变量名 in 选项列表 do 循环体 done

函数

shell 函数是一组为了完成特定任务而集合在一起的命令序列,它可以在脚本中任何地方被调用。以下是 shell 函数的语法和知识点:

  1. 函数的定义:

function_name () { commands }

其中,function_name 是函数名,commands 是需要执行的命令序列。

  1. 函数的调用:

function_name

可以在脚本中任何地方调用函数,只需要使用函数名即可。

  1. 函数的传参:

可以向函数传递参数,参数在函数内部通过 $1$2$3 等变量来获取,例如:

function_name () { echo "第一个参数: 1"echo"第二个参数:1" echo "第二个参数: 2" } function_name arg1 arg2

输出结果为:

第一个参数: arg1 第二个参数: arg2

  1. 函数的返回值:

函数可以返回一个值,返回值通过 return 语句来指定,例如:

function_name () { return 10 } function_name echo "函数的返回值是: $?"

输出结果为:

函数的返回值是: 10

其中 $? 是上一个命令的返回值,也就是函数的返回值。

  1. 函数的作用域:

函数内部定义的变量和函数外部定义的变量是不同的,函数内部的变量只在函数内部可见,函数外部的变量只在函数外部可见。

shell脚本的执行

  1. Shell脚本以#!开头,第一行指定脚本解释器的路径。#! /bin/bash
  2. 启动方式:
    1. 文件名运行: ./filename.sh
    2. 解释器运行: bash ./filename.sh
    3. #source 运行
    4. source ./filename.sh
  3. 可以使用变量来存储数据。变量名必须以字母或下划线开头,不能以数字开头,可以包含字母、数字和下划线。
  4. Shell脚本中的注释使用#号开头。
  5. Shell脚本中可以使用if语句、for循环、while循环等控制语句。
  6. Shell脚本中可以使用函数,使用function关键字定义函数。
  7. Shell脚本中可以使用命令替换和变量替换来执行命令和获取命令的输出。
  8. Shell脚本中可以使用管道和重定向来处理命令的输入和输出。
  9. Shell脚本中可以使用数组来存储一组数据。
  10. Shell脚本中可以调用系统命令和外部命令。
  11. Shell脚本中可以使用正则表达式匹配字符串。
  12. Shell脚本中可以使用文件操作命令,如创建目录、复制文件等。
  13. Shell脚本中可以使用错误处理机制,如使用set -e命令开启自动退出模式,遇到错误就退出脚本。

shell脚本执行过程

当我们在Linux或Unix操作系统中运行一个shell脚本时,操作系统会首先检查脚本文件的权限是否允许执行。如果脚本文件有执行权限,那么操作系统就会启动一个新的shell进程,并且把脚本文件作为参数传递给这个新的进程。

接下来,新的shell进程会逐行读取脚本文件,并且执行每一行的命令。在执行命令的过程中,新的shell进程会创建新的子进程执行一些命令(例如一些外部命令),并等待这些子进程完成后再继续执行下一条命令。

例如,如果我们在脚本文件中写下如下命令:

#!/bin/bash echo "Hello World"

当我们执行这个脚本时,操作系统会启动一个新的shell进程,并把脚本文件作为参数传递给这个进程。新的shell进程会读取脚本文件的第一行,即“#!/bin/bash”,并且识别出这是一个Bash shell脚本。接着,新的shell进程会执行第二行的命令,即输出“Hello World”到终端。

总之,shell脚本的执行过程就是操作系统启动一个新的shell进程,逐行读取脚本文件并执行每一行的命令,其中可能会创建新的子进程执行一些命令。

shell展开

shell展开是指在命令行中使用通配符(wildcard)和变量引用(variable expansion)来扩展(expand)命令参数。通配符可以匹配多个文件名,而变量引用可以获取变量的值并将其插入命令中。

以下是shell展开的一些详细语法:

  1. 通配符展开
  • * 匹配任意数量的字符(包括0个)
  • ? 匹配一个任意字符
  • [characters] 匹配一个字符集中的任意一个字符
  • {string1,string2,...} 匹配多个字符串中的任意一个
  1. 变量展开
  • $variable 获取变量的值并将其插入命令中
  • ${variable} 同上,但是用花括号明确变量名的边界
  • ${variable:-word} 如果变量未定义或为空,则使用word作为默认值
  • ${variable:=word} 如果变量未定义或为空,则将word赋值给变量并使用它
  • ${variable:?message} 如果变量未定义或为空,则将message打印到标准错误输出并退出脚本或命令

04 调试和前端集成

使用set命令设置调试选项:

set命令可以设置多种调试选项,例如-x可以输出执行的每一条命令及其参数,-v可以输出脚本中每一行执行的命令。例如:

#!/bin/bash set -x echo "开始执行脚本..." # do something set +x echo "脚本执行完成。"

在执行该脚本时,终端会输出每一条执行的命令及其参数,方便我们查看脚本执行过程。

使用trap命令捕获错误信息:

trap命令可以捕获脚本执行时的错误信息,并进行相应的处理。例如:

#!/bin/bash trap 'echo "发生错误,程序退出!"' ERR # do something

当脚本执行过程中发生错误时,终端会输出错误信息,并执行trap命令中指定的操作。这样可以及时发现错误并进行处理。