在Linux中,我如何测试程序的输出是发送到实时终端还是文件?

9

当你使用git时,它似乎神奇地知道标准输出是通过管道还是进入文件,而不是显示到控制台。例如,如果启用了颜色,并且执行以下命令:

git status

这将为列出的不同文件类别着色输出。但是,如果您这样做

git status | less

或者
git status > status.txt

它会移除Linux颜色格式,只显示纯文本。

git如何检测其命令的输出是前往文件还是前往终端?


3
我认为这不应该出现在Superuser上,因为原帖作者真正想知道的是程序(如git)如何检测它是否被重定向。 - t0mm13b
2
我同意 @tommieb75 的观点,这是一个API问题,而不是一个如何管理的问题。 - user257111
顺便说一下,如果你不只是出于好奇,而是想要从git中获得彩色和分页输出,你可以通过更改git config设置来实现,例如core.pager(less)和color.pager(true)。http://www.kernel.org/pub/software/scm/git/docs/git-config.html - rescdsk
4个回答

14

isatty(int fd)将检查fd是否指向终端或其他内容。它是GNU C库中的unistd.h的一部分。

手册页面:http://linux.die.net/man/3/isatty

顺便说一下:如果您想使用另一个程序读取程序,但是您想欺骗isatty,使其认为您的程序是人类,则有一种方法可以做到这一点。您可以使用pseudo-terminal(pty)。例如,这种技术被expect使用。


8
以下是关于如何检测标准输出是否被重定向的C代码示例:
int main(int argc, char **argv){
    if (!isatty(fileno(stdout))){
      fprintf(stdout, "argv, argc, 有人将我的输出重定向到其他地方了...\n");
      return 1;
    }
    /* 其余的C代码在这里... */
}
这就是git如何知道输出是发送到终端还是文件中的方法。

3

我可以确认这就是Git所依赖的:

$ grep -ir "isatty" ./*
./builtin-commit.c:     if (isatty(0))
./builtin-config.c:         stdout_is_tty = isatty(1);
./builtin-pack-objects.c:   progress = isatty(2);
./builtin-prune-packed.c:   int opts = isatty(2) ? VERBOSE : 0;
./builtin-revert.c: if (isatty(0))
./builtin-shortlog.c:   if (!nongit && !rev.pending.nr && isatty(0))
./builtin-unpack-objects.c: quiet = !isatty(2);
./color.c:      stdout_is_tty = isatty(1);
./compat/winansi.c: if (!isatty(fileno(stream)))
./compat/winansi.c: if (!isatty(fileno(stream)))
./pack-redundant.c: if (!isatty(0)) {
./pager.c:  if (!isatty(1))
./pager.c:  if (isatty(2))
./remote-curl.c:    options.progress = !!isatty(2);
./transport.c:  args.no_progress = args.quiet || (!transport->progress && !isatty(1));
./transport-helper.c:   int no_progress = v < 0 || (!t->progress && !isatty(1));
./wt-status.c:   * will have checked isatty on stdout).

针对git源代码运行。

请注意,默认情况下,fds 0=stdin,1=stdout,2=stderr,但这些当然可以被重定向或关闭(通常如果您是守护程序,您会关闭文件描述符并重新打开您想要的那些)。


3

从shell脚本中,使用-t测试标志应用于文件描述符0(标准输入)。

示例:

# Any Bourne-style shell
[ -t 0 ] && echo This is a terminal

# Modern interactive shells: ksh, bash, zsh
[[ -t 0 ]] && echo This is a terminal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接