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

发布于 2024-08-18 21:37:08 字数 501 浏览 7 评论 0原文

当您使用 git 时,它似乎神奇地知道标准输出是否通过管道或进入文件与显示到控制台时的情况。例如,如果您启用了颜色并且您

git status

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

git status | less

或者

git status > status.txt

它会删除 linux 颜色格式你只能看到简单的、无色的文本。

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

When you use git it seems to magically know whether standard out is going through a pipe or into a file vs when it is being displayed to the console. For example, if you have colors enabled and you do

git status

it will colorize the output for different categories of files being listed. However, if you do

git status | less

or

git status > status.txt

it removes the linux color formatting and you only see plain, uncolored text.

How does git detect whether the output of its commands are going to file vs going to the terminal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烙印 2024-08-25 21:37:08

istty(int fd) 将检查 fd 是否引用终端或其他东西。它是 GNU C 库中 unistd.h 的一部分。

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

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

isatty(int fd) will check whether the fd refers to a terminal or something else. It's part of unistd.h in the GNU C library.

Man page: http://linux.die.net/man/3/isatty

As an aside: if you want to read from a program using another program, but you want to fool isatty into thinking that your program is a human, there is a way to do that. You can use a pseudo-terminal (pty). This technique is used by expect, for example.

南街女流氓 2024-08-25 21:37:08

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

int main(int argc, char **argv){
    if (!isatty(fileno(stdout))){
      fprintf(stdout, "argv, argc, someone is redirecting me elsewhere...\n");
      return 1;
    }
    /* rest of C code here... */
}

这就是 git 知道输出是发送到终端还是发送到文件的方式。

This is a C Code to demonstrate how to detect if standard output is redirected:

int main(int argc, char **argv){
    if (!isatty(fileno(stdout))){
      fprintf(stdout, "argv, argc, someone is redirecting me elsewhere...\n");
      return 1;
    }
    /* rest of C code here... */
}

That is how git knows whether the output is going to the terminal or to a file.

墟烟 2024-08-25 21:37:08

可以确认这就是 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,但这些当然可以重定向或关闭(通常,如果您是守护程序,则关闭文件描述符并重新打开您想要的文件描述符)。

Can confirm that's what git relies on:

$ 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).

Run against the git source tree.

Note that fds 0=stdin, 1=stdout, 2=stderr by default, but these can of course be re-directed or closed (typically if you are a daemon you close your file descriptors and re-open the ones you want).

酷炫老祖宗 2024-08-25 21:37:08

在 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

From a shell script, use the -t test flag applied to the file descriptor 0 (standard input).

Examples:

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

# Modern interactive shells: ksh, bash, zsh
[[ -t 0 ]] && echo This is a terminal
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文