精选文章 函数及expect

函数及expect

作者:lc01081314 时间: 2021-02-05 08:53:31
lc01081314 2021-02-05 08:53:31
【摘要】在写脚本的时候,会经常用到某些算法、命令集等,如果每次都要重新再写一遍,就非常浪费时间,所以就需要用到函数来解决这个问题了。而且有时候会遇到交互式的情况,那么该怎么办呢?except就是用来解决这种情况的。那么接下来就看一下函数及expect的用法吧。一、函数   1、定义函数的定义:f_name(){     ...函数体...

   在写脚本的时候,会经常用到某些算法、命令集等,如果每次都要重新再写一遍,就非常浪费时间,所以就需要用到函数来解决这个问题了。而且有时候会遇到交互式的情况,那么该怎么办呢?except就是用来解决这种情况的。那么接下来就看一下函数及expect的用法吧。函数及expect1

一、函数

   1、定义函数的定义:

f_name()

{

...函数体...

}

   2、函数体:

函数体就是一堆命令的集合

   3、函数的调用:

  直接写函数名就是调用该函数

   4、函数的删除:

unset f_name  

函数说明:

1、函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程。

2、它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

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

Shell程序在子Shell中运行,不会影响父shell。

而函数在当前Shell中运行。因此在当前Shell中,函数可以对shell中变量进行修改。

比如当前shell中变量name的值是chen,而在函数中定义name=li,那么调用函数之后,当前shell中name的值就变成li了

函数及expect2

注意:如果函数体与{}写在同一行,那么大括号里两边都要有空格,且最后的空格之前要有分号。

4、local 变量名  

表示设置本地变量,只在函数体内部起作用

比如,当前shell中name的值为li,而在函数中定义local name=chen,那么不影响当前shell

函数及expect3 

5、在命令行定义好的函数是不能修改的,只能删除重建,或者直接使用同一个函数名,重新写函数体 ,那么就会覆盖原来的函数体了。

函数及expect4 

6、函数名不要跟现有的别名,现有的命令等冲突。如果冲突,系统会认为你是要执行该命令,而不是定义函数,就会报错

函数及expect5 

7、函数相当于命令,可以使用反引号``来引用其执行结果

函数及expect6 

8、函数如果是在命令行直接写的,那么只在当前终端能用,如果写在文件中,那么都可以用

函数及expect7

9、函数中可以使用别名,脚本中不能用别名

函数及expect8 

函数及expect9 

10、在函数中一般不用exit退出,会直接退出当前shell,可以使用return退出函数,并且还可以自定义返回值。

函数及expect10 

函数及expect11 

11、/etc/init.d/functions该文件存放着大量的函数的定义

如果别的函数或者脚本需要用到该文件里的函数,那么直接使用. /etc/init.d/functions调用这个文件,再调用其中的函数即可。当然自定义的函数也可以写入其中,或者自己再建一个文件存放自定义的函数,那么用的时候直接调用文件,就不用每次都要定义函数了。

函数及expect12 

12、函数的递归调用,即自己调用自己。每调用一次就开一个子进程,所以使用函数的时候注意递归次数。

了解了函数的作与用法之后,来写个脚本试试吧函数及expect13


编写脚本/root/bin/copycmd.sh,要求:

(1) 提示用户输入一个可执行命令名称

(2) 获取此命令所依赖到的所有库文件列表

(3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下;如:

/bin/bash ==> /mnt/sysroot/bin/bash

/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd

(4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下:如:

/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2

(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit


#!/bin/bash

. /etc/init.d/functions

echo "目标目录是:/app"

[ -d /app ]||mkdir /app

cpcmd(){

   if which $needcmd &>/dev/null;then

local cmd=`which --skip-alias $needcmd`

local dir=`dirname $cmd`

[ -d /app$dir ]||mkdir -p /app$dir

if [ -f /app$cmd ];then

echo "$cmd 已存在"

else

cp $cmd /app$dir&&echo `action "$cmd" true`

fi

   elif [ "$needcmd" == "quit" ];then

exit

   else

echo "命令不存在或者该命令是内部命令或者该命令是别名"

   fi

}

cpso(){

   if which  $needcmd &>/dev/null;then   

local so=`ldd $(which --skip-alias $needcmd)|egrep -o "/.* "`

for i in $so ;do

local sodir=`dirname $i`

[ -d /app$sodir ]||mkdir -p /app$sodir

if [ -f /app$i ];then

echo "$i 已存在"  

else   

cp $i /app$sodir&&echo `action "$cmd" true`

fi

done

   fi

}

until [[ "$needcmd" == "quit" ]];do

   read -p "请输入需要复制的命令(quit退出): " needcmd

   cpcmd

   cpso

done

二、expect

expect默认是没有安装的,需要安装yum install expect

1、expect作用:

自动化地把交互式的提交变成非交互式的。

可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率

2、expect 语法:

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

  选项:

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

示例:expect -c 'expect "hi" {send "you said hi\n"}'

函数及expect14

  -d:可以输出调试信息,即显示详细的过程

比如expect -d ssh1.exp表示执行ssh1.exp登陆到别的终端,并且显示详细的信息。而且登陆之后,在该终端执行的每个操作都会重新再显示一遍。

3、expect中相关命令

   spawn:启动新的进程

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

   expect:从进程接收字符串

   interact:允许用户交互

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

这几个命令会在下面的示例中详细说明

4、expect最常用的语法(tcl语言:模式-动作)单一分支模式语法:

比如expect “hi{send You said hi\n"}

 表示匹配到hi后,会输出“you said hi”,并换行

函数及expect15 

5、多分支模式语法:

   比如expect

expect "hi" { send "You said hi\n" } \

"hehe" { send Hehe yourself\n" } \

"bye" { send Good bye\n" }

表示匹配hi,hello,bye任意字符串时,执行相应输出。

函数及expect16 

示例1:

cat ssh1.exp

#!/usr/bin/expect

spawn ssh 192.168.80.128 ----->表示启动新进程,即执行ssh命令

expect {

"yes/no" { send "yes\n";exp_continue } ---->表示匹配到yes/no时,就输入yes

回车,exp_continue表示后面还有字符串需要匹配

"password" { send "123456\n" } ---->表示匹配到password时,就输入123456并回车

}

Interact ----->允许用户交互,也就是说成功登陆之后可以继续在该终端 继续操作,而不直接退出

执行:ssh1.exp

函数及expect17 

示例2:在expect脚本使用变量

cat ssh2.exp

#!/usr/bin/expect

set ip 192.168.8.100 ----->设置变量ip=192.168.8.100

set user root ---->设置变量user=root

set password 123456 ---->设置变量password=123456

set timeout 10 ----->设置超时时间为10秒,超过10秒没执行成功就终止进程

spawn ssh $user@$ip

expect {

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

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

}

Interact

执行:ssh2.exp

函数及expect18 

示例3:引用位置参数

cat ssh3.exp

#!/usr/bin/expect

set ip [lindex $argv 0] ----->将第一个参数的值赋值给变量ip

set user [lindex $argv 1] ----->将第二个参数的值赋值给变量user

set password [lindex $argv 2] ----->将第三个参数的值赋值给变量password

spawn ssh $user@$ip

expect {

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

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

}

interact

执行:ssh3.exp 192.168.80.128 root 123456

函数及expect19 

示例4:执行多个命令

cat ssh4.exp

#!/usr/bin/expect

set ip [lindex $argv 0]

set user [lindex $argv 1]

set password [lindex $argv 2]

set timeout 10

spawn ssh $user@$ip

expect {

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

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

}

expect "]#" { send "useradd haha\n" } ----->创建用户haha

expect "]#" { send "echo magedu |passwd --stdin haha\n" }----->给该用户设置密码

send "exit\n" ----->退出连接

expect eof ------>结束expect,相当于退出ssh连接后换行的作用 

执行:ssh4.exp 192.168.80.128 root 123456

函数及expect20 

示例5:shell脚本调用expect

cat ssh5.sh

#!/bin/bash

ip=$1

user=$2

password=$3

expect <将下面的内容重定向到expect,直到读到EOF结束

set timeout 10

spawn ssh $user@$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

执行:ssh5.sh 192.168.8.100 root magedu

函数及expect21 

   以上就是博主要跟大家分享的东西,希望能对大家有所帮助。欢迎留言,共同探讨。

函数及expect22


勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:Eclipse SmartHome源码编译过程

下一篇:python基础练习_1

您可能感兴趣

  • VB下几个非常有用的函数

    VB下几个非常有用的函数'————————(1)————————————'获得指定ini文件中某个节下面的所有键值 TrueZq,,需要下面的API声明'Private Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As S...

  • 定义函数对象

    定义函数对象 时间:2001/02/07 15:22 作者:vckbase VC知识库  尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。 用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计...

  • 使用SendMessage函数滚动文本框控件中的内容

    在Visual Basic 中, 可 以 通 过 程 序 使 文 本 框 控 件 中 的 内 容 进 行 滚 动, 而 不 用 等 待 用 户 单 击 滚 动 条 控 件, 可 以 通 过 使 用Windows API 的SendMessage 函 数 将 一 个 或 多 个 滚 动 消 息 发 送 到 系 统 来 实 现 上 述 功 能。 在 文 本 框 控 件 中 滚 动 ---- 在...

  • 轻松使用自己的回调函数

    轻松使用自己的回调函数 vcbear原创 文章级别: 小技巧      回调函数是一个很有用,也很重要的概念。当发生某种事件时,系统或其他函数将会自动调用你定义的一段函数。回调函数在windows编程使用的场合很多,比如Hook回调函数:MouseProc,GetMsgProc以及EnumWindows,DrawState的回调函数等等,还有很多系统级的回调过程。本文不准备介绍这些函数和过程...

  • WINDOWS未开函数揭密(1)

    WINDOWS未开函数揭密   什么是未公开函数?   对于Windows的API函数调用相信大家已经不会陌生了。API函数调用是通过在VB中定义和调用Windows动态连接库中的函数从而扩展VB程序的功能。API函数的定义和调用方法在微软的开发工具中都有详细的说明。   那么什么是“未公开”函数呢?微软为了某种目的。对于一些封装在系统中的函数没有在任何开发文档提供任何函数说明和定义。而这...

  • Windows未公开函数揭密(3)

    Windows未公开函数揭密    '根据一个特定文件夹对象的ID获得它的目录pidlPublic Function GetPIDLFromFolderID(hOwner As Long, nFolder As SHSpecialFolderIDs) As LongDim pidl As LongIf SHGetSpecialFolderLocation(hOwner, nFolder, ...

  • 成员变量/函数指针的用法

    说明: 这是今天看《thinking in c++》的第10章时作的"笔记",前面也有人 问到关于成员函数指针的问题,我那时说直接传入this指针,现在看 了书后有多了一种方法,不过,它的语法有点难计。   这下回去可以看看MFC的消息映射/动态创建是怎么写的了,我想也应 该是成员函数指针把 指针是指向一些内存地址的变量,既可以是数据的地址也可以是函数的地址。C++的成员指针遵从同样的原则...

  • C/C++中的函数参数传递机制

    C/C++中的函数参数传递机制 作者:杨宁 发布时间:2000/11/30  文章摘要:  本文论述了在 C 和 C++ 中函数调用的参数传递机制;同时附带说明了函数返回值的一些问题。本文示例使用的是VC++6.0。         正文:   C/C++中的函数参数传递机制   一、 函数参数传递机制的基本理论  函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用...

51CTO

51CTO

51CTO是一家综合的IT技术用户服务平台,立足满足用户多维度需求,为技术用户成长赋能。2005年成立至今,拥有专业主流技术媒体51CTO企业信息化媒体CIOAge中国最大的IT在线教育平台51CTO学院。

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
函数及expect介绍:华为云为您免费提供函数及expect在博客、论坛、帮助中心等栏目的相关文章,同时还可以通过 站内搜索 查询更多函数及expect的相关内容。| 移动地址: 函数及expect | 写博客