shell编程之免交互(shell脚本)

news2024/9/22 1:06:59

Here Document 免交互

Here Document 概述

Here Document是一个特殊的用途的代码块。它在linux shell中使用I/O重定向的方式将命令列表提供给交互式程序或命令,比如ftp,cat或read命令。Here Document 是标准输入的一种替代品,可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用于命令的标准输入。基本语法格式如下:

特殊字符在“<<"在标记和命令之前,这样做的目的是将命令块的输出定向搭配程序或命令的stdin。标记的选择要确保不会出现在其他地方,避免出现混淆;两个标记之间的内容被当做是 一个文件并用作“命令”的标准输入。此外,Here Document 也可以与非交互程序和命令一起使用。

特殊字符在“在实际使用过程中,有四点需要注意:

标记可以使用任意的合法字符;

结尾标记一定要顶格写,前面不能有任何字符;

结尾的标记后面也不能有任何字符(包括空格);

开头的标记前后的空格会被省略掉;

在linux系统中使用wc-l命令后面直接跟文件名就可以统计文件内有多少行内容。采用Here Document免交互方式也可以实现对行数的统计。将要统计的内容置于标记“EOF”之间,直接把内容传给wc-l来统计,具体操作如下:

在编写shell脚本时使用Here Document 可以实现免交互,通过Here Document可以将一些简单的交互任务的交互过程去除掉,尤其是在编写脚本的过程中。

具体示例如下:

1,通过read命令接收输入并打印

通常使用read命令接收用户的输入值时会有交互过程,尤其是在脚本执行过程中遇到read命令,脚本会停下来的等待用户输入值才会继续。

这个示例中的输入值是两个eof标记之间的部分,也就是hi,这将作为变量i的值,在最后echo打印变量i的值,其值为hi

        

2,通过passwd给用户设置密码

通过passwd命令给jerry用户设置密码,为避免重复交互,可使用Here Document的方式。EOF标记之间的两行是输入的密码和确认密码,两江内容必须保持一致,否则密码将设置不成功。此脚本执行后不会输出任何信息,可另开一个终端使用jerry用户登录,输入新修改的密码来验证密码是否修改正确。

Here Document变量设定

Here Document 也支持使用变量,如果标记之间有变量被使用,会先替换变量值。如果想要将一次内容写入文件,除了常规的方法外,也可以使用Here Document 。如果写入的内容中包含变量,在写入文件时要先将变量提花成实际值,在结合cat命令完成写入。

除了变量替换,还可以结合Here Document 来进行变量的设定。Here Document 不光可以将标记内容传给命令来执行,还可以将整体赋值给一个变量,然后通过echo命令将变量值打印出来。

Here Document 格式控制

Here Document 支持两种控制输出的格式的类型:关闭变量替换的功能与去掉每行之前的TAB字符。

(1)关闭变量替换的功能

关闭变量替换的功能,就是希望按照字符原来的样子输出,不做任何修改或替换。

(2)去掉每行之前的TAB字符。

本示例的标记内,每行都有一个TAB字符,在第一行标记前面加“-”,这个表示要抑制各行首TAB的作用。

Here Document 多行注释

BASH的默认注释是“#“,该注释方法只支持单行注释,在shell脚本的工作中,”#”右侧的任何字符串,bah都会将其忽略,Here Document的引入解决了多行注释的问题,其语法格式如下:

上述语法结构中“代表什么都不做的空命令。中间标记区域的内容不会被执行,会被bash忽略掉,因此可达到批量注释的效果。

下面脚本用于演示shell中多行注释,“:”开头的Here Document 标记内容不会被执行,在需要使用多行注释的时候可以采用此方法。

expect免交互

expect是建立在tcl语言基础上的一个工具,它可以让一次需要交互的任务自动化地完成,相当于模拟了用户和命令行的交互操作。expect是用来进行自动化控制和测试的工具。主要解决shell脚本中不可交互的问题。对于大规模的linux运维很有帮助。

在linux运维和开发中,经常需要远程登录服务器进行操作,登录的过程是一个交互的过程,可能会需要输入yes/no,password等信息,为了模拟这种输入,可以使用expect脚本。

