暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Expect命令用法详解及实例

IT那活儿 2025-06-09
64

点击上方“IT那活儿”公众号--专注于企业全栈运维技术分享,不管IT什么活儿,干就完了!!!


  
在Linux环境中,自动化脚本是系统管理员和开发人员的重要工具。Expect是一个用于自动化交互式应用程序(如ssh、ftp等)的脚本工具。

通过Expect,你可以编写脚本来自动处理这些应用程序的交互过程,从而大大提高工作效率。本文将介绍Expect的基本用法,并通过实例展示如何在文件上传和下载中使用Expect。



Expect基础

Expect脚本的基本结构包括:

  • 设置超时时间
    set timeout命令用于设置Expect脚本的超时时间。
  • 启动程序
    spawn命令用于启动一个需要交互的程序。
  • 捕获输出
    expect命令用于捕获程序的输出,并根据输出执行相应的操作。
  • 发送输入
    send命令用于向程序发送输入。字符串末尾需要加上\r来表示回车。

Expect实例

以下将通过两个实例展示Expect在文件上传和下载中的应用,其中${portid}、${username}、${ip}、${passwd_var}根据实际填写端口号、用户名、主机IP和用户登录密码。

2.1 文件上传实例

假设你有一个配置文件,其中记录了本地目录、远端目录和文件名,你需要将这些文件上传到远程服务器:

#!/usr/bin/ksh
###配置文件格式:本地目录|远端目录|文件名
for line_info in $(sed 's/[ \t]*//g' /home/rate/pandao_pcs/conf_pcs/pcs_up_238.conf)
do
    #local_dir remote_dir filename
    #获取目录和文件名
    local_dir=$(echo"${line_info}"  | awk -F \| '{print $1}' |sed 's/[ \t]*//g')
    remote_dir=$(echo"${line_info}" | awk -F \| '{print $2}' |sed 's/[ \t]*//g')
    file_name=$(echo"${line_info}"  | awk -F \| '{print $3}' |sed 's/[ \t]*//g')
    
    cd${local_dir}
    file=`ls ${file_name}`
    if [ -z "${file}" ];then
        echo $(date) >> home/rate/pandao_pcs/log/noupfile_238.log
        echo"没有${file_name}文件" >> home/rate/pandao_pcs/log/noupfile_238.log
    fi
    for final_file in${file}
    do
        echo $(date) >> home/rate/pandao_pcs/log/upfile_238.log
        echo${final_file} >> home/rate/pandao_pcs/log/upfile_238.log
        usr/bin/expect <<EOF
        set timeout 10000
        spawn sftp -oPort=${portid}${username}@${ip}
        expect {
           -nocase "*password:"
           {
               send "${passwd_var}\r"
           }
        }
        expect {
           -nocase "sftp>"
           {
               send "cd ${remote_dir}\r"
           }
        }
        expect {
           -nocase "sftp>"
           {
               send "put ${final_file}\r"
           }
        }
        expect {
          -nocase "sftp>"
          {
              send "bye\r"
          }
        }
EOF
        #清理上传的文件
        rm ${final_file}
    done
done

2.2 文件下载实例

与上传类似,假设你有一个配置文件,记录了需要从远程服务器下载的文件信息:

#!/usr/bin/ksh
###配置文件格式:本地目录|远端目录|文件名
for line_info in $(sed 's/[ \t]*//g' /home/rate/pandao_pcs/conf_pcs/pcs_down_238.conf)
do
    #
    #获取目录和文件名
    local_dir=$(echo"${line_info}"  | awk -F \| '{print $1}' |sed 's/[ \t]*//g')
    remote_dir=$(echo"${line_info}" | awk -F \| '{print $2}' |sed 's/[ \t]*//g')
    file_name=$(echo"${line_info}"  | awk -F \| '{print $3}' |sed 's/[ \t]*//g')
    mkdir -p ${local_dir}/temp
    temp_dir="${local_dir}/temp"
    #将文件下载到临时目录
    usr/bin/expect <<EOF
    set timeout 10000
    spawn sftp -oPort=${portid}${username}@${ip}
    expect {
       -nocase "*password:"
       {
           send "${passwd_var}\r"
       }
    }
    expect {
       -nocase "sftp>"
       {
           send "lcd ${temp_dir}\r"
       }
    }
    expect {
       -nocase "sftp>"
       {
           send "cd ${remote_dir}\r"
       }
    }
    expect {
       -nocase "sftp>"
       {
           send "mget ${file_name}\r"
       }
    }
    expect {
      -nocase "sftp>"
      {
          send "bye\r"
      }
    }
EOF
    
    #列出文件并删除
    cd${local_dir}/temp
    file=`ls ${file_name}`
    for i in${file}
        do
        usr/bin/expect <<EOF
                set timeout 10000
                spawn sftp -oPort=${portid}${username}@${ip}
                expect {
                   -nocase "*password:"
                   {
                       send "${passwd_var}\r"
                   }
                }
                expect {
                   -nocase "sftp>"
                   {
                       send "cd ${remote_dir}\r"
                   }
                }
                expect {
                   -nocase "sftp>"
                   {
                       send "ls ${i}\r"
                   }
                }
                expect {
                  -nocase "sftp>"
                  {
                      send "bye\r"
                  }
                }
EOF
        done
        
        #将临时目录文件移到正式目录
        mv ${file_name}${local_dir}
done


总 结

通过上述实例,我们可以看到Expect在自动化文件传输中的强大功能。无论是文件上传还是下载,Expect都能通过捕获和发送命令来简化复杂的交互过程。

在实际应用中,你可以根据具体需求对Expect脚本进行扩展和优化,以满足更复杂的自动化需求。


END


本文作者:孙华伟(上海新炬中北团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论