[英]Spawning interactive CLI command with Expect exits with 0 early, when run as Symfony Process in Behat context
这是一个非常先进的问题,也许没有必要了解Symfony和Behat来理解这个问题。
因此,为了测试我使用Symfony控制台组件用PHP编写的交互式CLI应用程序bin/albumgrab
的输入和输出,我已经设置了我的Behat特性上下文来构建一个expect
脚本,通过exec
运行。
此exec
命令通过Symfony Process
在PHP中运行。
$expect = <<<BASH
exec expect -c '
set timeout 180
spawn bin/albumgrab
expect "Please enter the name of the directory"
send "/tmp/php-london\n"
expect "Please enter the URL to the first image"
send "https://www.facebook.com/PeeHPLondon/photos/pb.7119218495.-2207520000.1430669248./10153559172718496/?type=3&src=https%3A%2F%2Ffbcdn-sphotos-g-a.akamaihd.net%2Fhphotos-ak-xfp1%2Fv%2Ft1.0-9%2F10986697_10153559172718496_5727444485530442900_n.jpg%3Foh%3Dc47770f4cd15fecc6888bcd504899087%26oe%3D55DA9CB0%26__gda__%3D1439174101_7c78a93bf247dbad6c56681b6db5309c&size=960%2C959&fbid=10153559172718496\\n"
interact
'
BASH;
$process = new Symfony\Component\Process\Process($expect);
$process->mustRun();
但是,当它超过第二个输入时,它似乎退出但成功。
呼叫:
$process->setTty(true);
使它一直运行,但会直接打印到stdout,我不能再捕获输出来进行断言,即使使用PHP的输出缓冲也是如此。
我认为PTY无论如何都会更合适:
$process->setPty(true);
因为它是StackOverflow问题的解决方案。 但是,这在任何地方都不受支持,至少在Mac OS X上不支持。
您可以在Github中看到我到目前为止所尝试的内容: https : //github.com/adamelso/albumgrab/pull/13/files和最后一次尝试的Travis输出https://travis-ci.org/adamelso/ albumgrab /职位/ 61137499
所以我的主要问题是它为什么一直提前退出0以及如何防止它?
为了能够接收问题的答案 - 您肯定需要终端(TTY)或伪终端(PTY)来获得任何用户输入。
这就是为什么 - 没有$process->setTty(true)
或setPty(true)
- QuestionHelper默默地回退到默认值,命令成功,退出代码为0。
现在 - 使用示例用户输入来测试命令 - 您应该使用symfony的控制台助手组件而不是使用expect。
Symfony\Component\Console\Helper\HelperSet
Symfony\Component\Console\Tester\CommandTester
如何使用这些助手在烹饪书章节测试期望输入的命令中进行了描述。
根据Expect Script wait命令挂起的答案,您需要等待EOF而不是使用interact
命令:
set timeout 180
spawn ./bin/albumgrab
expect "Please enter the name of the directory"
send "/tmp/php-london\n"
expect "Please enter the URL to the first image"
send "https://www.facebook.com/PeeHPLondon/photos/pb.7119218495.-2207520000.1430669248./10153559172718496/\n"
expect EOF
这是我用来在OS X上测试它的完整脚本:
<?php
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\Process\Process;
$expect = <<<BASH
exec expect -c '
set timeout 180
spawn ./bin/albumgrab
expect "Please enter the name of the directory"
send "/tmp/php-london\n"
expect "Please enter the URL to the first image"
send "https://www.facebook.com/PeeHPLondon/photos/pb.7119218495.-2207520000.1430669248./10153559172718496/?type=3&src=https%3A%2F%2Ffbcdn-sphotos-g-a.akamaihd.net%2Fhphotos-ak-xfp1%2Fv%2Ft1.0-9%2F10986697_10153559172718496_5727444485530442900_n.jpg%3Foh%3Dc47770f4cd15fecc6888bcd504899087%26oe%3D55DA9CB0%26__gda__%3D1439174101_7c78a93bf247dbad6c56681b6db5309c&size=960%2C959&fbid=10153559172718496\\n"
expect EOF
'
BASH;
$process = new Process($expect);
$process->setPty(true);
$process->start();
$process->wait(function ($type, $buffer) {
if (Process::ERR === $type) {
echo 'ERR > '.$buffer;
} else {
echo 'OUT > '.$buffer;
}
});
if (!$process->isSuccessful()) {
throw new \RuntimeException($process->getErrorOutput());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.