在实际的生产环境中,有一个常用的场景就是批量配置集群无秘钥登录。如果集群的机器数量很多,手动一台一台地去每台机器去配置无秘钥是非常糟糕的事情。使用expect功能,可以远程登录机器,并通过交互方式进行无秘钥登录。

基本命令介绍

(1)脚本解释器

expect脚本中首先引入文件,表明使用的是哪一个shell。

#!/usr/bin/expect

(2)expcet/send

expect命令用来判断上次输出结果是否包含指定的字符串,如果有则立即返回,否则就等待超时时间后返回,只能捕捉spawn启动的进程的输出。

expect接收命令执行后的输出,然后和期望字符串匹配,若匹配成功则执行相应的send向进程发送字符串,用于模拟用户的输入,send发送的命令不能自动回车换行,一般要加\r(回车)。

方法一:

expect "$case1" {send "$respond1\r"}

方法二:

expect "$case1"

send "response1\r"

方法三:

expect支持多个分支。

expect

{

“$case1” {send "$response1\r"}

“$case2” {send "$response2\r"}

“$case3” {send "$response3\r"}

}

上述语法结构中$case代表测试命令的输出结果,如果输出内容和$case1一致,通过send命令模拟用户发送内容到终端。

(3)spawn

spawn后面通常跟一个命令,表示开启一个会话,启动进程,并跟踪后续交互信息。

语法如下:

spawn linux执行命令

例如,如果想要跟踪切换用户的交互信息,可以执行以下命令。

spawn su root

(4)结束符

expect eof ;等到执行结束,若没有这一句,可能导致命令还没执行,脚本就结束了。

interact;执行完成后保持交互状态,把控制权交给控制台,这时可以手动输入信息。

需要注意的是,expect eof 与interact只能二选一。

(5)set

expect默认的超时时间是10秒,通过set命令可以设置会话超时时间,若不限制超时时间则映射中为-1.

例如执行以下命令即可将超时时间设置为30秒。

set timeout 30

(6)exp_continue

exp_continue表示允许expect继续向下执行指令。

(7)send_user

send_user表示回显命令,相当于echo。

(8)接收参数

expect脚本可以接受从bash传递的参数,使用[lindex $argv n]获得。其中n从0开始,分别代表第一个,第二个,第三个....参数。

参数存在argv中,使用第一个参数如下:

在上述脚本中,$argv0是脚本名,但[lindex $argv 0]是第一个参数param1,[lidex $argv1]是第二个参数param2,以此类推。send_user用来显示信息到父进程(一般为用户的shell)的标准输出。

expect语法:

1,语法结构

(1)单一分支语法

单一分支用于简单的用户交互,当监控命令的标准输出满足expect指定的字符串时,向标准输入发送send指定的字符串。具体用法如下所示。默认情况下,send不会向标准输入发送回车键,所以需要通过\r手动换行。

(2)多分支模式语法

多分支用于复杂的用户交互,一般情况下输出内容可能有很多个,根据不同的输出内容,分别向标准输入发送不同的内容,其语法格式如下所示,只要匹配了aaa,bbb或ccc中的任何一个,就执行相应的sed语句,然后退出该expect语句。

expect

{

“aaa” {send “AAA\r}

“bbb” {send “BBB\r}

“ccc” {send “BBB\r}

}

除了上述的多分支结构之外,还有另外一种多分支结构,具体使用方法如下所示。

exp_continue表示继续后面的匹配,假如匹配了aaa,执行完send语句后还要继续向下匹配bbb。

2,expect执行方式

(1)直接执行

通过ssh方式登录远程服务器,需要输入用户名和密码,比较繁琐。如果服务器比较多,手动输入用户名和密码会耗费大量时间,expect命令可以实现自动登录远程服务器,并进去交互模式。

(2)嵌入执行

上面讲到的直接执行的方式需要expect命令去执行脚本,在编写shell脚本的时候需要去调用expect脚本,使用不灵活,这种情况下,可以使用嵌入执行模式,将expect过程融入shell当中,方便执行和处理。

expect案例

1,创建用户并设置密码

正常情况下创建用户jack并把密码设置jack123的交互过程如下:

根据正常的交互过程,编写expect脚本如下所示:

wangwu是$1的值,pwd123是$2的值。

2,实现ssh自动登录

