浅记初次使用expect、scp和Net::SCP::Expect、Net::SSH::Expect中出现的一些小问题

以前也学过一些shell,不过学得并不是很深入,动手写的代码的时间也不是很多。前不久将shell比较细的过了一遍,leader布置了任务让用shell写一个脚本将redis源码压缩包从一个服务器上传到另外一个服务器,同时在本服务器上传入命令,解压源码包并在另一个服务器上启动redis服务。

虽然学了一些shell,但是本次任务中需要使用的SCP和expect却是第一次使用,其中也遇到了一些问题,所以在这里总结一下。

现代的Shell对程序提供了最小限度的控制(开始,停止,等等),而把交互的特性留给了用户。 这意味着有些程序, 你不能非交互的运行,比如说passwd。简单点说就是你得手动输入密码,shell没有提供给你将密码直接在程序中一次性搞定的方法。

也正是因为如此,expect诞生了。

注意expect是独立于shell之外的,或者说他们完全不是一个东西(但是两者都是linux下很强大的工具)。当时我因为绝得expect是shell的一个补充,所以在expect中使用了很多shell的语法,呵呵!!!结果你懂的。

我在这里就简单说一下我用到的expect的基本语法,以及走过的坑,同时如果大家有愿望去学习一下的话我会在后面提供几个给我不少借鉴的网页,以便大家深入学习。

  1. 最简单的#!/usr/bin/env sh和#!/usr/bin/env expect 就懒得说了;
  2. 其次在expect中,传入参数的个数是用$argc访问的,然而在shell中$#。虽然很简单,但是shell中下面这几个参数还是记得的好:

  

  3. shell中设置变量,$a="hello world",expect中 set a "hello world"

  4. 在expect中查看变量的值:send_user "$a";

  5. 在expect中执行shell的程序: spawn <shellCommand>

  6. expect中查看传入的参数的值:[lindex $argv 1] [lindex $argv 2] [lindex $argv 3]...[lindex $argv n]

  7. 特别有用的:用于进行交互的expect 和 send。我也没学得太深,只能大概举一个例子:

  spawn ssh -l username 192.168.1.1

  expect "*password:"

  send "ispass\r"

  就差不多这个样子吧!特别注意的是:send 后面的密码最后一定要跟一个\r,否则你等着错吧!!!

  刚好到这里就再说说我遇到的一个大坑——情况是这样的,为了提高代码的复用性,导师都是让我不要把什么密码啊这一类的写死的,要么传参要么设置环境变量值,我选择了传参的方法,就比如下面这个程序:

  hello.sh

  #!/usr/bin/env expect

  set host [lindex $argv 1]

  set passwd [lindex $argv 2]

  spawn ssh -l username $host

  expect "*password:"

  send "$passwd"

  执行的命令是这样的:./hello.sh "192.168.1.1" "ispass\r"

  好了,TMD。一直出错,不记得具体报什么错了,好像是提示密码错误。怎么会出错呢,纠结,纠结.....足足纠结几个小时啊!!!不知道错哪儿了

  后来看到了这篇文档(http://blog.itpub.net/27042095/viewspace-745589/)的第一张图片,恍然大悟啊!!!赶快改正过来。

  hello.sh

  #!/usr/bin/env expect

  set host [lindex $argv 1]

  set passwd [lindex $argv 2]

  spawn ssh -l username $host

  expect "*password:"

  send "$passwd\r"

  执行命令:./hello.sh "192.168.1.1" "ispass"

  8. 这个一定要注意:如果你在expect中利用ssh登录了某个服务器,你希望直接进入那个服务器(简单点说就是你现在是在服务器长操作了,看到的是服务器的文件)一定要使用interact

  简单举一个例子吧:

  #!/usr/bin/expect
  set timeout 30
  spawn ssh -l username 192.168.1.1
  expect "password:"
  send "ispass\r"
  interact  expect eof

  9.程序嘛!还是尽量有expect eof 和exit的好一点。

  10. 最大的坑来了,expect的if用法:

  if { <条件判断> } {
    <commands>...
  }  也许你没有仔细看:
  1. if的后面是大括号{},不是();
  2. if和后面的大括号之间是有一个空格的,你造吗?
时间: 2024-10-19 07:10:39

浅记初次使用expect、scp和Net::SCP::Expect、Net::SSH::Expect中出现的一些小问题的相关文章

C#中值类型和引用类型的区别浅记

C#中值类型和引用类型的区别浅记 在C#中,变量的类型分为两种,分别是值类型和引用类型. 值类型的变量直接存储值,说得更具体一些,就是值类型变量在内存中直接存储它们自身的值,如代码所示, int x = 2: 值类型变量x,在内存中的某处直接存储了它自身的值:2. 引用类型的变量存储的是对其对象的引用,更进一步说,就是引用类型变量在内存中直接存储了一个指向它处的引用,而引用所指的对象则保存在引用类型变量所指的内存中.如代码所示, public class Thing { int x; } Thi

C# 中堆与栈的浅记

C# 中堆与栈的浅记 什么是堆和栈? 简言之,堆和栈是驻留在内存中的区域,它们的作用是帮助我们执行代码.在.Net Framework 环境下,当我们的代码执行时,内存中的堆和栈便存储了这些代码,并包含了代码执行所需要的全部信息. 这样说来还是有些抽象,那么,在堆和栈中究竟都保存了些什么呢?概括说来就是四类数据: 1.值类型数据 2.引用类型数据 3.指针 4.指令 下面对上述四类数据做以简单介绍.我们知道,C#中的数据类型分为两种,分别是值类型和引用类型.值类型数据直接在内存中的一个位置存储它

ssh+expect+scp实现服务器集群自动化搭建

之前介绍过ansible的使用,通过ssh授权批量控制服务器集群 但是生成密钥和分发公钥的时候都是需要确认密码的,这一步也是可以自动化的,利用ssh + expect + scp就可以实现,其实只用这几个命令结合也可以实现类似ansible的功能了 为了远程操作服务器进行环境初始化,总结我们都需要以下几步操作 1.ssh-keygen生成密钥对 2.将生成的公钥发送到node服务器 3.scp拷贝安装包到node服务器 4.ssh远程执行拷贝过去的安装包 下面进行集群环境初始化脚本的编写,通过s

linux之cp/scp命令+scp命令详解

linux之cp/scp命令+scp命令详解 名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数个档案拷贝至另一目录. 把计 -a 尽可能将档案状态.权限等资料都照原状予以复制. -r 若 source 中含有目录名,则将目录下之档案亦皆依序拷贝至目的地. -f 若目的地已经有相同档名的档案存在,则在复制前先予以删除再行复制. 范例: 将档案 aa

【转】linux之cp/scp命令+scp命令详解

linux之cp/scp命令+scp命令详解 名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source... directory 说明:将一个档案拷贝至另一档案,或将数个档案拷贝至另一目录. 把计 -a 尽可能将档案状态.权限等资料都照原状予以复制. -r 若 source 中含有目录名,则将目录下之档案亦皆依序拷贝至目的地. -f 若目的地已经有相同档名的档案存在,则在复制前先予以删除再行复制. 范例: 将档案 aa

解决scp时报bash: scp: command not found的错误

在进行scp时报bash: scp: command not found [[email protected] add_admin]# scp ocp_admin_privileges.mysql [email protected]:/root[email protected]'s password: bash: scp: command not foundlost connection 查看本机是否安装openssh-clients软件包 [[email protected] add_admi

《暗时间》阅读浅记

刘未鹏提到的"书写"."写博客",强调的是一个内容输出,促进思考.倒逼输入.实际上在一番学习之后,无论是参加小组讨论还是教授他人,都是一种知识的"再加工",这是将知识转化为自身理解的途径,这里就突出思考的重要性了.带着问题,学习则变成一种主动式获取:书写或传授他人,则要求自身先将知识消化:结合诸多其他学习类的书籍,可以肯定这必定是普适方法之一. 具体如何实践?作者倒是提出了多个方法,虽是是个人经验也颇有参考价值,重点是要存着一个"主动&

浅谈初次搭建nginx+php+mysql遇到的问题

先说明下我linux上的环境: nginx + php(5.5.10) + mysql 开始的源码已经在本地写好,并调试成功(本地的环境是用XAMPP的默认配置),在把代码上传至linux上时,出现以下问题: [1]写日志时: PHP message: PHP Warning: fopen(log/log.log.141019): failed to open stream: Permission denied 这个是说明没有访问权限 解决:linux对php访问的用户权限有些限制,应该默认是n

13 X window system 学习浅记

一.X window system:指通过图形接口(Graphical user interface,GUI)操作;那么为甚图形窗口接口成为X呢?因为英文字母X在W(window)后面,故人们就戏称这一版接口为X啰(下一版新窗口之意).  1.定义:        a.在 Unix Like 上面癿图形用户接口 (GUI) 被称为 X 戒 X11:        b.X11 是一个『软件』而不是一个操作系统:        c.X11 是利用网络架构来进行图形接口的执行不绘制:        d