2010-01-26 9 views
8

Quando si utilizza git sembra sapere magicamente se lo standard sta passando attraverso una pipe o in un file vs quando viene visualizzato sulla console. Ad esempio, se hai i colori abilitati e lo faiIn Linux, come posso verificare se l'output di un programma sta per un terminale live o su un file?

git status 

colorerà l'output per diverse categorie di file elencati. Tuttavia, se si fa

git status | less 

o

git status > status.txt 

rimuove il linux color formatting e si vede solo pianura, il testo incolore.

In che modo git rileva se l'output dei comandi sta andando al file o al terminale?

+3

Non credo che questo dovrebbe essere il superutente, come l'OP sta veramente cercando è come funziona il programma di esempio. git rileva dove viene reindirizzato o meno. – t0mm13b

+2

Sono d'accordo con @ tommieb75 si tratta di una domanda API, non di come faccio una domanda di amministrazione. –

+0

A proposito, se non fossi solo curioso, e lo stavi chiedendo perché volevi avere un output "colorized" * e * paginato da git, puoi fare pasticci con le impostazioni di 'git config' come' core.pager' (meno) e 'color.pager' (true). http://www.kernel.org/pub/software/scm/git/docs/git-config.html – rescdsk

risposta

14

isatty(int fd) controllerà se la fd si riferisce a un terminale o qualcos'altro. Fa parte di unistd.h nella libreria GNU C.

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

Per inciso: se si desidera leggere da un programma utilizzando un altro programma, ma si vuole ingannare i isatty a pensare che il vostro programma è un essere umano, c'è un modo per farlo . È possibile utilizzare un pseudo-terminal (pty). Questa tecnica è utilizzata da expect, ad esempio.

8

Questo è un codice C per dimostrare come rilevare se standard output viene reindirizzato:

 
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... */ 
} 

che è come git sa se l'uscita è andare al terminale o in un file.

3

può confermare che è quello che si basa su 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). 

corsa contro l'albero dei sorgenti git.

Nota che fds 0 = stdin, 1 = stdout, 2 = stderr di default, ma questi possono naturalmente essere reindirizzati o chiusi tu vuoi).

2

Da uno script di shell, utilizzare il flag di prova -t applicato al descrittore di file 0 (input standard).

Esempi:

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

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