scp + expect 实现全自动传送文件

          嵌入式工作中总会有各种需求,比如这次,客户希望在板子上实现scp免确认,直接传送文件。那是经过一番折腾,可算是实现了,前因后果,且看下面慢慢道来。

          scp 工作模式 ,当用scp 传送文件时,首次总会让确认

$ scp vimrc [email protected]:~
The authenticity of host '192.168.9.250 (192.168.9.250)' can't be established.
ECDSA key fingerprint is SHA256:SXkTDqjo+6RFecNQPGw4DxgX9lz8qmphja4HbHR8rL8.
Are you sure you want to continue connecting (yes/no)? 

其大概意思就是,要传送的目的ip(此处的192.168.9.250)不是本机 ~/.ssh/known_hosts 里面,~/.ssh/known_hosts 其实是一张表,记录这所有可以直接scp的host ip。

        要避免确认的方法有很多, 比如更改ssh的配置文件、第一次确认后即可等。但是有这样一个应用场景,嵌入式板子中没有ssh的配置文件,如这里用的自研imx6q平台,但是客户有希望开机启动时进行文件同步,完全不给输入 yes的机会。哦豁~  这个咋个整嘛~,客户又得罪不起多。

      哈哈,经过一番查找,不得不说,很感谢度娘的强大和技友(技术朋友)们的热心,有人说可以通过 expect 自动和终端进行交互实现,那咱们也试试。经过大半天的尝试,完成如下脚本,名之曰为 auto_scp:

#!/usr/bin/expect

spawn scp test.txt [email protected]:~

expect {
 "y/n" {exp_send "y\r"; interact}
}

在终端下通过命令 $ expect auto_scp ,即可成功自动传送文件到目标机上。这里需要说明的一点是,pc 上使用scp和嵌入式平台使用scp 提示信息可能有出入,所以 expect匹配也是不一样的。如这里 匹配 "y/n"是imx6q平台上的;而在pc上验证的时候匹配的是"yes/no"。

        auto_scp 脚本大概表述是, 先执行一个scp的动作,通过spawn 关键字执行。expect { } 里进行匹配和执行相关的操作,双引号表示匹配的内容,匹配成功后执行后面的 exp_send 操作,发送一个字符'y'并回车。然后继续执行 interact,即把执行权交还终端。

       那么问题又来了,嵌入式平台没有expect命令。移植呗,有源码还不能搞点事情阿 ^_^ . 这里需要两个部分的源码交叉编译,tcl 和 expect。why? because  expect depend on tcl 啊~

tcl移植思路:拉源码-》配置编译(中间省略N个步骤 🙈),直接上步骤

wget http://prdownloads.sourceforge.net/tcl/tcl8.4.20-src.tar.gz   # get source codes

tar xvf tcl8.6.20-src.tar.gz                                      # unzip
cd tcl8.6.20/
cd unix/                                                          # path to work

export tcl_cv_type_64bit="long long"     
export ac_cv_c_bigendian=no
export tcl_cv_strtod_buggy=1
export ac_cv_func_strstr=yes
export ac_cv_func_opendir=yes                           #  export necessary  environment variable 


./configure --prefix=/usr/lib  --host=arm-linux        # configure

#export toolchain
 source /opt/fslc-framebuffer/2.5/environment-setup-armv7at2hf-neon-fslc-linux-gnueabi 

make V=s
make install

这里有一个小经验分享一下,最好将安装路径配置为  "/usr/lib" ,因为在嵌入式平台执行expect时,会根据安装路径去找init.tcl,一定会根据 安装路径去找的!安装不一定会成功,也可以不安装,毕竟编译成功就会成功了90%了。

expect编译

expect
wget http://sourceforge.net/projects/expect/files/Expect/5.45/expect5.45.tar.gz


./configure  --prefix=expect_install --with-tcl=xxxx/tcl_install/lib --with-tclinclude=xxx/tcl_install/include --host=x64

expect 配置需要指定tcl的头文件和库,然后指定host为x86的, 因为expect 不支持交叉编译,据说有patch,无奈时间不等人,先产生makefile然后再改吧,这也是曲线救国阿。修改makefile中的 CC 和AR,编译即可生成所需的expect和库。部署到板子上,大功告成!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章