使用s3cmd进行棘手的stderr重定向

时间:2012-07-03 12:58:12

标签: php bash shell s3cmd

我有一些奇怪的行为,从s3cmd重定向stdout和stderr。例如:

$ touch test

$ s3cmd put test s3://non_existent_bucket
test -> s3://non_existent_bucket/test  [1 of 1]
 4 of 4   100% in    0s    88.17 B/s  done
ERROR: S3 error: 404 (NoSuchBucket): The specified bucket does not exist

这个输出是(如果我没有弄错的话)part stdout和part stderr。如下所示:

$ s3cmd put test s3://non_existent_bucket 2> log
test -> s3://non_existent_bucket/test  [1 of 1]
 4 of 4   100% in    0s   120.11 B/s  done

$ cat log
ERROR: S3 error: 404 (NoSuchBucket): The specified bucket does not exist

实际上,stderr被重定向,但我们想要stdout和stderr。我们先试试stdout:

$ s3cmd put test s3://non_existent_bucket > log
ERROR: S3 error: 404 (NoSuchBucket): The specified bucket does not exist

$ cat log

它不是在命令之后写的,所以我理解stdout实际上是重定向(或者某种东西),但它不会被日志文件捕获。我想它会以某种方式检测它是否连接到tty,并且只在第一种情况下输出这种数据。

以同样的方式,如果我尝试重定向两个流,我得到stderr但不是我需要的stdout输出:

$ s3cmd put test s3://non_existent_bucket >& log

$ cat log
ERROR: S3 error: 404 (NoSuchBucket): The specified bucket does not exist

事实上,我需要做的是从PHP调用它并获得完整的输出。我只找到了执行命令和检索stdout的方法,所以我做的如下:

exec('s3cmd put test s3://non_existent_bucket 2>&1', $output);

在这里,我没有从任何流中获得任何输出。我想我失去了stdout,因为s3cmd检测到它没有连接到tty,但是stderr我还是不明白它为什么没有被捕获。

尝试使用popen()和exec(),我得到了相同的结果。

我至少需要整个输出或stdout(虽然我猜进度信息会以某种方式被抓取)。有什么想法吗?

提前致谢!!

1 个答案:

答案 0 :(得分:1)

man page for s3cmd详细说明--progress / --no-progress标记,说明如下:

  

显示或不显示进度表。在TTY(例如console或xterm)上运行时,默认设置是显示进度表。如果没有在TTY上(例如输出被重定向到某个地方或从cron运行),则默认为不显示进度表。

所以看起来s3cmd会像isatty(0)那样确定是否将进度详细信息写入STDOUT,但是如果明确指定--[no-]progress则会强制执行一个或另一个行为。< / p>

尝试:

exec('s3cmd --progress put test s3://non_existent_bucket 2>&1', $output);