欺骗一个应用程序,认为它的标准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: