两种Linux下非交互式命令的实现

一、概述

在Linux环境,有多种实现自动化的脚本语言,如Shell、Python、Perl、Tcl等。Shell语言因与Shell外壳结合紧密,是最常见的实现自动化的脚本语言。

同时,在Linux环境中存在大量功能单一的小工具——通常它们在指定输入后,立即就可获得输出,例如echo、cat等字符串/文本打印工具,又或者是如sed、awk等最常用的字符串编辑工具。通过编写Shell脚本,我们可以反复利用这些小工具来实现一些自动化的批处理。

在少数情况下,我们也需要用到一些交互式的工具,例如passwd、fdisk等——这意味着在自动化执行的过程中,我们必须停顿下来,满足工具本身的交互式流程。本文将介绍两种在使用交互式命令时规避交互来实现自动化的方式。

二、用分界符控制交互式命令

Shell中的 ‘<<’符号表示一种特殊的重定向,用于向某一个命令传递多行输入。当脚本中出现此符号时,Shell将首先会把紧跟着‘<<’的一个字符串,视为一种特殊的分界符;然后,用户可以输入一连串的数据;最后,用户单独起一行,用另一个相同的分界符结尾。在两个分界符之间的内容,都被视为命令的输入参数。

我们在实际的软件开发项目中看到最多的就是用cat向一个文件输入一段文本。例如下面的example1.sh脚本中的内容:

cat > example1.sql <<EOFSQL

declare @num int, @sql nvarchar(1000) 
set @sql=‘select @a=count(*) from tableName ‘ 
exec sp_executesql @sql,N‘@a int output‘,@num output 
select @num

<<EOFSQL

该脚本的运行结果是生成一个example1.sql文件,内容为两个分界符EOFSQL之间所示的内容。

用cat命令向一个文本输入字符串,本身不是交互式的。当使用交互式命令时,分界符便可以控制命令的输入参数,满足不同的控制流的要求。

三、用expect命令控制多个命令

在执行另外一些操作(如ssh登录)时,我们无法用分界符的方法来输入多个命令,因为ssh的输入来源是终端(分界符的输入,应理解为通常意义上的字符串)。这时,我们可以考虑用expect命令。

expect命令是Linux中专门以非交互式方法处理交互式命令的工具。相比分界符来说,它更为强大,且能实现分界符能实现的一切功能。

expect命令的工作原理是在shell中另启一个新进程,并且在此进程中模拟了终端,对输入/输出进行全面监控。而要使用expect命令,则必须需要编写独立的脚本。

expect有相当多的参数和语法,下面我们仅介绍一些基础部分,供大家参考。

1.[#! /usr/bin/expect]

expect脚本的第一行总是用这个语法。这类似于shell脚本的#! /bin/sh,这句话的含义也是定义脚本的解释器。

值得注意的是,根据操作系统的不同,expect命令的位置也可能是在 /usr/local/bin/expect。使用前,用户应确认工具是否存在(确认方法是在root用户下执行“which expect”命令)。

2.[set timeout 30]

设置响应的超时时间,计时单位是秒。设置timeout -1表示永不超时。

3.[spawn ssh -l username ip]

spawn是进入expect环境后才可以执行的expect内部命令。它主要的功能是给ssh运行进程加个壳,用来传递交互指令。

4.[expect "xxxxx:"]

这里的expect也是一个内部命令。这个命令的意思是判断上次输出结果里是否包含“xxxxx:”的特定字符串,如果有则立即返回。

expect还有些扩展的用法,最常见的如下所示:

expect {

“xxx1”   {command1;exp_continue}

“xxx2”  {command 2}

}

以上代码的含义如同C语言的switch语句,不同的条件类似不同的case子句。而其中的exp_continue就如同不加break语句,程序将继续执行后面的语句。

5.[send "ispass\r"]

这是执行交互动作,即模拟终端进行输入。值得注意的是,命令字符串结尾别忘记加上“\r”。

6.[expect eof]

退出expect解释器 。

下面是一个使用expect命令的实例:

#! /usr/bin/expect -f

set timeout -1

spawn ssh -l zhou 10.10.10.10

expect {

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

"*assword:" {send "zhou"}

}

expect "*>" {send "echo’HelloWorld!’\r"}

expect "*>" {send"exit\r"}

expect eof

示例中,我们通过ssh以用户zhou登录了10.10.10.10,然后向ssh输入该用户的密码。登录成功之后,我们打印“Hello World!”,之后退出ssh,结束expect命令的执行。

expect命令的更详细用法请参考man手册。

四、总结

本文简单地介绍了在Linux下,两种使用交互式命令时规避交互来实现自动化的方式,供相关的开发人员参考。

-----------------

本人微信公众号:zhouzxi,请扫描以下二维码:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-08 09:41:22

两种Linux下非交互式命令的实现的相关文章

Linux下非root用户安装软件

下面简要说一下Linux下非root用户安装软件的一般流程:1. 获取源代码,一般是wget方式,ubuntu可以使用apt-get source来获取源代码.2. 解压源代码,一般使用tar -zxvf xxx.tar.gz即可3. 切换到解压后的目录,运行 ./configure.其选项可以通过 ./configure –help来获取,非root用户下最重要的应该是定义安装目录,即应该定义 ./configure –prefix=/path/to/bin, 对于一些依赖库,可能还需要使用

Linux下使用crontab命令以及Python脚本实现自动签到

关于这一部分, 我首先介绍下如何实现使用Python脚本实现签到功能其实,linux下有个命令叫做curl,完全可以完成模拟签到的功能,但是为了练习Python,我就用Python来写了.有这个想法完全是因为实验室的学长开发了一款App,上边收个起床签到,还有排名,为了能那个首签... 言归正传 首先,因为是手机上的App, 所以,我们需要抓包看下它具体的URL以及发送的内容是什么,关于这部分内容我就不在赘述了,我实现的功能主要有模拟发布状态和模拟签到两种功能,两个的URL也是不同的.为了不让学

在Linux下如何限制命令执行的时间?

在Linux下如何限制命令执行的时间?两种解决方法,如下: 1: Linux命令--timeout 运行指定的命令,如果在指定时间后仍在运行,则杀死该进程.用来控制程序运行的时间. 2: command & pid=$! ;sleep 2;kill -9 $pid

linux下安装7z命令及7z命令的使用

本文主要介绍了在linux下安装7z命令的方法,同时介绍了7z命令的使用.7z压缩格式拥有众多优点,具有极高的压缩比率,如果你还不了解,请看文章:7z格式.LZMA压缩算法和7-Zip详细介绍. reille使用的linux发行版是ubuntu,同时在Redhat上业已验证,可正常使用. 1. linux安装7z命令 linux上安装7z命令有两种方式:在线安装和安装包安装,下面分别介绍. 1.1 在线安装 如果你的宿主机Linux可以连接外网,推荐用这种方式,方便简单,执行命令: sudo a

[转]linux下终端常用命令和vi命令修改文件及保存的使用方法

首先介绍一下Ubuntu下各个目录的一般作用: / 这就是根目录,一台电脑有且只有一个根目录,所有的文件都是从这里开始的.举个例子:当你在终端里输入"/home",你其实是在告诉电脑,先从/(根目录)开始,再进入到home目录. /root 系统管理员(root user)的目录.至于系统管理员的权限有多大我这里就不在废话了.因此,请小心使用root帐号. /boot 系统启动文件,所有与系统启动有关的文件都保存在这里 . /bin 这里是存放系统的程序. /etc 主要存放了系统配置

原 Linux下的rename命令

原贴:http://www.linuxfly.org/post/300/ 5 [原]Linux下的rename命令 linuxing , 16:28 , 网络服务 ? 虚拟机 , 评论(0) , 引用(0) , 阅读(61) , Via 本站原创 大 | 中 | 小 引用地址: 注意: 该地址仅在今日23:59:59之前有效 Dos/Windows下,对文件改名用rename.而书上说,Linux下对文件或目录改名该用mv.我一直也是这样做的,却忽略了Linux下也有个叫rename的命令.都是

linux下使用fdisk命令进行磁盘分区

linux下使用fdisk命令进行磁盘分区 目录 分区类型 分区方法表示 文件系统 fdisk命令分区过程 分区类型 主分区:总共最多只能分四个 扩展分区:只能有一个,也算作主分区的一种,也就是说主分区加扩展分区最多有四个.但是扩展分区不能存储数据和格式化,必须再划分成逻辑分区才能使用. 逻辑分区:逻辑分区是在扩展分区中划分的,如果是IDE硬盘,Linux最多支持59个逻辑分区,如果是IDE硬盘,Linux最多支持59个逻辑分区,如果是SCSI硬盘Linux最多支持11个逻辑分区 分区方法表示

linux下修改rm命令防止误删除

前言:相信很多朋友都遇到过在linux下用rm命令误删除文件的时候,此刻的心中仿佛有无数的羊驼在奔腾.那么怎么防止这种情况发生呢?当然是有方法的,我们可以写一个shell脚本,改变一下rm命令的作用. 第一步: 先在home目录下创建一个叫username名字的目录(当然名字可以自定义),具体命令为:sudo mkdir username(自定义的名字) 这时候记得要用命令:sudo chmod 777 username(自定义的名字)来改变一下你的目录权限,因为在home目录下刚创建的目录是没

linux下的shell命令的编写,以及java如何调用linux的shell命令(java如何获取linux上的网卡的ip信息)

程序员都很懒,你懂的! 最近在开发中,需要用到服务器的ip和mac信息.但是服务器是架设在linux系统上的,对于多网口,在获取ip时就产生了很大的问题.下面是在windows系统上,java获取本地ip的方法.贴代码: package com.herman.test; import java.net.InetAddress; /** * @see 获取计算机ip * @author Herman.Xiong * @date 2014年5月16日 09:35:38 */ public class