我正在尝试使用来自Eclipse的命令管道启动一个shell,例如:
/bin/bash -c "external_tool_executable parameters | grep pattern"
grep应该是一个外部程序,而不是一个插件,所以我可以使用自定义脚本/程序。
但是当我在“外部工具配置:
中设置以下内容时Location:
/bin/bash
Arguments:
-c
"ping -c 10 google.com | grep time"
只有在完成所有操作后,输出才会显示在控制台中(没有grep time
一切正常)。进程树显示外部工具不是多线程的:
andrey@andrey-SX58:~$ ps axjf
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
4164 4165 2145 2145 ? -1 Sl 1000 2:23 | \_ /usr/bin/java -Djava.library.path=/usr/lib/x86_64-linux-gnu/jni/ -Dosgi.requiredJavaVersion=1.6 -XX:MaxPermSize=256m -Xms40m -Xmx512m -jar /data/vdt/eclipse_01//plugins/org.eclipse.equinox.launcher
4165 4978 2145 2145 ? -1 S 1000 0:00 | \_ /bin/bash -c ping -c 10 google.com | grep time
4978 4983 2145 2145 ? -1 S 1000 0:00 | \_ ping -c 10 google.com
4978 4985 2145 2145 ? -1 S 1000 0:00 | \_ grep time
当我从常规控制台(没有Eclipse)运行时会有所不同 - 输出按预期显示 - 一次一行
andrey@andrey-SX58:~$ /bin/bash -c 'ping -c 10 google.com | grep time'
andrey@andrey-SX58:~$ ps axjf
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
2281 5072 5072 5072 pts/27 5121 Ss 1000 0:00 | \_ /bin/bash
5072 5121 5121 5072 pts/27 5121 S+ 1000 0:00 | \_ /bin/bash -c ping -c 10 google.com | grep time
5121 5122 5121 5072 pts/27 5121 S+ 1000 0:00 | \_ ping -c 10 google.com
5121 5123 5121 5072 pts/27 5121 S+ 1000 0:00 | \_ grep time
我错过了一些愚蠢的选择吗?
安德烈
Update1:我错了,进程树只为Eclipse应用程序显示“l”,而不是在独立模式下显示bash。
我被建议使用--line-buffered
和grep,它可以工作 - 但我仍然不明白为什么它可以工作,以及为什么从控制台启动shell时不需要它。
答案 0 :(得分:0)
根据grep(1):
--line-buffered Force output to be line buffered. By default, output is line buffered when standard output is a terminal and block buffered otherwise.
Eclipse 可能不使用适当的流来捕获已启动进程的输出。 ping 可能并不关心,只是输出和刷新任何tty,而grep有一个不同的方法,如手册页中所定义。
grep 检测到(使用isatty(3))它没有在流对象上运行,因此不会刷新每一行。
一个简单的程序可以在bash(mygrep)上显示这种行为:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char** argv)
{
printf("isatty: %s\n", isatty(fileno(stdout))? "true": "false");
return 0;
}
如果使用管道运行,如下所示:
你会看到:$ ping google.com | ./mygrep
isatty:true
但是使用:
$ ./mygrep&gt;临时文件
你会得到:
isatty:false