ssh登录过程根据不同的场景会出现多种交互形式,比较典型的交互场景如下所示。

首次登录:

正常登录:

连接被拒绝,可能是ssh服务没启动,或者端口不对,或者防火墙限制。

没有连接地址:

利用expect,根据上述不同的场景,可编写的脚本如下:

3,利用expect完成FTP登录过程

正常的FTP登录交互过程如下所示:

编写的expect脚本如下:

服务器端要安装vsftpd服务,并关闭防火墙,内核安全机制。并开启vsftpd服务。

客户端要安装ftp服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1869901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

postman忘记密码发邮件,久久收不到怎么办?

根本原因是需要FQ&#xff01;&#xff01;&#xff01; 重置密码的链接&#xff1a; https://identity.getpostman.com/trouble-signing-in 找个平台或者软件&#xff0c;访问这个链接即可完成修改密码后续操作&#xff0c;不用再傻傻等着验证码了。 有需要协助的朋友也可私信…

运算放大器(运放)输入偏置电流、失调电流

输入偏置电流定义 理想情况下&#xff0c;并无电流进入运算放大器的输入端。而实际操作中&#xff0c;始终存在两个输入偏置电流&#xff0c;即IB和IB-(参见图1)。 I B I_B IB​的值大小不一&#xff0c;在静电计AD549中低至60 fA(每三微秒通过一个电子)&#xff0c;而在某些高…

Linux CentOS 宝塔中禁用php8.2的eval函数详细图文教程

PHP_diseval_extension 这个方法是支持PHP8的, Suhosin禁用eval函数&#xff0c;不支持PHP8 一、安装 cd / git clone https://github.com/mk-j/PHP_diseval_extension.gitcd /PHP_diseval_extension/source/www/server/php/82/bin/phpize ./configure --with-php-config/ww…

似然 与 概率

概率似然概率函数与似然函数的关系似然与机器学习的关系最大似然估计 似然与概率分别是针对不同内容的估计和近似 概率 概率&#xff1a;概率表达给定参数 θ \theta θ下样本随机向量 X x \textbf{X} {x} Xx的可能性。 概率密度函数的定义形式是 f ( x ∣ θ ) f(x|\t…

【博士每天一篇文献-综述】A survey on few-shot class-incremental learning

阅读时间&#xff1a;2023-12-19 1 介绍 年份&#xff1a;2024 作者&#xff1a;田松松&#xff0c;中国科学院半导体研究所&#xff1b;李璐思&#xff0c;老道明大学助理教授&#xff1b;李伟军&#xff0c;中国科学院半导体研究所AnnLab&#xff1b; 期刊&#xff1a; Neu…

FastGPT部署和OneAPI部署

FastGPT模型管理 FastGPT只支持openai 格式的restful 的api接口。 就是 chat/completion那个接口。如果不理解可以参考这个文章 https://zhuanlan.zhihu.com/p/656959227 。 支持Python 。JAVA 等后端语言或者 http 访问 因此如果想访问大模型&#xff0c;有以下几种方案&…

一次tcpdump抓包过程

#查询网卡 tcpdump -D # 监听 21100 端口 网卡ens192 &#xff08;不知道网卡&#xff0c;可以直接不输入 -i 网卡&#xff09;TCP数据&#xff0c;等待一段时间&#xff0c;执行CtrlC&#xff0c;终止程序 tcpdump -x -s 0 -w /tmp/123.dump -i ens192 -p tcp port 21100 #…

《2024快手行业人群画像报告-大家电类目》

快手商业化品牌行业运营中心与快手商业化用户研究中心联合发布了一份名为《2024快手行业人群画像报告-大家电类目》的研究报告。 这份报告深入分析了大家电市场的用户画像,涵盖了品类划分、用户趋势、交易洞察、人群洞察、搜索洞察以及品牌认知等多个维度的详尽数据和洞察,为理…

海思平台使用ITTP_Stream调试sensor

目录 相关资料1.ISP相关资料2.MIPI RX相关资料3.sensor资料4.MIPI标准 准备工作1.准备sensor驱动2.准备sample vio3.准备上位机和下位机程序 运行1.只运行HiPQTool1.1.板端运行1.2.PC端运行HiPQTool 2.使用ITTP_Stream2.1.板端运行2.2.打开上位机软件 相关资料 1.ISP相关资料 …

