从 Expect 脚本中的变量中删除回车符 (\r)

从 Expect 脚本中的变量中删除回车符 (\r)

设置 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 命令出现问题,因为它将文件名和目标目录放在新行上。导致无效命令:

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 变量中删除 \r,或者如何以不同方式填充 $sourceFile 变量以防止 (\r) 首先出现。

PS 我已经尝试了许多不同的尝试来使用 sed、awk 和 tr 但我尝试过的似乎都没有帮助。

答案1

发送密码并“按 Enter”后,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)来获取第一组括号捕获的文本。

相关内容