前端青训营-shell脚本和编程

94 阅读7分钟

Shell脚本和编程

  • Linux服务器的基本操作和管理
  • 前端nodejs服务的进程管理,问题排查,资源监控等运维操作
  • 使用shell编写tce、scm、docker脚本,完成服务编译和部署

shell基础概念

Shell是一种在操作系统上运行的命令解释器,它是一个命令行界面,允许用户输入命令并运行对应的程序。Shell常被用于管理操作系统,例如文件操作、进程管理、系统配置等。在Linux和Unix操作系统中,有许多不同的Shell可供选择,例如bash、zsh、ksh等。

  命令行界面:Shell提供了一个命令行界面,允许用户输入命令并运行相应的程序。
  
  Shell脚本:Shell脚本是一系列Shell命令的集合,可以被保存为脚本文件,并在需要时运行。脚本文件通常以.sh作为文件扩展名。
  
  变量:在Shell中,可以定义和使用变量来存储数据。变量以$符号开头,例如$var,可以用来存储字符串、数字等类型的数据。
  
  条件语句:Shell中支持ifelse、elif等条件语句,用于根据条件来执行不同的命令或代码块。
  循环结构:Shell中支持forwhileuntil等循环结构,可以用来迭代执行一系列命令或代码块。
  输入输出重定向:Shell中可以使用输入输出重定向来改变命令的输入和输出。例如,将一个命令的输出重定向到一个文件中。
  
  管道操作:Shell中可以使用管道符号(|)来将一个命令的输出作为另一个命令的输入。例如,将一个命令的输出传递给另一个命令用作输入。

shell构成

解释器

  • bash内置指令
  • gun核心工具库
  • 第三方库

编程语言

  • 变量
    • 自定义变量
    • 环境变量
    • 系统环境变量
  • 运算
    • 逻辑运算
    • 算数运算
  • 语句
    • 判断
    • 分支
    • 循环
  • 函数

配置文件加载

运算符和引用

管道

在Shell中,管道(|)是一种用于将一个命令的输出作为另一个命令的输入的机制。管道将两个或多个命令连接在一起,使得它们可以协同工作来完成更复杂的任务。管道可以大大简化命令的编写和处理。以下是一些管道的示例:

  1. 用管道将两个命令连接在一起,例如:
ls -l | grep ".txt"

这个命令列出当前目录的所有文件和子目录,然后将结果作为输入送到grep命令中,以筛选出以".txt"结尾的文件。

  1. 管道可以用于连接多个命令。例如,以下命令使用管道连接三个命令:
cat file.txt | awk '{print $2}' | sort | uniq

这个命令读取一个名为file.txt的文件,并将其传递给awk命令。awk然后提取每行中的第二个单词,并将其传递给sort命令进行排序,并且最终将结果传递给uniq命令,以去除重复的行。

  1. 管道可以用于将命令的输出直接写入文件中。例如,以下命令将一个查询结果的输出重定向到文件中:
ps -ef | grep "firefox" > firefox_processes.txt

这个命令运行ps命令来列出进程,然后使用grep命令来查找包含"firefox"的进程。最后,将输出写入名为firefox_processes.txt的文件中。

管道是Shell中一个非常有用的功能,可以让Shell命令更加灵活和强大。管道不仅可以连接两个命令,还可以连接多个命令和处理复杂的数据。

重定向

在Shell中,重定向是用于改变命令输入和输出的一种简便方法。通过重定向,可以将命令的输入或输出重定向到文件、其他命令或特殊设备中。以下是一些常见的重定向操作:

  1. 输出重定向

使用>符号可以将命令的输出重定向到文件中:

ls > file.txt

这个命令将当前目录的文件列表输出到file.txt文件中,如果文件不存在会创建一个新文件,如果文件存在则清空文件内容。

使用>>符号可以将命令输出附加到文件的末尾,而不是替换文件中的内容:

echo "新内容" >> file.txt

这个命令将"新内容"追加到file.txt文件的末尾。

  1. 输入重定向

使用<符号可以将命令从文件中读取输入:

sort < file.txt

这个命令将file.txt文件作为输入,按字母顺序对其进行排序并输出结果。

  1. 管道重定向

