shell-2

关于 Tcl 和 Expect 的语法,请参考 Unix/Linux 平台任务的自动化相关部分。

QUOTE:

例 1: 下面是一个 telnet 到指定的远程机器上自动执行命令的 Expect 脚本, 该脚本运行时的输出如下:

# /usr/bin/expect sample_login.exp root 111111

spawn telnet 10.13.32.30 7001

Trying 10.13.32.30...

Connected to 10.13.32.30.

Escape character is ‘^]‘.

accho console login: root

Password:

Last login: Sat Nov 13 17:01:37 on console

Sun Microsystems Inc. SunOS 5.9 May 2004

#

Login Successfully...

# uname -p

sparc

# ifconfig -a

lo0: flags=2001000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4,VIRTUAL> mtu 8232 index

1

inet 127.0.0.1 netmask ff000000

eri0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2

inet 10.13.22.23 netmask ffffff00 broadcast 10.13.22.255

ether 0:3:ba:4e:4a:aa

# exit

accho console login:

Finished...

ChinaUnix 论坛 Shell 版精华帖合集 - Made by UNREGISTERED version of Easy CHM

382

QUOTE:

下面是该脚本的源代码:

# vi sample_login.exp:

proc do_console_login {login pass} {

set timeout 5

set done 1

set timeout_case 0

while ($done) {

expect {

"console login:" { send "$loginn" }

"Password:" { send "$passn" }

"#" {

set done 0

send_user "nnLogin Successfully...nn"

}

timeout {

switch -- $timeout_case {

0 { send "n" }

1 {

send_user "Send a return...n"

send "n"

}

2 {

puts stderr "Login time out...n"

exit 1

}

}

incr timeout_case

}

}

}

}

proc do_exec_cmd {} {

set timeout 5

send "n"

expect "#"

send "uname -pn"

ChinaUnix 论坛 Shell 版精华帖合集 - Made by UNREGISTERED version of Easy CHM

383

expect "#"

send "ifconfig -an"

expect "#"

send "exitn"

expect "login:"

send_user "nnFinished...nn"

}

if {$argc<2} {

puts stderr "Usage: $argv0 login passwaord.n "

exit 1

}

set LOGIN [lindex $argv 0]

set PASS [lindex $argv 1]

spawn telnet 10.13.32.30 7001

do_console_login $LOGIN $PASS

do_exec_cmd

close

exit 0

上面的脚本只是一个示例,实际工作中,只需要重新实现 do_exec_cmd 函数就可以解决类似问题了。

我们看一看这样的一个例子脚本:

#! /usr/bin/expect

spawn ftp 202.199.248.11

expect "Name"

send "ftpr"

expect "Password:"

send "nothingr"

expect "apply"

send "cd /pub/UNIX/Linux/remoteXr"

expect "successful."

send "binr"

expect "set to I"

send "get exceed5.zipr"

expect "complete."

send "quitr"

ChinaUnix 论坛 Shell 版精华帖合集 - Made by UNREGISTERED version of Easy CHM

394

这个是什么意思?呵呵,就是个自动下载程序。第一行说明这个程序应该调用/usr/b

in/expect 去执行,然后的就是 expect 命令。

我们可以把建立连接

的命令放在一个循环里面,并且根据回应的不同自动选择重新输入命令还是继续执行:

spawn ftp

while {1} {

expect "ftp>"

send "o 202.199.248.11r"

expect {

"Connected" break

"refused" { sleep 10} ;

}

ChinaUnix 论坛 Shell 版精华帖合集 - Made by UNREGISTERED version of Easy CHM

396

}

这里使用了我们在 tcl 语言中讲到的 while 和 break 命令,熟悉 C 的读者应该很容易看出

它的行为:不断地等待 ftp>提示符,在提示符下面发送连接远端服务器的命令,如果服

务器回应是 refused(连接失败) ,就等待 10 秒钟,然后开始下一次循环;如果是 Conne

cted,那么就跳出循环执行下面的命令。sleep 是 expect 的一个标准命令,表示暂停若干

秒钟。

gawk ‘/foo/ {print $0}‘ BBS-list

实际的 gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜

寻输入档里的每一行是否含有子字串 ‘foo‘,如果含有 ‘foo‘ 则执行 action。

action 为 print $0,是将现在这一行的内容印出。BBS-list 是输入的档案。

#删除一个文件中前 10 行

