2015-02-08 414 views

回答

8

按照GNU grep的源代碼,grep檢查輸入和輸出的i節點:

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; 
    } 

out_stat是通過調用fstat針對STDOUT_FILENO填充。

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

感謝您的答覆,我忘了怎麼殼居然事先設置進程的文件描述符和grep的可以查看這些信息。 – iobender 2015-02-08 05:02:12

+0

@iobender,不客氣。 – falsetru 2015-02-08 05:12:59

2

查看源代碼 - 你可以看到,它會檢查這種情況(文件已經開放供grep讀),並將其報告,請參見下面的SAME_INODE檢查:

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

下面是如何寫回一些文件:

​​
0

嘗試pipline與貓或TAC:

cat file | grep 'searchpattern' > newfile 

它的最佳實踐,併爲短期實現