工程效率配置&Shell&打包等Linux 学习学习提升

shell脚本的编写

2020-09-16  本文已影响0人  wo_monic

鉴于shell的高效、通用,使用shell编写脚本实现日常使用的一些小功能。

处理生成文件的问题

强烈建议,在生成文件之前,先检测文件是否存在,如果存在就删除这个文件。对于使用管道符>指定输出文件时,请一定先检查文件是否存在。现在许多程序运行可能出错,需要重新运行,但是用户基本不会手动删除先前生成的错误的文件,所以我们在输出到文件之前,要先检测之前是否存在
输出文件前,可以请使用下面的命令检测是否存在该文件。

#检测是否存在该文件,如果有,则自动删除旧版本
if [ -e $output ]; then
    echo "之前存在文件$output,自动删除旧版本。"  
    rm -rf $output
fi

1.编写前必知的编写规范

#!/bin/bash
##debug
set -x  #直接输出每次执行的命令
set -e  #程序异常结束时候,输出错误。

1.1 shell脚本开头如上三行。

1.2 检查shell脚本可以使用shellcheck,

sudo apt-get install shellcheck
shellcheck test.sh #检测test.sh的语法是否正确。

1.3 在bash,如果不加 local 限定词,变量默认都是全局的。

对于在函数内声明的变量,请务必记得加上 local 限定词。

1.4 trap函数的使用

对于程序结束的方式进行判断,如果正常结束,则执行命令1,错误则执行命令2,如果是Ctrl+C终止,可以执行命令3.

trap "echo end analysis" EXIT   #程序退出时执行,无论是正常退出,还是错误退出。
trap "echo there have a error" ERR  #出错时,执行

2. 基础shell语法

shell脚本的执行方式
方法1:bash test.bash
方法2:

chmod 757 test.bash
./test.bash
变量

shell变量:要求等号后面紧跟变量,不能有空格
例如:Name=Zhangsan
shell中双引号和单引号,如果引号内有变量,使用双引号。单引号内部的字符不会被转变为变量。
引用变量方式:$Name或者${Name},一般推荐变量引用的时候,都加上大括号,不然后面某些时候,拼接字符串的时候会出现无法识别变量名的问题。
只读变量 readonly Name 上面的Name变量就变成只读变量,不能被修改。
删除变量 unset variable_name
局部变量 默认的变量都是全局变量
local age=18

字符串操作

拼接字符串

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1
#输出内容
#hello, runoob ! hello, runoob !

查找字符串(使用正则expr index )

string="runoob bilideise site"
echo `expr index "$string" o`  # 输出 4  

获取字符串长度 ${#string}

string="abcd"
echo ${#string} #输出 4

提取字符串,第2:4个。

string="runoob is a great site"
echo ${string:1:4} # 输出 unoo

bash中的index下标从0开始。0是第一个。

数组

array_name=(value0 value1 value2 value3)或者单独定义array_name[4]=value4
获取数组第1个元素 ${array_name[0]}
获取数组所有元素 ${array_name[@]}
获取数组元素个数 length=${#array_name[@]}
获取某个元素的长度arr1_length=${#array_name[1]}

注释符号

单行注释#
多行注释

<<!
此处是区块注释
多行注释文本
多行注释文本
!
参数传递

传参分为$1,$2,……$n代表传入的第1,2,n个参数。
$0代表执行的文件(包括路径)
$#传入参数的个数
$*传入的所有参数(以一个单字符显示)
$@传入的所有参数(依次显示每个参数)
$$脚本运行的当前进程id
$!后台运行的最后一个进程id
$?显示命令最后退出的状态,如果不是0,则代表程序没有正常结束。
``

if [ -n "$1" ]; then
    echo "包含第一个参数"
else
    echo "没有包含第一参数"
fi

算术比较, 比如一个变量是否为0,[ $var -eq 0 ]
文件属性测试,比如一个文件是否存在,[ -e $var ], 是否是目录,[ -d $var ]
字符串比较, 比如两个字符串是否相同, [[ $var1 = $var2 ]]

运算符

算术运算符+ - * / % 加减乘除整除取余
=是赋值,==!=仅用于数字比较。
运算符使用时,必须在中括号内,且两边均有空格。
例如:[ 5==5.0 ]
关系运算符(仅限于数字之间比较)
-eq -ne -gt -lt -ge -le依次是相等,不等,大于,小于,大于等于,小于等于
逻辑运算符
! -o -a 非;或;与
&&||
字符串运算符
= != 等于 ;不等于
-z 字符串长度为0,则返回true
-n字符串长度不为0,则返回true
$ 检查字符串是否为空,不为空返回true.
文件运算符
-d检查文件是否是目录,是,则返回true
-r 检测文件是否可读
-w检测文件是否可写
-x检测文件是否可执行
-s检测文件是否为空,不为空则返回true
-e检测文件(或目录)是否存在,是,则返回true
-L 检测文件是否存在并且是一个符号链接

echo命令
输出换行echo -e "this is a new line! \n"

shell流程控制

shell里面else里面如果没有东西,就不要写else.
流程控制里不能为空。

if [ $age -ge 18 ] then
  echo "成年人!"
else
  echo “未成年!”
fi

多组if-elif-else-fi

if [ $age -lt 18 ] then
  echo "未成年"
elif [ $age -ge 60 ] then
  echo "老年人"
else
  echo "青年和中年"
fi

每组的if后一定要有then。

循环

for循环

for var in `ls namefile`
do
  echo $var
done
#for循环实例
for((i=1;i<=5;i++));do
    echo "这是第 $i 次调用";
done;

while循环

int=1
while(( $int<=5 ))
do
  echo $int
  let "int++"
done

无限循环

while true
do
  ping www.baidu.com
done
case
echo "输入1到4之间的数字"
read aNum
case $aNum in
  1) echo "输入的是1"
  ;;
  2) echo "输入的是2"
  ;;
  *) echo "您输入的不在范围"
  ;;
esac

中断或者跳出循环的方法
break终止后续循环
continue中止当前循环,后续循环继续运行。

函数的定义

3.实战1:编写两个文件合并的小教本

因时间仓促,写了简单的脚本,以其能够理解其原理和shell语法。脚本在github.下载后,直接运行命令commerge -h即可。如果不能执行,请添加执行权限即可chmod 757 commer

上一篇 下一篇

猜你喜欢

热点阅读