OSX bash & 期待
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15096740/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OSX bash & expect
提问by John Oliver
I have a script that must perform a 'sudo' operation on each of a number of hosts. I'm trying to get expect working so I only have to enter it once, and have run into a couple of issues.
我有一个脚本,必须在多个主机中的每一个上执行“sudo”操作。我正在尝试让 expect 工作,所以我只需要输入一次,并且遇到了一些问题。
First, several examples suggest to use:
首先,几个例子建议使用:
/usr/bin/expect <<EOD
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
EOD
However, as soon as I enter the second '<', all of the quoting gets screwed up, and my script will terminate with an unexpected end of file. This is really strange, as I use the same mechanism with cat to write out files in other scripts.
然而,一旦我输入第二个“<”,所有的引用都会被搞砸,我的脚本将以意外的文件结尾终止。这真的很奇怪,因为我使用与 cat 相同的机制在其他脚本中写出文件。
Other examples suggest:
其他例子表明:
/usr/bin/expect -c "
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
"
Doing it this way (and adding -d to expect), I get errors about no tty and a repeat of my password with an 'n' appended to the end, so it isn't sending a newline (I've tried '\r' as well), but instead appears to be escaping the 'n'
这样做(并添加 -d 以期望),我收到关于 no tty 的错误,并且我的密码重复并在末尾附加了“n”,因此它不会发送换行符(我试过 '\ r'),但似乎是在逃避 'n'
Since most of the examples I'm finding are from Linux, I expect (ha, ha, pun not intended!) that they're using a GNU expect, and I'm using a BSD expect. I am reading through the man page, but the word "spawn" appears so many times, it could be quite a while before I stumble across the correct instance.
由于我找到的大多数示例都来自 Linux,我希望(哈哈,双关语不是故意的!)他们使用的是 GNU 期望,而我使用的是 BSD 期望。我正在阅读手册页,但是“spawn”这个词出现了很多次,可能需要很长时间才能偶然发现正确的实例。
Here's a result that seems to be closest to working:
这是一个似乎最接近工作的结果:
flamingo:~ jnojr$ Scripts/getinfo_expect.sh
Assuming you have one 'sudo' password for all of your hosts, enter it now:
expect version 5.45
spawn /usr/bin/ssh -t macbook /usr/bin/sudo -v
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {67358}
expect: does "" (spawn_id exp7) match glob pattern "Password:"? no
Password:
expect: does "Password:" (spawn_id exp7) match glob pattern "Password:"? yes
expect: set expect_out(0,string) "Password:"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "Password:"
send: sending "password\n" to { exp7 }
argv[0] = /usr/bin/expect argv[1] = -d argv[2] = -c argv[3] =
spawn /usr/bin/ssh -t macbook /usr/bin/sudo -v
expect Password: { send password\n }
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
sudo: no tty present and no askpass program specified[/CODE]
That's with leaving the '\n' outside of the quotes, as in
那是将 '\n' 留在引号之外,如
send "$SUDOPASS"\n
It seems to be mostly working, except skipping the '-t' option to ssh
除了跳过 ssh 的“-t”选项外,它似乎大部分都在工作
回答by morgant
I second @BrianCain's comment that passwordless sshw/sudowould be a better solution. That said, let's try to help with your expectscript and you can decide whether it continues to be too much of a headache.
我支持@BrianCain 的评论,即无密码sshw/sudo将是更好的解决方案。也就是说,让我们尝试帮助您expect编写脚本,您可以决定它是否仍然令人头疼。
I believe you're going to want to use expect -f -(read the script from STDIN) when using the bash"here string" (<<) to input the script to expect. So:
我相信expect -f -在使用bash“此处字符串”( <<) 将脚本输入到expect. 所以:
/usr/bin/expect -f - <<EOD
spawn ssh -t $host /usr/bin/sudo -v
expect "Password:"
send "$SUDOPASS\n"
EOD

