运维linuxshell编程之函数使用(代码片段)

逆风飞翔的小叔 逆风飞翔的小叔     2022-12-07     614

关键词:

前言

使用linux的shell编程,可以说函数是非常重要的内容,也是在编写各类shell脚本的时候经常用到的,本篇将介绍下函数相关的使用。

shell 函数分类

  • 系统函数
  • 自定义函数

系统函数

系统函数为linux自带的函数, 可以在shell编写中直接使用。下面介绍几种常用的系统函数

1、basename

用于获取文件名函数, 根据给出的文件路径截取出文件名;

语法

basename [string / pathname] [suffix]  

  • 根据根据指定字符串或路径名进行截取文件名, 比如: 根据路径"/root/shells/aa.txt", 可以截取出aa.txt;
  • suffix: 用于截取的时候去掉指定的后缀名;

简单案例

比如在当前目录下,有一个叫ch1.sh的文件,使用该命令的效果如下

 

该命令的用途

  • 遍历某个文件目录之后,可以使用该命令拿到该目录下的文件名称做后续处理;
  • 拿到文件名称之后,更改某个匹配的文件的权限等;

2、dirname

从指定文件的绝对路径, 去除文件名,返回剩下的前缀目录路径

语法

dirname 文件绝对路径

简单案例

 

更多的系统函数,可以使用: declare -f 命令进行查看

自定义函数

shell编程人员可以通过自定义开发函数,实现代码重用,提升模块的封装性、可读性以及可维护性;

语法

# 函数的定义
[ function ] funname ()

    命令
    [return 返回值]

# 调用函数
funname 传递参数1 传递参数2 ...

语法说明

  • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数;
  • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值, return后跟数值n(0~255);

注意点

必须在调用函数地方之前,先声明函数再调用,shell脚本是逐行运行的, 只有先运行了函数, 后面的动作才可以使用函数;

案例1:无参无返回值函数

#!/bin/bash

hello()

        echo "hello func"




hello

调用下这个脚本,观察效果展示

 

案例2:无参有返回值函数

#! /bin/bash

function sum()

    echo "求两个数的和..."
    read -p "请输入第一个数字: " n1
    read -p "请输入第二个数字: " n2
    echo "两个数字分别为 $n1 和 $n2 "
    return $(($n1+$n2))


sum

echo "两个数字的和为: $? "  # 获取函数返回值

运行上面的shell,观察输出效果

案例3:有参函数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1 表示第一个参数,$2 表示第二个参数...

其他参数介绍

参数处理说明
$#传递到脚本或函数的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

案例介绍

使用上面的参数编写一个输出用户输入参数的示例

#!/bin/bash
funParam()
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 $10 !"
    echo "第十一个参数为 $11 !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"


funParam 1 2 3 4 5 6 7 8 9 10 11 12 15

 

调用上面的脚本观察效果

补充:Shell程序与函数的区别

函数和shell程序比较相似,区别在于:

  • Shell 程序(内置命令和外部脚本文件), 外部脚本文件是在子Shell中运行, 会开启独立的进程运行;
  • Shell函数在当前Shell的进程中运行;

linux shell编程常用案例介绍

以下结合前面关于shell编程技术点的介绍,列举常用的一些可以使用shell编程来处理的场景

1、日志(数据)备份

比如生产环境下,为了保留每天的核心日志,可以使用定时任务,调度某个shell脚本,在脚本中编写程序用于备份日志数据

 

参考示例

#!/bin/bash  

tar  -zcvf  log-`date +%Y-%m-%d`.tar.gz log-`date +%Y-%m-%d` /var/log   
  

2、监控内存和磁盘容量,小于给定值时报警

当生产服务器的内存和磁盘容量不足时,可以通过编写shell进行监控报警

参考示例

#!/bin/bash  
  
  
# 提取根分区剩余空间  
disk_size=$(df / | awk '/\\//print $4')  
  
# 提取内存剩余空间  
mem_size=$(free | awk '/Mem/print $4')  
while :  
do  
# 注意内存和磁盘提取的空间大小都是以 Kb 为单位  
if  [  $disk_size -le 512000 -a $mem_size -le 1024000  ]  
then  
    mail  ‐s  "Warning"  root  <<EOF  
  Insufficient resources,资源不足  