sed ‘1,10d‘

# delete the last line of a file

#删除一个文件中最后 1 行

sed ‘$d‘

#删除一个文件中最后 2 行

sed ‘N;$!P;$!D;$d‘

#删除一个文件中后 10 行

sed -e :a -e ‘$d;N;2,10ba‘ -e ‘P;D‘ # method 1

sed -n -e :a -e ‘1,10!{P;N;D;};N;ba‘ # method 2

#删除文件所有空白行(似于"grep ‘.‘ ")

sed ‘/^$/d‘ # method 1

sed ‘/./!d‘ # method 2

#删除文件开头部分中的所有空白行

sed ‘/./,$!d‘

#打印一个文件的后 10 行(仿"tail")

sed -e :a -e ‘$q;N;11,$D;ba‘

sed ‘$!N;$!D‘

输出文件最后 2 行,相当于 tail -2 foo

# 在每一行中查找字串“foo”,并将找到的“foo”替换为“bar”

sed ‘s/foo/bar/‘ # 只替换每一行中的第一个“foo”字串

sed ‘s/foo/bar/4‘ # 只替换每一行中的第四个“foo”字串

sed ‘s/foo/bar/g‘ # 将每一行中的所有“foo”都换成“bar”

sed ‘s/\(.*\)foo\(.*foo\)/\1bar\2/‘ # 替换倒数第二个“foo”

规则

表达式 描述

/./ 将与包含至少一个字符的任何行匹配

/../ 将与包含至少两个字符的任何行匹配

/^#/ 将与以 ‘#‘ 开始的任何行匹配

/^$/ 将与所有空行匹配

/}^/ 将与以 ‘}‘(无空格)结束的任何行匹配

/} *^/ 将与以 ‘}‘ 后面跟有零或多个空格结束的任何行匹配

/[abc]/ 将与包含小写 ‘a‘、‘b‘ 或 ‘c‘ 的任何行匹配

/^[abc]/ 将与以 ‘a‘、‘b‘ 或 ‘c‘开始的任何行匹配

当编辑指令(参照[section 2.2])在命令列上执行时 , 其前必须加上选项 -e 。其命令格式如下 :

sed -e ‘编辑指令 1‘ -e ‘编辑指令 2‘ ... 文件檔

首先理解一个()的情况

举个例子:

[[email protected] root]# echo "111(222)333"| sed ‘s/(\(.*\))/\1\1/‘

111222222333

