期待内部bash+;打开(从机):错误的文件号+;父级:同步字节写入:断开的管道

期待内部bash+;打开(从机):错误的文件号+;父级:同步字节写入:断开的管道,bash,expect,Bash,Expect,我正在bash脚本中使用expect脚本。 我试图将文件从远程主机复制到本地主机。我面临的错误是 打开(从pty):错误的文件号+父级:同步字节写入:断开的管道 守则: #!/bin/bash read -p "Enter username: " username read -s -p "Enter password: " password #Expect script /bin/expect -<<EOD set SERVERS {100 101 102} foreach

我正在bash脚本中使用expect脚本。 我试图将文件从远程主机复制到本地主机。我面临的错误是

打开(从pty):错误的文件号+父级:同步字节写入:断开的管道

守则:

#!/bin/bash

read -p "Enter username: " username
read -s -p "Enter password: " password

#Expect script
/bin/expect -<<EOD 

set SERVERS {100 101 102}

foreach SERVER \$SERVERS {
set timeout -1
spawn scp ${username}@plsa\${SERVER}.corp.com:/log.2011-11-24 log.2011-11-24 
expect "*password:"; send "$password\r"
expect eof }
EOD
#/bin/bash
阅读-p“输入用户名:”用户名
阅读-s-p“输入密码:”密码
#期望脚本

/bin/expect-这并不能完全回答您的问题,但是为什么要用bash包装expect脚本呢?如果您在bash中所做的唯一一件事就是读取几行输入,那么您最好将其移动到expect中:

#!/usr/bin/env expect

send_user "Enter username: "
expect_user -re "(.*)\n" {set username $expect_out(1,string)}

send_user "Enter password: "
stty -echo
expect_user -re "(.*)\n" {set password $expect_out(1,string)}
stty echo

set SERVERS {100 101 102}

foreach SERVER \$SERVERS {
set timeout -1
spawn scp ${username}@plsa\${SERVER}.corp.com:/log.2011-11-24 log.2011-11-24 
expect "*assword:"; send "$password\r"
expect eof }
现在,您已经删除了一整层复杂性,这可能会使实际错误更易于调试。另外,请注意,scp会提示“Password”,而不是“Password”,所以您需要像我在这里所做的那样修改匹配字符串

另外一个问题:是否可以对这些连接使用基于ssh密钥的身份验证而不是密码身份验证?这将简化整个过程——在本例中,您根本不需要与expect混在一起。你可以这样做:

for server in 100 101 102; do
  scp -i mykey ${username}@plsa${SERVER}.corp.com:/log.2011-11-24 log.2011-11-24
done

这是其中一个“不应该发生”的错误。例如,本FAQ中的以下问题提到可能是C库的故障。另一种可能是您已经用完了一些系统资源(文件描述符)。最可能的原因是您在循环中调用spawn,而忽略了调用close和wait


我知道这篇文章很旧,重新打开旧文章被认为是不好的,但是搜索这个错误信息会不断地把谷歌发送到这里,所以我认为这可能是一个很好的地方来回答它

根据我的经验,我发现造成这种情况的许多可能原因之一与以下事实有关:Expect正在对系统上的其他程序进行库调用,在我的情况下,我无法使用我的用户权限运行这些辅助程序。我一直无法找出是哪个库调用导致了该问题,但是

username All=(ALL) /path/to/your/script
进入
visudo
为我修复了它。显然,您不必颁发一揽子权限,但允许用户使用sudo root权限执行脚本可以提供Expect所需的访问权限。我只是想加上这个,希望它能在将来帮助别人