Bash

從期望腳本中的變數中刪除輸入符 (r)

  • June 13, 2019

安裝 Ubuntu 16.04 期望腳本

在下面的簡單腳本中,目標是使用 ssh 在遠端電腦上的目錄中簡單地找到最舊的 .zip 文件。

然後使用 scp 將此文件下載到本地“workingBuild”目錄。

目前腳本

#!/usr/bin/expect
set user "hidden"
set pass "hidden"
set sourceDir "/opt/tomcat/someDirectoryName/"
set workingDir "/home/someUser/workingBuild"

spawn sh -c "ssh $user@www ls -t $sourceDir | head -1"
expect "password:"
send "$pass\r"
expect -re ".*\.zip"

set sourceFile $expect_out(0,string)
spawn sh -c "echo 'bob'$sourceFile'bob2'"

spawn sh -c "scp $user@www:$sourceDir$sourceFile $workingDir"
expect {
       password: {send "$pass\r"; exp_continue}
}

問題

似乎我在儲存的文件名前面的 $sourceFile 變數中填充了一個隱藏的輸入符 (\r)。這反過來又導致 scp 命令出現問題,因為它將文件名和destinationDirectory 放在這樣的新行上。導致無效命令:

spawn sh -c scp meliudaj@www:/opt/tomcat/someDirectoryName/
build_0.0.1.zip /home/meliudaj/workingBuild

上面程式碼中的以下調試行也證明了這一點:

spawn sh -c "echo 'bob'$sourceFile'bob2'"

$sourceFile’bob2’ 總是在 ‘bob’ 下面的新行上

期望的結果是這樣的:

spawn sh -c scp meliudaj@www:/opt/tomcat/someDirectoryName/ build_0.0.1.zip /home/meliudaj/workingBuild

問題

我怎樣才能從 $ sourceFile variable, or how can I populate the $ sourceFile 變數以不同的方式防止 (\r) 首先出現。

PS 我已經嘗試了許多不同的嘗試來使用 sed、awk 和 tr 但我嘗試過的任何嘗試似乎都沒有幫助。

在您發送密碼並“按輸入”後,ssh 所做的第一件事就是發出一個換行符。您沒有在從 expect_out 緩衝區中提取的文本中考慮這一點。另請注意,expect 使用 CRNL 來表示換行符,我理解這是為了與一些網路協議標准保持一致。

這個互動式期望會話幾乎重現了這個問題。最後,我將變數的內容髮送到外部命令od以查看其中的確切內容:

expect1.1> spawn sh -c {read password; ls -t | head -1}
spawn sh -c read password; ls -t | head -1
42945
expect1.2> send "\r"
expect1.3> expect "*.zip"

somefile.zip
expect1.4> set sourceFile $expect_out(0,string)

somefile.zip
expect1.5> exec od -c << $sourceFile
0000000  \r  \n   s   o   m   e   f   i   l   e   .   z   i   p
0000016

您要做的是擷取以“.zip”結尾的文本,該文本出現在最後一個換行符之後。使用正則表達式相當簡單:

expect1.1> spawn sh -c {read password; ls -t | head -1}
spawn sh -c read password; ls -t | head -1
42992
expect1.2> send "\r"
expect1.3> expect -re {.*\r\n(.*\.zip)}

somefile.zip
expect1.4> set sourceFile $expect_out(1,string)
somefile.zip
expect1.5> exec od -c << $sourceFile
0000000   s   o   m   e   f   i   l   e   .   z   i   p
0000014

請注意使用(1,string)來獲取第一組括號擷取的文本。

引用自:https://unix.stackexchange.com/questions/524564