当您使用git时,它似乎神奇地知道标准输出是通过管道还是进入文件,以及何时显示到控制台。例如,如果您启用了颜色并且您执行了
git status
它将为列出的不同类别文件的输出着色。但是,如果你这样做
git status | less
或者
git status > status.txt
它删除了linux 颜色格式,你只能看到纯的、无色的文本。
如何git
检测其命令的输出是文件还是终端?
当您使用git时,它似乎神奇地知道标准输出是通过管道还是进入文件,以及何时显示到控制台。例如,如果您启用了颜色并且您执行了
git status
它将为列出的不同类别文件的输出着色。但是,如果你这样做
git status | less
或者
git status > status.txt
它删除了linux 颜色格式,你只能看到纯的、无色的文本。
如何git
检测其命令的输出是文件还是终端?
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.
这是一个 C 代码,用于演示如何检测标准输出是否被重定向:
int main(int argc, char **argv){ if (!isatty(fileno(stdout))){ fprintf(stdout, "argv, argc, 有人将我重定向到别处...\n"); 返回 1; } /* 剩下的 C 代码在这里... */ }
这就是 git 知道输出是发送到终端还是文件的方式。
可以确认这是 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 默认情况下,但这些当然可以重定向或关闭(通常,如果您是守护程序,则关闭文件描述符并重新打开所需的文件描述符)。
在 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