Trick an application into thinking its stdout is a terminal, not a pipe
我试着做与
检测stdin是终端还是管道?
我运行的应用程序正在更改其输出格式,因为它在stdout上检测到一个管道,我希望它认为它是一个交互式终端,以便在重定向时获得相同的输出。
我在想用
有什么想法吗?
啊哈!
1 | script --return -c"[executable string]" /dev/null |
耍把戏!
基于Chris的解决方案,我提出了以下小助手功能:
1 2 3 | faketty() { script -qfc"$(printf"%q""$@")" /dev/null } |
为了在
用途:
1 | faketty <command> |
例子:
1 2 3 4 5 6 | $ 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脚本应该处理这个OK。如果不是这样,应用程序可能正在寻找与其输出连接的对象以外的其他对象,例如,将术语环境变量设置为什么。
我不知道它是否可以从PHP实现,但是如果您真的需要子进程来查看tty,您可以创建一个pty。
在C:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #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...] ", 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 */ } |
不过,我当时的印象是,
参考前面的答案,在Mac OS X上,"脚本"可以如下使用…
1 | script -q /dev/null commands... |
但是,因为它可能会将返回代码从""更改为"
",所以我需要这样运行。
1 2 3 4 | script -q /dev/null commands... | perl -pe 's/ / /g' |
如果这些命令之间有一些管道,则需要清除stdout。例如:
1 2 3 4 5 | script -q /dev/null commands... | ruby -ne 'print".... ";STDOUT.flush' | perl -pe 's/ / /g' |
对于具体的答案,我还不太了解,但我想我会跟进上面的Ingomueller网络发布的
我发现这是在创建一个我不想要/不需要的
在"Unix环境中的高级编程,第二版"这本书的示例代码中还包含一个pty程序!
以下是如何在Mac OS X上编译PTY:
http://codesnippets.joyent.com/posts/show/8786