Shell脚本和编程(五) | 青训营笔记

86 阅读1分钟

今天是参加笔记活动的的第12

函数

语法

语法一

funcName(){echo "abc";}

语法二

function funcName() {echo"abc";}

注意

  • shell自上而下执行,函数必须在使用前定义
  • 函数获取变量和shell script类似,0代表函数名,后续参数通过0代表函数名,后续参数通过1,$2获取
  • 函数内return仅仅表示函数执行状态,不代表函数执行结果
  • 返回结果一般使用echo,printf,在外面使用$(),``获取结果
  • 如果没有return,函数状态是上一条命令的执行状态,存储在$?中

函数也是命令 exit:手动退出 shell 、命令 exit 10 返回 10 给 shell,返回值非 0 为不正常退出 $? 用于判读昂当前 shell 前一个命令是否正常退出(非 0 为不正常退出) 为了函数内定义的变量不污染全局, 我们最好使用 local 去定义, 或者在函数退出之前使用 unset 去处理一下

模块化

模块化的原理是在当前shell内执行函数文件,方式为 source [函数库的路径]

#!/bin/bash#add函数
#@return platForm
function add() {
    declare -i res=$1+$2
    echo $res
}

转换为

#!/bin/bashsource './math.sh'
​
total=$(add 1 2)
​
echo $total

常用命令

命令使用
grep查找错误日志: grep -n "ERROR" -A3 -B3 cloudfun.log 统计次数: grep -n "ERROR" -c cloudfun.log
sort指定分隔符后以第三列进行排序: sort -t " " -k 3
wc统计出现的行数,单词数,字符数 wc -lwm
head查看前十行: head -n 10 cloudfun.log
tail等待追加内容: tail -f -n 10 cloudfun.log
cut对数据行的内容进行处理: cut -d " " -f 3
find文件和目录查找
xargs参数处理
which查找命令路径

执行过程和原理

执行

1.shell脚本一般以.sh结尾,也可以没有,这是一个约定:第一行需要指定用什么命令解释器来执行

#!/bin/bash
#!/usr/bin/env bash

2.启动方式

#文件名运行
./filename.sh
​
#解释器运行
bash ./filename.sh
​
#source运行
source ./filename.sh

#!是内核识别并选择合适的解释器之后,将文本文件再交给解释器执行

执行过程

1.字符解析

  • 识别换行符,分号(;)做行的分割
  • 识别命令连接符(|| && 管道)做命令的分割
  • 识别空格,tab符,做命令和参数的分割

2.shell展开,例如{1..3}解析为 1 2 3

3.重定向,将stdin,stdout,stderr的文件描述符进行指向变更

4.执行命令

  • builtin直接执行
  • 非builtin使用$PATH查找,然后启动子进程执行

5.收集状态并返回

这个架构类似一个流水线,在里面进行输入分析和解析 bash 会以一些特殊字符作为分隔符,将文本进行分段解析。最主要是回车还有分号";"。在 bash 脚本中是以回车或者分号作为一行命令结束的标志。这就是第一层级的解析,将大段的命令行进行分段 符号拓展(使用各种方法,比如大括号 {} 、波浪符 ~ 、变量和参数的展开/替换、文件名展开),并最终执行命令(通过 shell 内置命令或外部命令)。