在shell脚本中使用expect实现scp传输问题

expect自动化scp传输
本文介绍如何使用expect工具自动化执行scp命令进行文件传输。首先通过安装tcl和expect环境,然后利用expect编写脚本实现自动输入密码及处理首次连接确认的过程。

1.安装expect

expect用于shell脚本中自动交互,其是基于tcl编程语言的工具。所以安装expect首先安装tcl。本文中使用的是expect5.45tcl8.6.6

安装tcl

[root@tseg0 /]$ mkdir /tools
[root@tseg0 /]$ tar -zxvf tcl8.6.6-src.tar.gz
[root@tseg0 /]$ cd tcl8.6.6/unix/
[root@tseg0 /]$ ./configure
[root@tseg0 /]$ make
[root@tseg0 /]$ make install

安装expect

[root@tseg0 /]$ cd /tools
[root@tseg0 /]$ tar -zxvf expect5.45.tar.gz
[root@tseg0 /]$ cd expect5.45/
[root@tseg0 /]$ ./configure --with-tcl=/usr/local/lib/ --with-tcl include=/tools/tcl8.6.6/generic/
[root@tseg0 /]$ make
[root@tseg0 /]$ make install

shell脚本实现scp传输

命令解释

-c 表示可以在命令行下执行except脚本;
spawn 命令激活一个unix程序来交互,就是在之后要执行的命令;
expect “aaa” 表示程序在等待这个aaa的字符串;
send 向程序发送字符串,expect和send经常是成对出现的,比如当expect“aaa”的时候,send“bbb”。

执行脚本

#! /bin/sh
expect -c "
    spawn scp -r /home/tseg/hello $name@10.103.240.33:/home/$name/
    expect {
        \"*assword\" {set timeout 300; send \"$pass\r\"; exp_continue;}
        \"yes/no\" {send \"yes\r\";}
    }
expect eof"

解释:
第二行: -c 表示可以不用与控制台交互;
第三行:spawn激活一个scp的unix程序;
第五行:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串, exp_continue表示执行下面的匹配;
第六航:expect期待含有“assword”的字符串,设置连接时间最大为300毫秒,如果出现这个字符串,就send 变量pass代表的密码字符串;
第八行:表示结束。

shell脚本使用scp命令有多种方式,以下为你详细介绍: ### 批量执行scp操作 ```bash #!/bin/bash remote_user="user_name" remote_host="ip_addrest" remote_port="port" remote_path="file_path" local_path="file_path" subdirectories=("0050_02" "your file names") for subdir in "${subdirectories[@]}"; do scp -P "$remote_port" -r "$remote_user@$remote_host:$remote_path/$subdir" "$local_path" done ``` 此脚本可批量执行scp操作,将远程主机上指定子目录下的文件复制到本地指定路径。其中,`-P`用于指定远程主机端口,`-r`表示递归复制目录及其内容[^1]。 ### 使用expect脚本结合scp自动输入密码 ```bash #!/usr/bin/expect set timeout 1 # 复制文件 spawn scp root@ip地址:/路径/文件名 . send "yes\r" expect "*password:" send "密码\r" interact ``` 该脚本使用`expect`工具结合`scp`命令,实现自动输入密码。`spawn`用于启动`scp`进程,`send`用于发送命令和密码,`expect`用于等待特定的提示信息[^3]。 ### 使用密钥文件避免密码输入 在主机A上执行如下命令生成配对密钥: ```bash ssh-keygen -t rsa ``` 遇到提示回车默认即可,公钥会被存到用户目录下的`.ssh`目录,如root用户存放在`/root/.ssh/id_rsa.pub`。将`.ssh`目录中的`id_rsa.pub`文件复制到主机B的`~/.ssh/`目录中,并改名为`authorized_keys`,在主机A中执行以下命令与主机B建立信任: ```bash scp ~/.ssh/id_rsa.pub 192.168.100.4:/root/.ssh/authorized_keys ``` 之后就可以使用`scp`、`ssh`命令无需密码获取主机B的文件,如: ```bash ssh 192.168.100.4 ``` 回车即可登录,无需输入密码[^4]。 ### 使用sshpass结合scp命令 ```bash #!/usr/bin/bash time=$(date "+%Y%m%d%H%M%S") mpath="/data/xxx/src_folder" dst="/data5/dst_folder" # 序号不连续的文件选择 models=(49 44 36 48 38 47 53 46 48 52 29) # 序号连续的文件选择:如从model-0069.params拷贝到model-0106.params models=$(seq 69 106) password="your_pass_word" username="your_user_name" Ip="10.xxx.xxx.xxx" # 序号不连续的for循环写法 for i in ${models[*]}; do i=$(printf '%04d' $i) # 文件名数字部分自动补0为4位 sshpass -p "$password" scp $mpath/model-$i.params $username@$Ip:$dst/ done # 序号连续的for循环写法 for i in $models; do i=$(printf '%04d' $i) sshpass -p "$password" scp $mpath/model-$i.params $username@$Ip:$dst/ done sshpass -p "$password" scp $mpath/model-symbol.json $username@$Ip:$dst/ echo "Done! $time" ``` 此脚本使用`sshpass`工具结合`scp`命令,通过循环将指定文件从本地复制到远程主机。`sshpass -p`用于指定远程主机的密码[^5]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值