因为(\(.*\)只有这一个部分,所以\1 就意味着这一个部分提取两次(如果是\2 就应该提不到东西)

[[email protected] root]# echo "111(222)333"| sed ‘s/(\(.*\))/\1\2/‘

sed:-e 表达式 #1,字符 16:Invalid reference \2 on `s‘ command‘s RHS

由于(不是元字符,所以直接写(就表示(这个符号,而\(才表示包含什么的意思

而又因为是()里面的内容,所以将 222 提取两次

如果将()去掉,例如

[[email protected] root]# echo "111(222)333"| sed ‘s/\(.*\)/\1\1/‘

111(222)333111(222)333

那么提取的匹配就是这个部分了

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

[[email protected] root]# echo "111(222)333"| sed ‘s/\(.*\)(\(.*\))/\1\1\1/‘

111111111333

因为//里面是由\(.*\) 和 (\(.*\))两部分组成,而\1 仍然是提取第一部分,也就是(222)前的所有内容

和(222)这个整个部分替换为(222)前的所有内容提取三次,其后的 333 不变

[[email protected] root]# echo "111(222)333"| sed ‘s/\(.*\)(\(.*\))/\2\2\2/‘

ChinaUnix 论坛 Shell 版精华帖合集 - Made by UNREGISTERED version of Easy CHM

696

222222222333

将(222)前的所有部分和(222)看成一个整体,被替换为()内的部分,也就是 222。

此处理解\2\2\2,2 的含义应该是提取第二个\(.*\)即:“第二个包含” 得意思也就是: (将()换成 yy 也

是一样得含义)

[[email protected] root]# echo "111y222y333"| sed ‘s/\(.*\)y\(.*\)y/\2\2\2/‘

222222222333

时间: 2024-11-06 16:33:09

shell-2的相关文章

【Linux系列】【基础版】第四章 Shell基础之正则表达式

4. Shell基础之正则表达式     4.1 正则就是一串有规律的字符串         4.1 grep              4.1.1 格式: grep [-cinrvABC] 'word' filename             4.1.2 -c //count,表示行数             4.1.3 -i //不区分大小写             4.1.4 -n  //显示行号             4.1.5 -r  //遍历所有子目录             4

linux Shell函数

Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以速度很快,另外,Shell还能对函数进行预处理,所以函数的启动比脚本更快. 1.函数定义 1 2 3 4 function 函数名() {     语句     [return] } 关键字function表示定义一个函数,可以省略,其后是函数名,有时函数名后可以跟一个括号,符号"{"表示函数执行命令的入口,该符号也可以在函数名那一行,"}"表示函数体的结

Shell实现跳板机,为什么用跳板机

整理自:http://blog.chinaunix.net/uid-22101889-id-3167454.html 注意:请谨慎使用,到现在为止,使用了,我还没找到改回去的方法. 1.     问题 第一.很多大公司的服务器都不允许直接登录,而是通过一个跳板机才能登录过去.在跳板机中,通常只能执行几个少数命令(如SSH),而其他命令是不允许执行的,那么怎样才能实现这个功能呢? 第二.一些小公司,由于服务器比较少,不需要什么跳板机之类的说法,公司的开发运维人员加起来也就那么十几二十人,通常大家都

linux shell基础语法

1.第一个Shell脚本 打开文本编辑器,新建一个文件,扩展名为sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用php写shell 脚本,扩展名就用php好了. 输入一些代码: #!/bin/bash echo "Hello World !" "#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell.echo命令用于向窗口输出文本. 运行Shell脚本有两种方法. 1.1作为可执行程序 将上面的代码保存为t

shell中test命令方法详解

test命令用法.功能:检查文件和比较值 1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                  两个表达式都为真 test 表达式1 –o 表达式2                 两个表达式有一个为真 2)判断字符串 test –n 字符串                                   字符串的长度非零 test –z 字符串                          

shell脚本

-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]-d filename 如果 filename为目录,则为真 [ -d /tmp/mydir ]-r filename 如果 filename可读,则为真 [ -r /var/log/syslog ]-w filename 如果 filename可写,则为真 [ -w /var/mytmp.txt ]-x filename 如果 filename可执行,则为真 [ -L /usr/bin/gr

20.5 Shell脚本中的逻辑判断;20.6 文件目录属性判断;20.7 if特殊用法;20.8 20.9 cace判断(上下)

扩展: select用法 http://www.apelearn.com/bbs/thread-7950-1-1.html 20.5 Shell脚本中的逻辑判断 格式1:if 条件 ; then 语句; fi 1. 创建if1.sh测试脚本: [[email protected] ~]# vi if1.sh a=5,如果a大于3,满足这个条件,显示ok 添加内容: #!/bin/bash a=5 if [ $a -gt 3 ] then echo ok fi 2. 执行if1.sh脚本: [[e

20.1 Shell脚本介绍;20.2 Shell脚本结构和执行;20.3 date命令用法;20.4 Shell脚本中的变量

20.1 Shell脚本介绍 1. shell是一种脚本语言 aming_linux blog.lishiming.net 2. 可以使用逻辑判断.循环等语法 3. 可以自定义函数 4. shell是系统命令的集合 5. shell脚本可以实现自动化运维,能大大增加我们的运维效率 20.2 Shell脚本结构和执行 1. 开头(首行)需要加: #!/bin/bash 2. 以#开头的行作为解释说明: 3. 脚本的名字以.sh结尾,用于区分这是一个shell脚本 4. 执行.sh脚本方法有两种:

shell 中seq的用法 echo -n用法

用法:seq [选项]... 尾数 或:seq [选项]... 首数 尾数 或:seq [选项]... 首数 增量 尾数 从1循环到100的两种方法(bash 其它的shell没试过)for x in `seq 1 100`;do echo $x;donefor x in {1..100};do echo $x;done echo -n 不换行输出 $echo -n "123" $echo "456" 最终输出 123456 echo -e 处理特殊字符 若字符串中

shell之数组的使用

数组 Array 一段连续的内存空间 1) 定义数组 [[email protected] shell]# aa[0]=martin [[email protected] shell]# aa[1]=jerry [[email protected] shell]# aa[2]=mike [[email protected] shell]# aa[10]=alice [[email protected] shell]# bb=(192.168.1.1 192.168.1.2 192.168.1.3