学习Shell的价值
- linux
- nodejs基础
- 编译docker脚本
01 shell基础概念
终端
teletypewrite
终端模拟器
构成:解释器和编程语言
02 语法和命令
命令
Shell是一种用于交互式命令行界面的程序,也是一种脚本语言。在Linux和Unix系统中,常用的Shell是Bash。Shell命令是通过在命令行输入命令来执行的,常用的命令包括:
- cd:切换当前工作目录。
- ls:列出当前目录中的文件和子目录。
- cp:复制文件或目录。
- mv:移动或重命名文件或目录。
- rm:删除文件或目录。
- mkdir:创建一个新目录。
- rmdir:删除一个空目录。
- touch:创建一个新文件或更新一个已有文件的最后访问时间和修改时间。
- cat:显示文件内容。
- grep:在文件中查找指定的字符串。
- chmod:修改文件或目录的权限。
- ps:列出当前正在运行的进程。
- kill:终止一个正在运行的进程。
- 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的运算符和引用,有以下几个知识点:
- 算术运算符:+、-、*、/、%等,用于进行数值计算。
- 比较运算符:-eq、-ne、-gt、-lt、-ge、-le等,用于比较数值的大小关系。
- 逻辑运算符:&&、||、!等,用于进行逻辑运算,例如判断多个条件是否成立。
- 字符串运算符:=、!=、-z、-n等,用于判断字符串的相等性、非相等性、长度等。
- 引用:VAR表示引用名为VAR的变量的值。
- 命令替换:反引号或者$()用于执行命令,并用其输出结果来替换命令本身。
判断命令
Shell中的判断命令通常用于在脚本中测试条件,并根据测试结果执行不同的命令或操作。以下是一些常用的Shell判断命令及其用法:
- test命令:test命令用于测试条件,并根据测试结果返回0或1。可以使用test命令检查文件是否存在、检查变量是否为空等。例如,要检查文件是否存在,可以使用以下命令:
if test -e /path/to/file then echo "File exists" else echo "File does not exist" fi
- 命令:[ ] 命令是test命令的一种简写形式。它可以使用与test命令相同的测试条件。例如,以下两个命令是等效的:
if test -e /path/to/file then echo "File exists" fi if [ -e /path/to/file ] then echo "File exists" fi
- [[ ]] 命令:[[ ]] 命令是test命令的一种扩展形式,支持更多的测试条件。例如,可以使用[[ ]]命令判断字符串是否相等、判断变量是否为数字等。以下是一个使用[[ ]]命令的示例:
if [[ "str2" ]] then echo "Strings are equal" fi
分支语句
在shell编程中,常用的分支语句有if语句和case语句。它们的知识点包括:
- if语句:if语句用于根据条件执行不同的操作。它的语法格式为:
if condition then command1 command2 ... else command3 command4 ... fi
其中,condition是一个条件表达式,如果它的值为true,则执行then语句块中的命令,否则执行else语句块中的命令。
- case语句:case语句用于根据不同的条件执行不同的操作。它的语法格式为:
case variable in pattern1) command1 command2 ... ;; pattern2) command3 command4 ... ;; *) command5 command6 ... ;; esac
其中,variable是一个变量,pattern1、pattern2是不同的模式,如果variable匹配某个模式,则执行对应模式下的命令。如果没有任何模式匹配variable,则执行默认的命令。
循环语法
循环语法是编程中常用的一种结构,Shell 也提供了多种循环结构来实现不同的需求。以下是 Shell 中常用的循环语法:
- for 循环:for 循环可以遍历一组数据,并对每个数据执行相同的操作。for 循环的语法如下:
for 变量名 in 取值列表 do 循环体 done
- while 循环:while 循环可以在满足某个条件的情况下一直执行循环体。while 循环的语法如下:
while [ 条件判断语句 ] do 循环体 done
- until 循环:until 循环与 while 循环的执行条件相反,只有在条件不满足的情况下才会执行循环体。until 循环的语法如下:
until [ 条件判断语句 ] do 循环体 done
- select 循环:select 循环可以在多个选项中进行选择,并执行相应的操作。select 循环的语法如下:
select 变量名 in 选项列表 do 循环体 done
函数
shell 函数是一组为了完成特定任务而集合在一起的命令序列,它可以在脚本中任何地方被调用。以下是 shell 函数的语法和知识点:
- 函数的定义:
function_name () { commands }
其中,function_name 是函数名,commands 是需要执行的命令序列。
- 函数的调用:
function_name
可以在脚本中任何地方调用函数,只需要使用函数名即可。
- 函数的传参:
可以向函数传递参数,参数在函数内部通过 $1、$2、$3 等变量来获取,例如:
function_name () { echo "第一个参数: 2" } function_name arg1 arg2
输出结果为:
第一个参数: arg1 第二个参数: arg2
- 函数的返回值:
函数可以返回一个值,返回值通过 return 语句来指定,例如:
function_name () { return 10 } function_name echo "函数的返回值是: $?"
输出结果为:
函数的返回值是: 10
其中 $? 是上一个命令的返回值,也就是函数的返回值。
- 函数的作用域:
函数内部定义的变量和函数外部定义的变量是不同的,函数内部的变量只在函数内部可见,函数外部的变量只在函数外部可见。
shell脚本的执行
- Shell脚本以#!开头,第一行指定脚本解释器的路径。#! /bin/bash
- 启动方式:
-
- 文件名运行: ./filename.sh
- 解释器运行: bash ./filename.sh
- #source 运行
- source ./filename.sh
- 可以使用变量来存储数据。变量名必须以字母或下划线开头,不能以数字开头,可以包含字母、数字和下划线。
- Shell脚本中的注释使用#号开头。
- Shell脚本中可以使用if语句、for循环、while循环等控制语句。
- Shell脚本中可以使用函数,使用function关键字定义函数。
- Shell脚本中可以使用命令替换和变量替换来执行命令和获取命令的输出。
- Shell脚本中可以使用管道和重定向来处理命令的输入和输出。
- Shell脚本中可以使用数组来存储一组数据。
- Shell脚本中可以调用系统命令和外部命令。
- Shell脚本中可以使用正则表达式匹配字符串。
- Shell脚本中可以使用文件操作命令,如创建目录、复制文件等。
- 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展开的一些详细语法:
- 通配符展开
*匹配任意数量的字符(包括0个)?匹配一个任意字符[characters]匹配一个字符集中的任意一个字符{string1,string2,...}匹配多个字符串中的任意一个
- 变量展开
$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命令中指定的操作。这样可以及时发现错误并进行处理。