2015-02-08 14 views

risposta

8

Secondo il codice sorgente grep GNU, il grep controllare gli i-nodi di ingresso ed uscita:

if (!out_quiet && list_files == 0 && 1 < max_count 
     && S_ISREG (out_stat.st_mode) && out_stat.st_ino 
     && SAME_INODE (st, out_stat)) /* <------------------ */ 
    { 
     if (! suppress_errors) 
     error (0, 0, _("input file %s is also the output"), quote (filename)); 
     errseen = 1; 
     goto closeout; 
    } 

Il out_stat è riempito chiamando fstat contro STDOUT_FILENO.

if (fstat (STDOUT_FILENO, &tmp_stat) == 0 && S_ISREG (tmp_stat.st_mode)) 
    out_stat = tmp_stat; 
+0

Grazie per la risposta, ho dimenticato di come il guscio in realtà imposta descrittori di file del processo in anticipo e che grep potrebbe verificare informazioni su questi. – iobender

+0

@iobender, prego. – falsetru

2

Guardando il codice sorgente - si può vedere che esso controlla per questo caso (il file è già aperto per la lettura da parte di grep) e le relazioni, vedi la verifica SAME_INODE di seguito:

/* If there is a regular file on stdout and the current file refers 
    to the same i-node, we have to report the problem and skip it. 
    Otherwise when matching lines from some other input reach the 
    disk before we open this file, we can end up reading and matching 
    those lines and appending them to the file from which we're reading. 
    Then we'd have what appears to be an infinite loop that'd terminate 
    only upon filling the output file system or reaching a quota. 
    However, there is no risk of an infinite loop if grep is generating 
    no output, i.e., with --silent, --quiet, -q. 
    Similarly, with any of these: 
     --max-count=N (-m) (for N >= 2) 
     --files-with-matches (-l) 
     --files-without-match (-L) 
    there is no risk of trouble. 
    For --max-count=1, grep stops after printing the first match, 
    so there is no risk of malfunction. But even --max-count=2, with 
    input==output, while there is no risk of infloop, there is a race 
    condition that could result in "alternate" output. */ 
    if (!out_quiet && list_files == 0 && 1 < max_count 
     && S_ISREG (out_stat.st_mode) && out_stat.st_ino 
     && SAME_INODE (st, out_stat)) 
    { 
     if (! suppress_errors) 
     error (0, 0, _("input file %s is also the output"), quote (filename)); 
     errseen = true; 
     goto closeout; 
    } 
2

Ecco come scrivere di nuovo a qualche file:

grep stuff file.txt > tmp && mv tmp file.txt 
0

prova pipline con gatto o tac:

cat file | grep 'searchpattern' > newfile 

E 'buone pratiche e l'abbreviazione di realizzazione

Problemi correlati