欺骗一个应用程序,认为它的标准input是交互式的,而不是pipe道

我正试图做相反的事情

检测标准input是一个terminal或pipe道?

我正在运行一个应用程序,它正在改变它的输出格式,因为它检测到一个标准输出pipe道,我想它认为这是一个交互式的terminal,所以当redirect时我得到相同的输出。

我想包装它在一个期望的脚本或使用PHP中的proc_open()会做到这一点,但事实并非如此。

有任何想法吗?

啊哈!

script命令做我们想要的…

 script --return -c "[executable string]" /dev/null 

诀窍!

基于克里斯的解决scheme ,我想出了以下小帮手function:

 function faketty { script -qfc "$(printf "%q " "$@")"; } 

看起来很奇怪的printf对于正确地扩展$@的脚本参数是必要的,同时保护了可能引用的命令部分(参见下面的示例)。

用法:

 faketty <command> <args> 

例:

 $ python -c "import sys; print sys.stdout.isatty()" True $ python -c "import sys; print sys.stdout.isatty()" | cat False $ faketty python -c "import sys; print sys.stdout.isatty()" | cat True 

Expect自带的unbuffer脚本应该可以处理这个问题。 如果没有,应用程序可能会看到一些东西,而不是它的输出连接到,例如。 TERM环境variables设置为什么。

在Python安装的地方,

 echo fakepassword | python -c 'import pty, sys; pty.spawn(sys.argv[1:])' ssh 

我不知道PHP是否可行,但是如果你确实需要subprocess来看一个TTY,你可以创build一个PTY 。

在C:

 #include <stdio.h> #include <stdlib.h> #include <sysexits.h> #include <unistd.h> #include <pty.h> int main(int argc, char **argv) { int master; struct winsize win = { .ws_col = 80, .ws_row = 24, .ws_xpixel = 480, .ws_ypixel = 192, }; pid_t child; if (argc < 2) { printf("Usage: %s cmd [args...]\n", argv[0]); exit(EX_USAGE); } child = forkpty(&master, NULL, NULL, &win); if (child == -1) { perror("forkpty failed"); exit(EX_OSERR); } if (child == 0) { execvp(argv[1], argv + 1); perror("exec failed"); exit(EX_OSERR); } /* now the child is attached to a real pseudo-TTY instead of a pipe, * while the parent can use "master" much like a normal pipe */ } 

其实,我的印象是, expect自己确实创造了一个PTY。

引用前面的回答,在Mac OS X上,“脚本”可以像下面一样使用…

 script -q /dev/null commands... 

但是,因为它可能会将返回码从“\ n”更改为“\ r \ n”,所以我需要像这样运行。

 script -q /dev/null commands... | perl -pe 's/\r\n/\n/g' 

如果这些命令之间有一些pipe道,则需要刷新标准输出。 例如:

 script -q /dev/null commands... | ruby -ne 'print "....\n";STDOUT.flush' | perl -pe 's/\r\n/\n/g' 

太新,以评论具体的答案,但我想我会跟上上面的网站上发表的faketty函数,因为它最近帮助我。

我发现这是创build一个我不想/需要的typescript文件,所以我添加了/ dev / null作为脚本目标文件:

function faketty { script -qfc "$(printf "%q " "$@")" /dev/null ; }

在“UNIX环境下的高级编程第二版”一书的示例代码中也包含了一个pty程序!

以下是如何在Mac OS X上编译pty:

http://codesnippets.joyent.com/posts/show/8786