Shell编程从入门到实践

您所在的位置:网站首页 shell传递参数到另一个脚本里 Shell编程从入门到实践

Shell编程从入门到实践

2023-06-28 17:07| 来源: 网络整理| 查看: 265

欢迎关注 「Android茶话会」 

回 「学习之路」 取Android技术路线经典电子书 回 「pdf」 取阿里&字节经典面试题、Android、算法、Java等系列武功秘籍。 回 「天涯」 取天涯论坛200+精彩博文,包括小说、玄学等 背景

之前在搞一些CI/CD,使用到了shell脚本,shell的开箱即用确实比较方便,至少无需在宿主上安装运行环境,本篇文章主要解释shell脚本实践过程中一些经验总结。

本篇是 实践篇

入门篇在 mp.weixin.qq.com/s?__biz=MzU…

模块化

刚开始看一些之前的shell脚本,一个脚本大几百行,很少有函数的情况,其实shell脚本也可以函数化,按照模块的拆分,这样就会带来良好的可读性和可维护性,通常我们会先定义main函数,将功能分解为一个个子函数

模块化之前 模块化之前 模块化之后 模块化之后 #!/bin/bash localvar="fun1" main() {     func1     func2 } func1() {     local localvar="funlocal"     echo ${localvar}     localvar="fun2" } func2() {     echo ${localvar} } main "$@" 函数

函数是模块化的基础,一个函数往往负责一件事件

函数名后面的圆括号不加任何参数 函数的完整定义必须置于函数的调用之前 函数名 (){  函数体 } 传参 #!/bin/bash print_something(){     echo "hello $1" # $1 获取第一个参数 } print_something Lion # Lion 为参数 print_something Frank # Frank 为参数 $1~$9:函数的第一个到第9个的参数。 $0:函数所在的脚本名。 $#:函数的参数总数。 $@:函数的全部参数,参数之间使用空格分隔。 $*:函数的全部参数,参数之间使用变量$IFS值的第一个字符分隔,默认为空格,但是可以自定义。 $?:显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。可以用于函数返回值 返回值 testFun(){     echo "helloworld!"     return 99 } # 千万要注意shell并不像其他语言直接返回返回值,其返回值放到$?中,这也是为什么只能返回整型的原因 # 所以这种承接方法是错误的,获取到的值是echo打印的内容 # return_value=`testFun` # 以下才是正确获取通过return返回的返回值的正确写法 testFun echo "the return value is: $?" 局部变量 不做特殊声明,shell中变量都是全局变量 局部变量 使用 「local」 关键字,函数内外同时存在同名变量,则函数内部会覆盖函数外部变量 脚本之间引用

模块化之后多个脚本和公共参数之间是可以相互复用的 这时候可以通过 souce或者点号来调用所需要的脚本

source ./util.sh . ./util.sh 错误处理

如果什么都不做,在shell中命令出错也不影响,默认会继续执行,这会带来麻烦,有时候我们需要区分业务错误和系统错误,比如在脚本执行遇到系统错误之后就应该退出,遇到业务错误,需要根据业务错误来确定是否往下执行,有以下几种方式来控制shell的错误

set 命令 set -e

只要脚本发生错误就终止执行,set +e表示关闭-e选项,set -e表示重新打开-e选项,但是要注意这个命令不适与管道操作

set +e command1 command2 set -e

管道处理需要借助

set -o pipeline

通常我们会把这些命令放在一起使用

# 写法一 set -Eeuxo pipefail # 写法二 set -Eeux set -o pipefail 短路符号

如果command正常退出,返回0,|| 运算符右半部分被短路,脚本继续执行。 如果command异常退出,返回非0, 运算符右半部分执行,脚本exit 1。

command || exit 1 # 写法一 command || { echo "command failed"; exit 1; } # 写法二 if ! command; then echo "command failed"; exit 1; fi # 写法三 command if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi 使用trap 捕获信号量

用来在bash脚本中响应系统信号,trap命令必须放在脚本的开头。否则,它上方的任何命令导致脚本退出,都不会被它捕获。标准格式

$ trap [动作] [信号1] [信号2] ...

HUP:编号1,脚本与所在的终端脱离联系。 INT:编号2,用户按下 Ctrl + C,意图让脚本终止运行。 QUIT:编号3,用户按下 Ctrl + 斜杠,意图退出脚本。 KILL:编号9,该信号用于杀死进程。 TERM:编号15,这是kill命令发出的默认信号。 EXIT:编号0,这不是系统信号,而是 Bash 脚本特有的信号,不管什么情况,只要退出脚本就会产生。

$ trap 'rm -f "$TMPFILE"' EXIT

表示 脚本遇到EXIT信号时,就会执行rm -f "$TMPFILE"

调试

也没有特别好的办法,可以让不同级别的日志打印出不同的颜色

function debug() {     echo -e "\033[37m$1\033[0m" } function infolog() {     echo -e "\033[32m$1\033[0m" } function warn() {     echo -e "\033[33m$1\033[0m" } function error() {     echo -e "\033[31m$1\033[0m" } 其他细节 预定义默认值 ${varname:-word} varname存在且不为空,则返回它的值,否则返回word ${varname:=word} varname存在且不为空,则返回它的值,否则将它设置为word并返回word ${varname:+word} varname存在且不为空,在返回word,否则返回空值,它的目的是测试变量是否存在 ${varname:?message} 如果变量varname存在且不为空,则返回它的值,否则打印出varname: message,并中断脚本的执行,它的目的是防止变量未定义 ()与{}的区别

前者用于命令执行,返回命令返回值

all_files=`ls` # 获取ls命令的执行结果 all_files=$(ls) # 效果同上

后者用于变量展开

echo ${A}B []和[[ ]] 、(())

在使用[]或者test指令进行字符串判空时,需要在引用的变量上加上双引号""。 如果使用[[]]的话就不需要。 $(())用来做整数运算的

curl中携带参数

curl中需要用单引号,数字和字符还不一样,注意tesMsg

jobId="78707463" tesMsg="msg:需要找专人审批" curl -X POST https://xxxx/openapi/xxxx/job/update_msg -H "Content-Type: application/json" -d '{ "jobId":'$jobId', "jobMsg":"'"${tesMsg}"'" }' 回 「学习之路」 取Android技术路线经典电子书 回 「pdf」 取阿里&字节经典面试题、Android、算法、Java等系列武功秘籍。 回 「天涯」 取天涯论坛200+精彩博文,包括小说、玄学等

您的 点赞、评论、转发 是对我的巨大鼓励!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3