基于哈尔小波基的一维密度估计(Python)

先说点其他的东西。 关于强非线性、强间断、多物理场强耦合或高度复杂几何形态问题能够得以有效求解的核心难题之一&#xff0c;是如何构建在多尺度情形、非线性作用下具有准确地识别、定位、捕获以及分离各个尺度特征尤其是小尺度局部特征能力的数值工具&#xff0c;这之中包…

C语言单链表的算法之遍历节点

一&#xff1a;什么是遍历 &#xff08;1&#xff09;遍历就是把单链表中的各个节点挨个拿出来&#xff0c;就叫遍历 &#xff08;2&#xff09;便利的要点&#xff1a;一是不能遗漏&#xff0c;二是不能重复追求效率 二&#xff1a;如何遍历单链表 &#xff08;1&#xff0…

element-plus 日期选择添加确定按钮

需求&#xff1a;选择日期后&#xff0c;点击确定按钮关闭面板 思路&#xff1a; 使用shortcuts自定义确定和取消按钮选择日期后使用handleOpen()强制开启面板点击确定后使用handleClose()关闭面板 <template><el-date-pickerref"pickerRef"v-model"…

能量智慧流转:全面升级储能电站的智能网关解决方案

监控系统是电化学储能电站的关键组成部分&#xff0c;储能电站也需要相应的监控系统&#xff0c;通过监控系统对储能设备的状态进行监测&#xff0c;实时感知储能设备的健康状态&#xff0c;控制储能设备的充放电功率和时机等&#xff0c; 一个好的监控系统可以实现储能电站安全…

微软发布Phi-3系列语言模型:手机端的强大AI助手

大模型&#xff08;LLMs&#xff09;在处理复杂任务时展现出的巨大潜力&#xff0c;但却需要庞大的计算资源和存储空间&#xff0c;限制了它们在移动设备等资源受限环境中的应用。微软公司最新发布的Phi-3系列语言模型&#xff0c;以其卓越的性能和小巧的体积&#xff0c;打破了…

[面试题]计算机网络

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis[面试题]消息队列[面试题]…

AppFlow无代码轻松搭建模型Agent

随着大语言模型发展至今&#xff0c;如何深度开发和使用模型也有了各种各样的答案&#xff0c;在这些答案当中&#xff0c;Agent无疑是一个热点回答。 通过模型也各种插件的组合&#xff0c;可以让你的模型应用具备各种能力&#xff0c;例如&#xff0c;通过天气查询插件机票查…

最新Adobe2024全家桶下载,PS/PR/AE/AI/AU/LR/ID详细安装教程

如大家所熟悉的&#xff0c;Adobe全家桶系列常用的软件有Photoshop&#xff08;PS&#xff09;、Premiere&#xff08;PR&#xff09;、After Effects&#xff08;AE&#xff09;、illustrator&#xff08;AI&#xff09;、Audition&#xff08;AU&#xff09;、Lightroom&…

使用 SwiftUI 为 macOS 创建类似于 App Store Connect 的选择器

文章目录 前言创建选择器组件使用选择器组件总结前言 最近,我一直在为我的应用开发一个全新的界面,它可以让你查看 TestFlight 上所有可用的构建,并允许你将它们添加到测试群组中。 作为这项工作的一部分,我需要创建一个组件,允许用户从特定构建中添加和删除测试群组。我…

商场配电新思维:智能网关驱动的自动化管理系统

在商场配电室监控系统中&#xff0c;主要是以无线网络为载体&#xff0c;目的就是便于对变电站等实时监测与控制。其中&#xff0c;4G配电网关非常关键&#xff0c;可以将配电室系统终端上的信息数据及时上传到服务器&#xff0c;再由服务器下达控制指令到各模块中&#xff0c;…

第六十九:iview 表格汇总怎么拿到传过来的数据,而不是自动累加,需要自定义方法

话不多少&#xff0c;先看官方解释 我这个简单&#xff0c;所以所有说明都在图上了 handleSummary({ columns, data }){console.log(columns, data)let sums {}columns.forEach((item,index)>{const key item.key;console.log("key",item)if(index 0){console.…