zoukankan      html  css  js  c++  java
  • 信号处理 & expect免交互命令执行

    一 信号处理

    # 1 什么是信号
    	由键盘组合键或者kill命令发出操作称之为信号
        
        信号是发送给进程的,进程在收到信号后会作出默认的响应
        
    # 2 为何要在进程内处理信号
        进程在收到信号后会有默认的响应,
        如果我们想改变进程在接收到信号后的反应,那么需要在进程内捕捉信号执行我们自定义的操作
        
    # 3 主要的应用场景:
        	在进程内捕捉终止信号,然后忽略掉,从而达到让进程不受外界干扰正常运行完毕的效果
            
            ps:不是所有的信号都可以被捕捉,比如-9
            
            
    3、如何处理信号
    
        trap "捕捉到信号之后要执行的命令" 信号
        trap "" 信号		                        # 如不指定执行信息则当做不做处理
        trap "" 信号1 信号2 信号3 			# 多个信号都不做处理
    

    trap信号列表

    信号 说明
    HUP 挂起,通常因终端掉线或用户退出而引发
    INT 中断,通常因按下Crtl+C组合健而引发
    QUIT 退出,通常因某些严重的执行错误而引发
    TERM 终止,通常在系统关机时发送
    TSTP 停止进程的运行,但该信号可以被处理和忽略,用户健入SUSP字符时(通常是Ctrl-Z)发出这个信号
    ABRT 中止,通常因某些严重的执行错误而引发
    • 示例如
    # 使用此方式执行脚本,对键盘执行的ctrl+c ctrl+z等其他操作都不会进行操作,以往执行ctrl+c都是停止。
    
    · 这里主要实现对脚本循环执行红绿灯,并且此脚本执行过程中不受下方信号影响。
    [root@tcy day07]# cat 3.sh 
    #!/bin/bash
    
    trap "" INT QUIT HUP TERM TSTP				# 当执行这些信号都不会做任何操作
    
    clear
    n=0
    
    while :
    do
        [ $n -eq 0 ] && n=1 || n=0    
    
        if [ $n -eq 1 ];then
            echo -e "33[31m 红灯亮 33[0m"
        else
            echo -e "33[32m 绿灯亮 33[0m"
        fi
        
        sleep 0.5
        clear
    done 
    

    HUP信号的处理:让一个进程脱离当前会话窗口运行

    nohup脱离父进程

    • (需将其终端关闭,才能将父进程改变为系统进程,否则为终端进程)

      # 在终端2内
      [root@tcy ~]# echo $$
      12479
      [root@tcy ~]# nohup ping www.baidu.com &
      
      # 关闭终端2
      
      # 在终端1内仍然可以看到进程(但其父进程为系统进程)
      [root@tcy ~]# ps -ef |grep [p]ing
      root      13169      1  0 18:58 ?        00:00:00 ping www.baidu.com
      
    • setsid(直接让父进程为系统进程)

      setsid ping www.baidu.com &
      
    • (进程 &) 直接让父进程为系统进程

      (ping www.tcy.com &)
      [root@db01 ~]# ps -ef|grep tcy
      root       8333      1  0 22:46 pts/1    00:00:00 ping www.tcy.com
      root       8360   8336  0 22:46 pts/2    00:00:00 grep --color=auto tcy
      

    二 expect

    expect介绍

    在使用expect时,基本上都是和以下四个命令打交道:

    命令 作用
    spawn 启动新的进程
    expect 从进程接收字符串
    send 用于向进程发送字符串
    interact 允许用户交互
    • spawn命令用来启动新的进程,spawn后的expectsend命令都是和使用spawn启动的新进程进行交互。
    • expect通常用来等待一个进程的反馈,我们根据进程的反馈,再使用send命令发送对应的交互命令。
    • send命令接收一个字符串参数,并将该参数发送到进程。
    • interact命令用的其实不是很多,一般情况下使用spawnexpectsend和命令就可以很好的完成我们的任务;但在一些特殊场合下还是需要使用interact命令的,interact命令主要用于退出自动化,进入人工交互。比如我们使用spawnsendexpect命令完成了ftp登陆主机,执行下载文件任务,但是我们希望在文件下载结束以后,仍然可以停留在ftp命令行状态,以便手动的执行后续命令,此时使用interact命令就可以很好的完成这个任务。

    expect基本使用

    # 前期需要安装expect安装包
    [root@db01 day08]# yum install -y expect
    
    # send指令提交方式(两者都可对指令进行提交)
    
    
    
    
    [root@tcy day07]# cat 4.sh 
    #!/usr/bin/expect 					# 这里虽然是脚本,但是需要指定解释器为expect
    spawn ssh root@127.0.0.1 hostname	                # 执行进程操作指令
    expect "yes/no"						# 等待进程反馈,匹配yes/no的指令
    send "yes
    "						# 根据expect匹配的指令进行操作,也就是直接帮助yes提交
    
    expect "assword"					# 继续等待进程反馈,屁屁额assword指令
    send "1
    "				                # 根据匹配的指令进行1操作,这里也就是我的密码
    
    expect eof						# 结束交互指令
    
    # 总结:
    这种操作存在弊端,只适用于第一次连接,如第二次进行ssh连接,可忽略yes步骤,直接输入密码即可,expect比较愚蠢,
    不会只能匹配,而是在第二次连接时当需要输入密码,直接也将第一次匹配的yes直接发送,也就导致了后续的报错。
    所以这里为了解决此问题,可参考expect一问一答中的案例操作。
    

    强调:我们此时编写的是expect脚本,不要用sh 4.sh执行,可以./4.sh运行,也可以expect 4.sh运行

    expect 一问一答(推荐使用)

    # 这里会根据进程指令自动匹配,所以需要将操作匹配指令写入同一个expect中进行处理。
    
    #!/usr/bin/expect 
    spawn ssh root@127.0.0.1 hostname
    
    expect {
        "yes/no" {send "yes
    ";exp_continue}    
        "*assword" {send "1
    ";}
    }
    
    expect eof
    

    远程登录主机执行多条命令

    # 可免交互式登录主机执行多条语句,注意,这里都是expect语句,不能按照shell语句方式执行
    
    [root@tcy day07]# cat 6.sh 
    #!/usr/bin/expect 
    
    spawn ssh root@127.0.0.1
    
    expect {
        "yes/no" {send "yes
    ";exp_continue}    
        "*assword" {send "1
    ";}
    }
    
    expect {
        "#" {send "ls
    "}			# 这里为匹配#交互式指令,到匹配到就执行ls命令
    }
    
    expect {
        "*root*" {send "pwd
    "}		# 这里为匹配root交互式指令,匹配到就执行pwd指令
    }
    
    expect {
        "#" {send "exit
    "}			# 这里为匹配# 指令,匹配到就执行exit指令,相当于回到自己的终端
    }
    
    expect eof		                # 结束交互式操作,但还在远程的终端中,超时才会自动退出
    

    interact(了解)

    [root@tcy day07]# cat 7.sh 
    #!/usr/bin/expect 
    
    spawn ssh tcy@127.0.0.1
    
    expect {
        "yes/no" {send "yes
    ";exp_continue}    
        "*assword" {send "1
    ";}
    }
    
    expect {
        "*tcy*" {send "ls
    "}
    }
    
    expect {
        "*tcy*" {send "pwd
    "}
    }
    
    interact			 # 运行完以上指令,不进行超时退出,任然停留在远程终端中			
    expect eof	
    
    
    

    在expect脚本中定义变量

    # 使用的并不是bash解释器,所以需要expect自身语法。
    #!/usr/bin/expect 
    set user "root"					         # 类似于bash的定义变量user=root
    set pass "1"
    set ip "127.0.0.1"
    set cmd "hostname"
    
    spawn ssh $user@$ip $cmd				 # 调用上方定义变量开启进程
    
    expect {
        "yes/no" {send "yes
    ";exp_continue}    
        "*assword" {send "$pass
    ";}
    }
    
    expect eof
    

    把expect引入shell脚本(推荐使用)

    # 单学expect较为复杂,可将expect引入bash中。
    
    #!/bin/bash							# 使用bash解释器
    
    user="root"							# 使用bash的方式定义变量
    pass="1"
    ip="127.0.0.1"
    cmd="hostname"
    
    expect << EOF							# 引expect在bash中也是一个命令,所以将其
    spawn ssh $user@$ip $cmd				        # 内容放入一个内容体当中
    
    expect {
        "yes/no" {send "yes
    ";exp_continue}    
        "*assword" {send "$pass
    ";}
    }
    
    expect eof
    EOF
    
    echo "success!!!"						
    
  • 相关阅读:
    无监督学习在反欺诈中的应用
    Java中Object对象方法
    ambari下httpfs安装
    深入理解spark-rdd详解
    Tensorflow实践Basic Classification
    深入理解spark-两种调度模式FIFO,FAIR模式
    深入理解spark-taskScheduler,schedulerBackend源码分析
    js模仿页面点击
    记一次请求走私学习
    十种常见的报错注入
  • 原文地址:https://www.cnblogs.com/tcy1/p/13596557.html
Copyright © 2011-2022 走看看