使用|符号将一个命令的输出作为另一个命令的输入,管道重定向如前所述。

  1. /dev/null

/dev/null是一个特殊的设备文件,可以用来丢弃命令的输出或输入。例如,以下命令会运行命令,但在屏幕上不显示任何输出:

command > /dev/null

这个命令将命令的输出重定向到/dev/null设备文件中,从而将命令输出丢弃。

这些是一些常见的Shell重定向操作。重定向是Unix / Linux命令行中非常有用的一项技术,可以使命令变得更加灵活和强大。

判断命令

在Shell脚本中,可以使用if语句来判断命令是否执行成功或某个条件是否为真。以下是一些常见的Shell判断命令:

  1. 当命令执行成功时返回0,可以使用$?特殊变量来检查命令是否执行成功。
command
if [ $? -eq 0 ]; then
    echo "命令执行成功"
else
    echo "命令执行失败"
fi

上述示例中,如果command执行成功,则输出"命令执行成功",否则输出"命令执行失败"。

  1. 可以使用-z选项来检查字符串是否为空。
str=""
if [ -z "$str" ]; then
    echo "字符串为空"
else
    echo "字符串不为空"
fi

以上示例中,如果str为空字符串,则输出"字符串为空",否则输出"字符串不为空"。

  1. 可以使用-eq-ne-lt-le-gt-ge等选项来比较数字。
num1=10
num2=20
if [ $num1 -eq $num2 ]; then
    echo "两个数字相等"
elif [ $num1 -lt $num2 ]; then
    echo "num1小于num2"
else
    echo "num1大于num2"
fi

上述示例中,如果num1等于num2,则输出"两个数字相等";否则,如果num1小于num2,则输出"num1小于num2";否则,输出"num1大于num2"。

这些是一些常见的Shell判断命令。在Shell脚本中使用if语句可以根据条件来控制程序的执行流程,从而使Shell脚本更加灵活。

分支语句

在Shell脚本中,可以使用分支语句来根据条件执行不同的操作。Shell中最常用的分支语句是if-else语句和case语句。

if-else语句

if-else语句用于根据条件执行不同的操作。以下是if-else语句的基本语法:

if [ condition ]
then
    # code to be executed if the condition is true
else
    # code to be executed if the condition is false
fi

其中,condition是要检查的条件表达式。如果condition为真,则执行then中的代码;否则执行else中的代码。

以下是一个经典的if-else语句示例,用于判断数字大小:

num1=10
num2=20
if [ $num1 -gt $num2 ]
then
    echo "$num1 大于 $num2"
else
    echo "$num1 小于等于 $num2"
fi

case语句

case语句类似于switch-case语句,用于根据变量的值执行不同的操作。以下是case语句的基本语法:

case variable in
pattern1)
    # code to be executed when variable matches pattern1
    ;;
pattern2)
    # code to be executed when variable matches pattern2
    ;;
patternN)
    # code to be executed when variable matches patternN
    ;;
*)
    # code to be executed when variable does not match any pattern
    ;;
esac

其中,variable是要检查的变量,pattern1..N是匹配的模式,*是一个通配符,匹配任何值。

以下是一个简单的case语句示例:

fruit=apple
case $fruit in
    "apple") echo "这是苹果" ;;
    "banana") echo "这是香蕉" ;;
    "orange") echo "这是橘子" ;;
    *) echo "未知的水果" ;;
esac

这个示例首先检查变量$fruit的值,如果值等于apple,则输出"这是苹果";如果值等于banana,则输出"这是香蕉";如果值等于orange,则输出"这是橘子";否则,输出"未知的水果"。

函数

Shell 函数是一个独立的代码块,在脚本中可以被多次调用。创建函数是一种将代码块组织为逻辑单元的方式,可以提高代码的可读性和可维护性。在 Shell 中,函数的语法与普通命令的语法非常相似,可以在需要的地方处于任何位置定义和调用。

下面是一个简单的 Shell 函数示例,该函数输出传递给它的两个字符串参数:

# 定义函数
myfunc() {
    echo "Hello $1, nice to meet you, $2!"
}

# 调用函数
myfunc "Alice" "how are you doing today?"

在调用该脚本时,该函数将输出字符串 "Hello Alice, nice to meet you, how are you doing today?!"。

