我正在进行标准重定向:
$ cat file.txt | /usr/bin/program
但是如果我直接在终端和复制粘贴输入中运行它,程序的行为会有所不同。 当输入是终端时,它显示进度条。无论如何,我想要进度条。
简而言之,我如何“欺骗”输入来自终端的程序而不是从文件重定向?
答案 0 :(得分:4)
使用expect
程序可能最简单;它为你做了大部分必要的工作。
必要的工作是繁琐的。它涉及使用伪ttys,它是寻找终端等程序的设备。如果您打算自己动手,那么您需要知道的POSIX系统调用是:
posix_openpt()
接口相对较新(问题6,与问题4,版本2相比,列出的其他功能)。如果你的系统没有posix_openpt()
,你需要自己找一本Unix书籍(可能是Stevens或Rochkind)来了解如何打开pty的主方面,或阅读你的系统手册相当仔细。但是,上面链接中posix_openpt()
的基本原理也可能有所帮助 - 它还有使用其他功能的指南。 Linux有posix_openpt()
; Mac OS X也是如此,通常推断BSD系统。
书籍:
W Richard Stevens,Stephen A Rago Advanced Programming in the Unix Environment, 3rd Edn
Marc J Rochkind Advanced Unix Programming, 2nd Edn
答案 1 :(得分:3)
我假设程序将调用glibc函数isatty()
来检查stdin / stdout是否是终端。对于在终端上使用彩色输出或ANSI终端的其他功能(如光标定位或线擦除/重绘)的程序而言,这是常见的。
您可以使用LD_PRELOAD环境变量欺骗程序。 LD_PRELOAD由ELF链接器处理,并告知动态库应该在之前加载所有其他动态库。使用此功能可以覆盖库函数,例如glibc函数isatty()
。
这是一个例子:
libisatty.c
/**
* Overrides the glibc function. Will always return true.
*
* Note: Although this should be ok for most applications it can
* lead to unwanted side effects. It depends on the question
* why the programm calls isatty()
*/
int isatty(int param) {
return 1;
}
生成文件
# Make the shared Library
lib: libisatty.c
gcc -shared -Wl,-soname,libisatty.so.1 -o libisatty.so.1.0 libisatty.c
ln -s libisatty.so.1.0 libisatty.so.1
ln -s libisatty.so.1 libisatty.so
运行:
make lib
它应该构建良好,我已经在Ubuntu12.04 AMD 64上进行了测试。
现在是时候测试库了。 :)我已经使用命令ls --color=auto
进行测试。 ls
调用isatty()
来决定是否应该将其输出着色。如果将输出重定向到文件或管道,则不会将其着色。您可以使用以下命令轻松测试:
ls --color=auto # should give you colorized output
ls --color=auto | cat # will give you monochrome output
现在我们将使用LD_PRELOAD环境var再次尝试第二个命令:
LD_PRELOAD=libisatty.so ls --color=auto | cat
你应该看到彩色输出。
答案 2 :(得分:2)
你需要使用伪tty来获得你想要的效果。 'man pty'会告诉你更多关于它的信息。