Bash:欺骗程序进入思考stdout是一个交互式终端

时间:2013-02-04 15:33:42

标签: bash shell pipe

我想通过管道运行程序的输出,但是当它检测到stdout不是交互式shell时,它显然表现不同。

如何在正常情况下通过管道欺骗它?

3 个答案:

答案 0 :(得分:16)

我假设程序将调用glibc函数isatty()来检查stdout是否是终端。这对于在终端上使用彩色输出或ANSI终端的其他功能(如光标定位或线擦除/重绘)的程序来说很常见。

您可以使用LD_PRELOAD环境变量欺骗程序。 LD_PRELOAD由ELF链接器处理,并告知动态库应该在之前加载所有其他动态库。使用此功能可以覆盖库函数,例如glibc函数isatty()。例如,您可以按照article进行操作。

我为你准备了一个例子:

首先创建文件 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;
}

并将其编译为共享库:

gcc -shared -o libisatty.so  libisatty.c

它应该很好。

现在是时候测试库了。 :)我已经使用命令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

你应该看到彩色输出。

btw cool usename:uʍopǝpısdn!!:D

答案 1 :(得分:2)

使用script对我有用:

script outputfile.txt yourcommand
# any output ends up in outputfile.txt

你可以用它来管道我猜:

script out.txt yourcommand ; cat out.txt | nextcommand

答案 2 :(得分:0)

你可能想试试这个:

./script.sh < `tty` > output

如果程序正在执行isatty(0)之类的操作,这可能就足够了。