模块化

Shell 脚本的模块化可以通过将公共代码段提取到单独的文件中,然后在需要的脚本中引用这些文件来实现。这种方法可以提高代码的可重用性和可维护性,使代码更易于组织和管理。

下面是一种常见的 Shell 模块化技术,使用 .sh 文件作为模块文件,并使用 source 命令在需要的脚本中引用模块文件。以调用其他脚本中的函数为例,可以按照以下步骤进行:

1.在一个 .sh 文件中定义需要共享的函数或变量,例如:

# file1.sh
function hello() {
    echo "Hello, world!"
}
export MYVAR="I am a variable"

2.在要使用这些函数或变量的脚本中使用 source 或者 . 命令引入定义好的模块文件,例如:

# file2.sh
source file1.sh
hello
echo $MYVAR

在执行 file2.sh 脚本时,会输出 "Hello, world!" 和 "I am a variable"。

这种方法可以用于拆分大型脚本文件,或将公共代码存储在集中的位置以便于管理和调用。同时,它也可以使代码更加易于重用和维护。

执行过程和原理

执行过程

Shell 脚本是一组命令的集合,按顺序执行。当我们运行一个 Shell 脚本时,它将被 Shell 解释器读入,并一行一行地执行,直到执行完毕或遇到错误。

Shell 执行脚本的过程如下:

  1. 在终端或其他调用程序中输入脚本名称,Shell 解释器将启动并读入脚本文件。

  2. Shell 解释器读入脚本文件的第一行内容,判断该行是否以 #! 开头。如果是,将其视为 "shebang" 行,指定该脚本的解释器。

  3. 解释器将读取脚本中的命令,并执行它们。每个命令通常由一个或多个单词组成,其中第一个单词是命令本身,其余单词为该命令所需的任何参数。

  4. 命令被解释器执行,它们可能会被执行系统调用调用底层系统功能,例如创建进程、读取文件、输出到终端等等。

  5. 当脚本中的所有命令都被执行完成后,Shell 解释器结束。

  6. 如果存在错误或故障,解释器将返回错误代码以指示问题所在。

  7. 脚本执行过程中,使用 echo 命令或者将值赋给变量等方式输出结果。

需要注意的是,Shell 脚本的执行过程可以被中断或暂停,例如使用 ctrl+c 终止脚本执行,或者使用 ctrl+z 将脚本置于后台运行等。

shell展开

Shell 展开是指将特定字符或通配符转换为表达式、路径或文件名的过程。例如,通配符 * 被展开为当前目录下所有文件名的列表,而环境变量 $HOME 被展开为当前用户的主目录路径。

Shell 展开包括:

  1. 命令替换:将命令的输出插入到其他命令或字符串中。用反引号或 $() 包围一个命令来进行命令替换。

例如:

echo "The current date is $(date +%Y-%m-%d)"

输出为:“The current date is 2022-07-15”。

  1. 变量替换:将变量名替换为其值。用 $ 符号加上变量名来进行变量替换。

例如:

MYVAR="Hello, world!"
echo "The message is: $MYVAR"

输出为:“The message is: Hello, world!”。

  1. 通配符展开:将通配符 * 展开为当前目录下所有匹配的文件名。

例如:

ls *.txt

将输出所有扩展名为 .txt 的文件名。

  1. 大括号展开:用花括号 { } 将一组值括在一起,形成一个列表,通过逗号分隔。展开时,每个值被顺序替换到大括号的位置。

例如:

echo {one,two,three}

将输出: "one two three" 。

需要注意的是,在展开中使用特殊字符和通配符时,应特别小心以避免不必要的结果。必要时需要使用引号或转义字符对特殊字符进行保护。

调试和前端集成

调试

  • 普通log,使用echo、printf
  • 使用set命令
  • vscode debug插件

vscode配置

  • shellman:代码提示和自动补全
  • shellcheck:代码语法校验
  • shell-format:代码格式化
  • Bash Debug:支持单步调试
    • 安装vscode插件
    • 编写launch.json文件
    • 升级bash到4.x以上版本

个人总结

了解从其发展历史、基础语法开始,通过示例逐步深入, 学会使用 Shell ,也在一定程度上去理解 Shell 的执行原理和语法设计。