Linux高级Shell脚本讲解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux高级Shell脚本讲解相关的知识,希望对你有一定的参考价值。

Shell高级进阶

条件选择if语句,可实现条件性判断

if语法:if commands;then commands(如果命令为真,将执行后续命令,fi结尾;)

       elif commands;then commands(如果前面if不为真,则判断elif是否为真,为真则执行后面的命令,可以写多个elif,可写可不写,条件多的情况下添加)

       else commands;then commands(如果上述全都不为真,则继续判断else是否为真,为真则执行后续命令)

       if true;then echo true;f1(如果true为真,则执行后续命令,结束)


条件判断;case

case 变量 in 

case语法:case word in [模式 [|模式 commands]...

case "变量" in

PAT1) (判断变量是否匹配PAT1,匹配的话则执行以下命令)

   分支1

   ;;

PAT2) (如果前面变量不匹配就执行以下命令)

   分支2

   ;;

...

*) (如果变量前面都不匹配就匹配这个)

   默认分支

   ;;

esac

使用的global风格语法,通配符

 *: 任意长度任意字符 

 ?: 任意单个字符 

 []:指定范围内的任意单个字符 

 a|b: a或b 


循环

将某代码段重复运行多次

重复运行多少次: 

       循环次数已知

       循环次数未知

有进入条件和退出条件

for,while,until


for循环

   for 变量名 in [word ....];do commadns; done

例子:

for num in 1 2 3 4

do

echo "num is $num"

done

上述数字内容写几个单词就循环几次


列表生成方法:

(1)直接给出列表

(2){}从起始到结束;比如:{1..10}(1-10);{1..10..2}递减2

(3)用命令生成列表

(4)使用glob,如:*.sh

(5)变量引用:[email protected],$*


while循环

     while commands(进入循环和终止循环的条件);do commands;done(当什么时候条件满足继续循环,当条件不满足将停止循环)

     

select循环与菜单

select 变量 in list (将列表数据分别赋予变量并且赋予序号,适用于菜单,PS3这个变量是专用于select做提示符使用的,$REPLY系统自带的变量,存输入的字符串)

do

循环体命令

done


信号捕捉trap

trap '触发指令' 参数

     当捕获到参数的操作的信号的时候将触发前面的指令

trap '' 参数

      忽略信号

trap '-' 参数

      恢复原信号的操作,也就是将上面的trap操作取消

trap -p 

      列出自定义操作


函数介绍

更加方便代码重用,也适用于模块化编程,相当于别名,别名是一条命令定义,而函数就相当于一个函数定义多条指令


定义函数

函数由两部分组成:函数名和函数体

语法一:

      f_name (){

...函数体...

}

语法二:

      function f_name {

...函数体...

       }