EOF  
fi  
done  

3、查看有多少远程 IP 连接本机

参考示例

#!/bin/bash  
  
# 查看多少远程 IP 连接本机(不管是通过 ssh 还是 web 还是 ftp 都统计)   
# 使用 netstat ‐atn 可以查看本机所有连接的状态,‐a 查看所有,  
# -t仅显示 tcp 连接的信息,‐n 数字格式显示  
# Local Address(第四列是本机的 IP 和端口信息)  
# Foreign Address(第五列是远程主机的 IP 和端口信息)  
# 使用 awk 命令仅显示第 5 列数据,再显示第 1 列 IP 地址的信息  
# sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数  

netstat -atn  |  awk  'print $5'  | awk  'print $1' | sort -nr  |  uniq -c  

4、编写nginx启动脚本

在实际的运维中,很多中间件服务,为了方便管理各个中间件服务,可以考虑将其做成各类启动脚本,统一维护,下面以nginx为例说明(其他的,比如redis,zk等可以类似的参考进行编写);

#!/bin/bash  
  
# 脚本编写完成后,放置在/etc/init.d/目录下,就可以被 Linux 系统自动识别到该脚本  
# 如果脚本名为/etc/init.d/nginx,则 service nginx start 就可以启动该服务  
# service nginx stop 就可以关闭服务  
# service nginx restart 可以重启服务  
# service nginx status 可以查看服务状态  
program=/usr/local/nginx/sbin/nginx  
pid=/usr/local/nginx/logs/nginx.pid  
start()  
if [ -f $pid ];then  
  echo  "nginx 服务已经处于开启状态"  
else  
  $program  
fi  
stop()  
if [ -! -f $pid ];then  
  echo "nginx 服务已经关闭"  
else  
  $program -s stop  
  echo "关闭服务 ok"  
fi  
  
status()  
if [ -f $pid ];then  
  echo "服务正在运行..."  
else  
  echo "服务已经关闭"  
fi  
  
  
case $1 in  
start)  
  start;;  
stop)  
  stop;;  
restart)  
  stop  
  sleep 1  
  start;;  
status)  
  status;;  
*)  
  echo  "你输入的语法格式错误"  
esac  

linuxshell编程(代码片段)

linuxshell编程1.shell脚本概述2.脚本的调用形式3.shell脚本语法3.1脚本开头标识3.2脚本注释3.3给脚本加上可执行权限3.4shell脚本的运行方式3.5检测脚本是否正确3.6重定向的使用3.7获取上一条命令的执行结果4.变量4.1变量的定义和使用4.2... 查看详情

linuxshell之递归读取指定目录下的所有文件(代码片段)

使用shell递归读取指定目录下的所有文件,代码如下:#!/bin/bash#采集一个函数readDir()#获取传入的目录路径localdir=$1#循环指定目录下的所有文件localfilesfiles=$(ls"$dir")forfilein$files;dolocalpath="$dir/$file"#指的... 查看详情

linuxshell编程(代码片段)

linuxshell编程1.shell脚本概述2.脚本的调用形式3.shell脚本语法3.1脚本开头标识3.2脚本注释3.3给脚本加上可执行权限3.4shell脚本的运行方式3.5检测脚本是否正确3.6重定向的使用3.7获取上一条命令的执行结果4.变量4.1变量的定义和使用4.2... 查看详情

网络编程之select(代码片段)

一select函数简介  select一般用在socket网络编程中,在网络编程的过程中,经常会遇到许多阻塞的函数,网络编程时使用的recv,recvfrom、connect函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法执... 查看详情

linuxshell编程参考大全(代码片段)

  本文记录LinuxShell编程中常用基本知识,方便快速入门以及查询使用。  本文主要分为以下几个部分:一、Shell中的变量  任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识。0... 查看详情

linuxshell编程参考大全(代码片段)

  本文记录LinuxShell编程中常用基本知识,方便快速入门以及查询使用。  本文主要分为以下几个部分:一、Shell中的变量  任何编程语言中,有关变量的定义,作用范围,赋值等都是最最基础的知识。0... 查看详情

