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

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

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
  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>...
  } else {
    <commands>...
  }

  也许你没仔细看,我来提醒你一下:

  1. if的后面是大括号{},不是();
  2. if和后面的大括号之间是有一个空格的,你造吗?
  3. 注意下面这张图片的红色框起来的部分:

  

  你造上面红色框框起来的部分必须在一行吗?而且彼此之间是必须有空格分隔的。唉,当时这个问题,都快把自己调试哭了!!!

  有了上面的语法,大家简单编辑一个小程序已经够了!!!至少完成我的任务我只用到了上面的语法,如果大家想比较深入的学习,下面的几个网站值得一看呢!!!

  很浅的语法:http://www.cnblogs.com/arlenhou/p/learn_expect.html

  例子虽短,但给我比较多启发的一个网站:https://www.centos.bz/tag/expect/

  expect学习笔记及实例详解(真的不错) :http://blog.itpub.net/27042095/viewspace-745589/

  Expect 教程中文版:http://fanqiang.chinaunix.net/a4/b8/20010912/1000001278.html

SCP

scp的语法是简单又实用,本来还想讲一下的。不过实在感觉下面这篇文档已经太棒了,所以这里直接给个连接吧!!!

SCP 命令:http://www.cnblogs.com/hitwtx/archive/2011/11/16/2251254.html

最后需要提一下的是,本程序中用到了利用ssh控制远程服务器执行命令的方法:

ssh <username>@<host> "<command1>;<command2>...<command3>"

如:ssh zhangsan@192.168.1.1 "cd /home;ls -l"

注意两个点:

1、双引号,必须有。如果不加双引号,第二个ls命令在本地执行;

2、分号,两个命令之间用分号隔开。

浅记初次使用expect、scp中出现的一些小问题的更多相关文章

  1. 在Android初次的前期学习中的二个小例子(2)

    Hello13:SQLite数据库 一.简述SQLite的概念和主要特性 SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,使用非常方便,支持SQL语法标准和数据库事务原则. 相对于Sh ...

  2. C# 中堆与栈的浅记

    C# 中堆与栈的浅记 什么是堆和栈? 简言之.堆和栈是驻留在内存中的区域,它们的作用是帮助我们运行代码.在.Net Framework 环境下,当我们的代码运行时,内存中的堆和栈便存储了这些代码,并包 ...

  3. C#中值类型和引用类型的差别浅记

    C#中值类型和引用类型的差别浅记         在C#中,变量的类型分为两种.各自是值类型和引用类型.         值类型的变量直接存储值,说得更详细一些,就是值类型变量在内存中直接存储它们自身 ...

  4. hybrid浅记

    目前首次接触hybrid项目,故根据翻阅了解后,浅记对它的认识. hybrid是携程推出的一个项目框架,其优点是:跨平台.开发效率高.开发成本相对较低,其不足是:体验不如Native hybrid设计 ...

  5. expect脚本中,变量的写法

    一.expect脚本中,变量的不同写法 shell脚本中定义时间变量的写法:time=`date "+%Y%m%d"` ==>>直接照搬到expect中,设置的变量是不 ...

  6. Nancy总结(二)记一次Nancy 框架中遇到的坑

    记一次Nancy 框架中遇到的坑 前几天,公司一个项目运行很久的Nancy框架的网站,遇到了一个很诡异的问题.Session 对象跳转到另外一个页面的时候,session对象被清空了,导致用户登录不上 ...

  7. 转:浅谈CSS在前端优化中一些值得注意的关键点

    前端优化工作中要考虑的元素多种多样,而合理地使用CSS脚本可以在很大程度上优化页面的加载性能,以下我们就来浅谈CSS在前端优化中一些值得注意的关键点: 当谈到Web的“高性能”时,很多人想到的是页面加 ...

  8. 浅谈Python在信息学竞赛中的运用及Python的基本用法

    浅谈Python在信息学竞赛中的运用及Python的基本用法 前言 众所周知,Python是一种非常实用的语言.但是由于其运算时的低效和解释型编译,在信息学竞赛中并不用于完成算法程序.但正如LRJ在& ...

  9. 记一次解决cmd中执行java提示"找不到或无法加载主类"的问题

    今天遇到一个问题:在cmd命令行中,用javac编译java文件可以成功,但是用java执行却提示“找不到或无法加载主类”.现将该问题的原因以及解决办法记录一下. 先理解一下系统变量path和clas ...

随机推荐

  1. Linux操作命令(四)

    本次实验将介绍 Linux 命令中 which.whereis.locate 命令的用法. which whereis locate 1.which which命令的作用是,在PATH变量指定的路径中 ...

  2. Continuous Subarray Sum II(LintCode)

    Continuous Subarray Sum II   Given an circular integer array (the next element of the last element i ...

  3. 解决vscode按下ctrl+S的时候自动格式化

    按下ctrl+S的时候自动格式化 为什么需要这种操作? 优点: 保存的时候格式化,让我们的代码自动格式化,减少人工调整. 缺点: 有一些打好包的JS有时候修改一下,但不需要格式化,因为打好包就是要压缩 ...

  4. Friends number NBUT - 1223 (暴力打表)

    Paula and Tai are couple. There are many stories between them. The day Paula left by airplane, Tai s ...

  5. 【BZOJ 2791】 2791: [Poi2012]Rendezvous (环套树、树链剖分LCA)

    2791: [Poi2012]Rendezvous Description 给定一个n个顶点的有向图,每个顶点有且仅有一条出边.对于顶点i,记它的出边为(i, a[i]).再给出q组询问,每组询问由两 ...

  6. 【最大流/费用流】BZOJ1834-[ZJOI2010]network 网络扩容

    [题目大意] 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费 ...

  7. codevs 1959 拔河比赛--判断背包内刚好装满n/2个物品

    1959 拔河比赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 一个学校举行拔河比赛,所有的 ...

  8. Manthan, Codefest 16 H. Fibonacci-ish II 大力出奇迹 莫队 线段树 矩阵

    H. Fibonacci-ish II 题目连接: http://codeforces.com/contest/633/problem/H Description Yash is finally ti ...

  9. Nginx + Keeplived双主测试

    Author: JinDate: 20130613Title: Nginx + Keeplived 双主测试 前言:一年多前做过一次测试,时间久了忘记了,现在又重新做一次 一.环境1.基本信息和规划p ...

  10. ms_sql_server_architecture

    We have classified the architecture of SQL Server into the following parts for easy understanding − ...