语法三:

      function f_name () { 

  ...函数体... 

f_name 执行函数

unset f_name 取消函数定义

定义的函数在哪个终端就得在哪个终端执行,别的终端无法执行

declare -f(查看定义的所有函数)


函数使用(先定义再调用)

函数一般不会在交互式环境中使用,基本都在脚本中使用

可将定义的函数单独放在一个文件中,脚本中调用函数文件的方法 source '文件名称'

/etc/init.d/function(系统专门存放函数的文件)

return 10(结束当前函数,并且$?返回值为10,并不代表结束)

local是一个特殊的关键字,只能在函数中使用;函数中如果不使用local的话,则函数中定义的变量,shell中可以使用,shell中定义的变量,函数中也可以调用,使用local的话则是只在函数中使用

子进程不能调用父进程中定义的函数,但可以使用export -f f_name将函数转换为环境函数


数组

将同一类型的数据取一个变量名字,数组的名称和数组的下标组合起来就能代表变量的唯一,从0表示第一个下标,最后一个下标的元素个数就为n-1,数字下标则成为数值索引

索引可支持自定义索引,而不止是数值索引,即为关联索引,bash4.0之后支持(bash --version)


bash的数组支持稀疏格式(索引不连续)

声明数组:

       declare -a "数组名称"

       declare -A "数组名称"(关联数组;自定义索引的为关联数组,先声明再调用)

数组赋值

(1)一次只赋值一个元素

   "数组名称[索引]"="值"

(2)一次赋值全部元素

   ARRAY_NAME=("VAL1" "VAL2" "VAL3")

(3)只赋值特定元素

   ARRATY_NAME=([0]="VAL1" [3]="VAL2")稀疏格式的时候不能以这种方法补全

(4)交互式赋值

   read -a

引用数组

echo ${ARRAY_NAME[INDEX]}显示某个特定的数组中的索引

引用数组所有元素

echo ${ARRAY_NAME[*]}显示所有数组索引

数组的长度(数组中元素的个数)

${#ARRAY_NAME[*]}

${#ARRAY_NAME[@]}

删除数组中指定元素

unset 数组[数字]

删除整个数组中的元素

unset 数组


数组数据处理

引用数组中的元素:

   数组切片:${ARRAY[@]:offset:number}

            offset:要跳过的元素个数

            number:要取出的元素个数

            取偏移量之后的元素

                 ${ARRAY[@]:offset}

向数组中追加元素:

ARRAY[${#ARRAY[*]}]=value


字符串切片

${#变量名}:返回字符串变量名的长度

${变量名:offset}:跳过offset

${变量名:offset:number}:跳过offset取number个

${变量名: -offset}:取倒数三个

${变量名:offset:-number}:去掉前面offset个,也去掉后number个

${变量名: -offset:-number}:取后面offset个,取出的offset中去掉number个,在7里面用


字符串处理

基于模式取字串

   ${变量名#*word}:其中word可以使指定的任意字符

         功能:从左往右,查找"变量名"所存储的变量值,匹配到后将匹配到的字符以及匹配到的字符前面的字符全部删除,问号代表一个 单独字符;

  ${变量名##*word}:同上,贪婪模式,删除的是字符串开头到最后一次由word指定的字符之间的所有内容

  ${变量名%word*}:从右向左,查找变量所存储的字符串中,第一次出现的word,删除从右向左发现的第一个匹配的word以及word右面的所有字符

  ${变量名%%wird*}:从右向左,贪婪模式,删除的是字符串开头到最后一次由word指定的字符之间的所有内要

查找替换

  ${变量/匹配的字符串/新替代的字符串}:查找变量所表示的字符串中,匹配的字符串替换为新替代的字符串,默认只替代第一次匹配到的

  ${变量//匹配的字符串/新替代的字符串}:贪婪模式,替换所有匹配到的字符串

  ${变量//#匹配的字符串/新替代的字符串}:替换以匹配的字符串开头的行

  ${变量/%匹配的字符串/新替代的字符串}:替换以匹配的字符串结尾的行

  ${变量/匹配的字符串}:删除匹配的字符串,非贪婪模式

  ${变量//匹配的字符串}:贪婪模式,删除所有匹配的字符串

  ${变量/#匹配的字符串}:删除以匹配的字符串开头的字符串

  ${变量/%匹配的字符串}:删除以匹配的字符串结尾的字符串

  ${变量^^}:将变量的值转换为大写

  ${变量,,}:将变量的值转换为小写


var=${str-"expr"};当str没有值的时候:var=expr;当str值为空的时候:var=$str;当str有值的时候:var=$str

var=${str:-expr};当str没有值的时候:var=expr;当str值为空的时候:var=expr;当str有值的时候:var=$str

........


高级变量用法-有类型变量

Shell变量一般是无类型的,但是bash shell提供了declare用于指定变量类型,bash中只支持整数

declare [选项] 变量名

 -r 声明或显示只读变量

 -i 声明整数

 -a 将变量定义为数组

 -A 将变量定义为关联数组

 -f 显示已定义的函数内容

 -F 显示已定义的所有的函数名

 -x 声明环境变量和函数

 -l 声明变量为小写字母

 -u 声明变量为大写字符


eval命令

eval命令会将命令进行两次扫描,在第一次扫描的时候,查看目标是否为变量,有值的话则会置换,第二次扫描则执行


间接变量引用

如果第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用

variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为

 variable1=variable2 

 variable2=value


mktemp:创建临时文件,并且显示

mktemp [OPTION]... [TEMPLATE] 

 TEMPLATE:filenameXXX 

 X至少要出现三个

OPTION:

  -d:创建临时目录

  -p:指明临时文件所存放目录位置


安装复制文件

install命令:

  install [option] 源文件 目标文件

  install [option] 源 目标

  install [option]

选项option:

  -m MODE,默认权限755

  -o OWNER:指定属主

  -g GROUP:指定属组

  -d 指定目录


expect介绍

      主要应用于自动化交互式操作的场景,将交互式的操作改为非交互式的操作

expect语法:

expect [选项] [-c command] [[ -[f|b] ] cmdfile ] [ args ]

选项:

    -c:从命令行执行expect脚本,默认expect是交互执行的

    -d:可以输出调试信息

expect中相关命令

spawn:启动新的进程

send:用于向进程发送字符串

expect:从进程接收字符串

interact:允许用户交互

exp_continue 匹配多个字符串在执行动作后加此命令


expect最常用的语法(模式-动作)

      单分支:expect "hi" {send "You said hi\n"}(捕获hi,而输入别的没有反应)

      多分支

            expect "hi" { send "You said hi\n" } \ (发现hi打印You said hi)

                   "hehe" { send "Hehe yourself\n" } \ (发现hehe打印Hehe yourself)

                   "bye" { send "Good bye\n" }(发现bye打印Good bye)



一:

#!/usr/bin/expect 

spawn scp /etc/fstab 用户@对方IP地址:/app 

expect {

        "yes/no" { send "yes\n";exp_continue } 

        "password" { send "fang\n" } 

}

expect eof


二:

#!/usr/bin/expect 

spawn ssh 用户@对方IP地址

expect {

        "yes/no" { send "yes\n";exp_continue } 

        "password" { send "用户密码\n" } 

}

expect eof

interact(执行完上述命令不退出执行交互式命令)


三:

#!/usr/bin/expect 

set ip "IP地址"(定义名为ip的变量,值为后方ip地址) 

set user "用户名"      (定义名为user的变量,值为root)

set password "密码"

set timeout 10 

spawn ssh [email protected]$ip 

expect { 

        "yes/no" { send "yes\n";exp_continue } 

        "password" { send "$password\n" } 

interact


#!/usr/bin/expect 

set ip [lindex $argv 0](定义名为ip的变量,值为第一个参数)  

set user [lindex $argv 1] (定义名为user的变量,值为第二个参数)

set password [lindex $argv 2] (定义名为password的变量,值为第三个参数)

spawn ssh [email protected]$ip 

expect { 

        "yes/no" { send "yes\n";exp_continue } 

        "password" { send "$password\n" } 

interact


五:Bash中调用expect

#!/usr/bin/expect 

#!/bin/bash 

ip=$1  

user=$2 

password=$3 

expect <<EOF 

set timeout 10 

spawn ssh [email protected]$ip 

expect { 

        "yes/no" { send "yes\n";exp_continue } 

        "password" { send "$password\n" } 

expect "]#" { send "useradd hehe\n" } 

expect "]#" { send "echo magedu |passwd --stdin hehe\n" } 

expect "]#" { send "exit\n" } 

expect eof 

EOF


以上是关于Linux高级Shell脚本讲解的主要内容,如果未能解决你的问题,请参考以下文章

Shell脚本编程入门详细讲解视频教程

linux基础学习-17-linux操作系统之Shell编程基础讲解

Linux-shell脚本基础

《Linux Shell 脚本攻略》读书笔记

Linux系统之Shell脚本简介

深入讲解丨Shell脚本单行和多行注释