嵌入式工作中總會有各種需求,比如這次,客戶希望在板子上實現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和庫。部署到板子上,大功告成!