我想通过管道运行一个程序的输出,但当它检测到stdout
不是交互式shell时,它会表现得不同。
如何欺骗它以正常情况下的方式通过管道写入?
我假设该程序会调用glibc函数isatty()
来检查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;
}
然后将其编译为共享库:
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 环境变量执行第二个命令:LD_PRELOAD=./libisatty.so ls --color=auto | cat
您应该看到彩色输出。
顺便说一句,用户名很酷:uʍop ǝpısdn !!:D
DYLD_INSERT_LIBRARIES=./libisatty.so DYLD_FORCE_FLAT_NAMESPACE=y ls -G | cat
(请注意,--color标志在Mac的ls上不起作用) - Christopher Shroba使用script
对我有效:
script outputfile.txt yourcommand
# any output ends up in outputfile.txt
我猜你可以用这个来进行管道操作:
script out.txt yourcommand ; cat out.txt | nextcommand
script
зҡ„жәҗд»Јз Ғеә”иҜҘдјҡжҸӯзӨәеҮәзЁӢеәҸз”ЁжқҘеҲӨж–ӯе®ғ们жҳҜеҗҰеңЁдәӨдә’ејҸиҝҗиЎҢж—¶жүҖдҪҝз”Ёзҡ„йҷӨдәҶisatty
д№ӢеӨ–зҡ„е…¶д»–дёңиҘҝгҖӮ - ntc2./script.sh < `tty` > output
isatty(0)
的操作,这可能已经足够了。ls --color=auto < \
tty` | cat`,你能看到颜色吗?我看不到。(我假设你已经执行了 dircolors 命令) - hek2mgl
expect
是一个很好的程序来完成这个任务。 - BeniBelascript
程序,请查看:https://dev59.com/dXM_5IYBdhLWcg3wZSE6#1402389 - Emmanuel Touzery