编程实践linuxshell编程:使用循环和递归实现斐波那契数列代码(代码片段)

用LinuxShell编程语言递归实现斐波那契数列代码:循环和递归LinuxShell编程语言是一种强大的工具,它可以轻松地实现程序设计语言中的常见算法。斐波那契数列斐波那契数列是一种经典的算法,它的定义如下:斐... 查看详情

socket编程之使用fsockopen()函数(代码片段)

fsockopen函数:初始化一个套接字连接到指定主机(hostname)get方式:client.php1<?php2//创建连接3$fp=fsockopen(‘localhost‘,80,$error,$errstr,10);45//检测6if(!$fp)7echo$errstr;die;8910//拼接http请求报文11$http=‘‘;1213//请求报文包括3部分请求行请... 查看详情

scala编程之惰性函数(代码片段)

...惰性函数惰性计算(尽可能延迟表达式求值)是许多函数式编程语言的特性。惰性集合在需要时提供其元素,无需预先计算它们,这带来了一些好处。首先,您可以将耗时的计算推迟到绝对需要的时候。其次,您可以创造无限个集合,只... 查看详情

linux编程之非局部跳转:longjmpsiglongjmp(代码片段)

在同一个函数中,我们可以使用goto修改程序的执行逻辑。如果在多个函数中,想要修改函数的执行顺序(从一个函数,返回到之前函数的某个预定义逻辑),怎么办呢?答案是使用longjmp或siglongjmp。本文主要内容:文章目录longjm... 查看详情

函数式编程之-f#类型系统(代码片段)

在深入到函数式编程思想之前,了解函数式独有的类型是非常有必要的。函数式类型跟OO语言中的数据结构截然不同,这也导致使用函数式编程语言来解决问题的思路跟OO的思路有明显的区别。什么是类型?类型在编程语言中有... 查看详情

linux编程之非局部跳转:longjmpsiglongjmp(代码片段)

在同一个函数中,我们可以使用goto修改程序的执行逻辑。如果在多个函数中,想要修改函数的执行顺序(从一个函数,返回到之前函数的某个预定义逻辑),怎么办呢?答案是使用longjmp或siglongjmp。本... 查看详情

es6异步编程解决方案之async(代码片段)

一、async函数的基本用法async函数返回一个Promise对象,可以使用then、catch方法添加回调函数async函数执行时,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句【异步函数同步执行】async函数有很多种... 查看详情

编程规范之书写规范(代码片段)

目录编程规范之书写规范1.每个缩进层级使用4个空格2.每行最多79个字符3.顶层函数或类的定义之间空两行4.采用UTF-8编码文件(通用编码格式)5.每行只使用import导入一个模块(分组标准库、三方库和本地库)6.在小括号、中括号... 查看详情

rust编程语言入门之编写自动化测试(代码片段)

编写自动化测试一、编写和运行测试测试(函数)测试:函数验证非测试代码的功能是否和预期一致测试函数体(通常)执行的3个操作:准备数据/状态运行被测试的代码断言(Assert)结果解剖测试函数测试函数需要使用test属性... 查看详情

笔记效率之门——python中的函数式编程技巧(代码片段)

文章目录Python函数式编程1.数据2.推导式3.函数式编程3.1.Lambda函数3.2.python内置函数3.3.高阶函数4.函数式编程的应用Python函数式编程我的AIStudio项目:【笔记】LearnDL第三课:Python高级编程——抽象与封装-飞桨AIStudio(baidu.com)p... 查看详情

极简教程linuxshell脚本编程(代码片段)

目录     shellscript简介shellscript执行shellscript编写shellscript重要功能shellscript追踪与调试#批量kill全部java进程ps-ef|grepjava|awk\'print$2\'|xargskill-9shellscript简介shellscript是利用shell的功能所写的一个程序, 查看详情

函数式编程之-模式匹配(patternmatching)(代码片段)

模式匹配在F#是非常普遍的,用来对某个值进行分支匹配或流程控制。模式匹配的基本用法模式匹配通过match...with表达式来完成,一个完整的模式表达式长下面的样子:match[something]with|pattern1->expression1|pattern2->expression2|pattern3... 查看详情