【问题标题】:In linux, how can I test whether the output of a program is going to a live terminal or to a file?在 linux 中,如何测试程序的输出是发送到实时终端还是发送到文件?
【发布时间】:2011-01-09 17:04:27
【问题描述】:

当您使用git 时,它似乎神奇地知道标准输出是通过管道还是进入文件,以及何时显示到控制台。例如,如果您启用了颜色并且您这样做了

git status

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

git status | less

git status > status.txt

它会删除linux color formatting,而您只会看到纯文本。

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

【问题讨论】:

  • 我不认为这应该在超级用户上,因为 OP 真正要寻找的是程序如何,即。 git 检测它是否被重定向。
  • 我同意@tommieb75,这是一个 API 问题,而不是我如何管理问题。
  • 顺便说一句,如果你不只是好奇,而且你问这个是因为你想对 git 的输出进行着色,你可以弄乱@987654328 @ 设置,例如 core.pager(更少)和 color.pager(真)。 kernel.org/pub/software/scm/git/docs/git-config.html

标签: linux terminal xterm gnome-terminal konsole


【解决方案1】:

isatty(int fd) 将检查 fd 是指终端还是其他东西。它是 GNU C 库中 unistd.h 的一部分。

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

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

【讨论】:

    【解决方案2】:

    这是一个 C 代码,用于演示如何检测标准输出是否被重定向:

    int main(int argc, char **argv){ if (!isatty(fileno(stdout))){ fprintf(stdout, "argv, argc, 有人将我重定向到别处...\n"); 返回 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 默认情况下,但是这些当然可以重定向或关闭(通常,如果您是守护进程,则关闭文件描述符并重新打开您的文件描述符)想要)。

      【讨论】:

        【解决方案4】:

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

        例子:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-16
          • 1970-01-01
          • 2020-10-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-30
          • 1970-01-01
          相关资源
          最近更新 更多