功能:tail命令能夠輸出文件的尾部內容,默認狀況下它顯示文件的最後十行。
顯示每一個指定文件的最後10 行到標準輸出。若指定了多於一個文件,程序會在每段輸出的開始添加相應文件名做爲頭。若是不指定文件或文件爲"-" ,則從標準輸入讀取數據。
它經常使用來動態監視文件的尾部內容的增加狀況,好比用來監視日誌文件的變化。node
語法:tail [選項] [文件]
短選項 | 長選項 | 涵義 |
---|---|---|
-c[+] K | --bytes=[+] K | 輸出最後 K 字節;另外,使用-c +K 從每一個文件的第 K 字節輸出 |
-n[+] K | --lines=[+] K | 輸出最後 K 行,代替最後10 行;使用-n +K 從每一個文件的第 K 字節輸出 |
-f | --follow=descriptor --follow=name |
descriptor是 --follow 默認值,因此 -f 等價 --follow 等價--follow=descriptor 即時輸出文件變化後追加的數據。 tail -f file 動態跟蹤文件file的增加狀況,tail會每隔一秒去檢查一下文件是否增長新的內容。若是增長就追加在原來的輸出後面顯示。但這種狀況,必須保證在執行tail命令時,文件已經存在。若是想終止 tail -f 輸出,按 Ctrl+C 中斷tail程序。若是按Ctrl+C不能中斷輸出,那麼能夠在別的終端上執行 killall tail 強行終止。 |
--pid=PID | 同 -f 使用,當 PID 所對應的進程死去後,終止。 | |
---retry | 即便目標文件不可訪問依然試圖打開;在與參數-f 或 --follow=name 同時使用時經常有用。 | |
-F | --follow=name --retry | 與 -f 相同,也是動態跟蹤文件的變化,不一樣的是執行此命令時文件能夠不存在。 |
--max-unchanged-stats=N | N 默認爲5,使用--follow=name,從新打開一個在 N 次迭代後沒有改變大小的文件來看它是否被解除鏈接或重命名(這是循環日誌文件的一般狀況)。 因爲有inotify,這個選項不多使用。 |
|
-s S | --sleep-interval=S | 與 -f 合用,表示在每次反覆的間隔休眠 S 秒 對於 --pid=PID ,每隔 S 秒檢查進程。 |
-q | --quiet 或 --silent | 不輸出文件名 |
-v | --verbose | 老是輸出給出文件名的首部 |
測試的文件內容以下[quietheart@lv-k tail_test]$ 1 04_libraryTest 2 a.out 3 a.out.symbol 4 autotools 5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 顯示文件的最後10行 [quietheart@lv-k tail_test]$顯示文件tail_test的最後10行7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 顯示文件的最後N行 [quietheart@lv-k tail_test]$顯示文件tail_test的最後5行12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 從第5行開始顯示文件 [quietheart@lv-k tail_test]$注意指定的數字前面 + 表明從這個數字相應的位置開始,顯示後面的內容5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test 顯示文件最後38個字節的內容 [quietheart@lv-k tail_test]$ ynctest 15 tail_ 16 tail_test 顯示文件第38個字節開始以後的內容 [quietheart@lv-k tail_test]$ 3 a.out.symbol 4 autotools 5 core.31058 6 cpp_test 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test注意指定的數字前面 + 表明從這個數字相應的位置開始,顯示後面的內容。cat tail_testtail tail_testtail -n 5 tail_testtail -n +5 tail_testtail -c 38 tail_testtail -c +38 tail_test
默認是以文件描述符方式,跟蹤文件的增加 [quietheart@lv-k tail_test]$此時等價於命令7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test這裏,輸入以後,顯示默認的文件的後10行,可是tail並無所以而結束,而是一直在運行着,保持這那個文件對應的索引節點的打開狀態。 接下來 若是使用 ,向文件追加新內容。那麼會看到tail又繼續將追加的內容打印出來。 若是使用 ,清空原內容並從新寫入新內容。那麼tail會輸出相似"tail: tail_test: file truncated"的字樣來告訴文件內容被truncated了。tail -f tail_test--follow=descriptor tail_testecho new >>tail_testecho new > tail_test
這個命令用於:跟蹤動態增加的文件。例如系統日誌。在默認狀況下,根據它本身的文件描述符號來跟蹤文件。
可是,有的程序追加文件內容的時候會將文件刪除而後新創建一個。例若有些日誌程序會在必定的時候將追加的日誌文件重命名,而後再創建一個以前同名的新日誌文件追加新的內容,這樣的話這個命令就很差用了。再例若有些編輯器例如vim進行修改文件的時候,沒法跟蹤其變化。經過"ls -il"對vim編輯以前的文件和以後的文件的inode號對比發現,二者不一樣,應當是編輯的時候先刪除文件的索引節點再新創建一個,新建的節點內容才包含了最新的內容,而以前tail打開的那個索引節點已經被刪除了,看不見了,因此固然不會發生變化。
若是想要肯定那麼就先用"ps -aux |grep tail"找到tail的進程號,進入/proc目錄的tail進程號目錄中,查看其fd文件中的某個描述符號,例如"cat 3"這樣會發現原來的內容。 mysql
以文件名方式,跟蹤文件增加 [quietheart@lv-k tail_test]$ 7 download_blog 8 gpg_test 9 hello-1.0.tar.gz 10 hello-2.0 11 hello-2.0.tgz 12 main.cpp 13 mysql20110512.sql 14 rsynctest 15 tail_ 16 tail_test這樣,tail根據文件名稱跟蹤文件的變化,默認來講tail就根據它本身的文件描述符號來跟蹤文件,就像前面所說的,有的程序追加文件內容的時候會將文件刪除而後新創建一個,例若有些日誌程序會在必定的時候將追加的日誌文件重命名,而後再創建一個以前同名的新日誌文件追加新的內容,那麼默認的方式就沒法跟蹤到文件的變化了,由於文件描述符號是表明一個索引節點的,而新追加的內容可能追加到新的索引節點上面了,這個時候就使用這個 --follow=name 選項。這樣,若是當文件新追加內容是追加到同一名稱的不一樣索引節點的狀況發生時,那麼tail那裏就會提示 "tail: 「tail_test」 has been replaced; following end of new file"以後,再從新顯示追加以後的新的最後10行。tail --follow=name tail_test
tail -f 和tail -F 的區別
-f 參數,若是在追蹤此文檔時,此文檔被刪除、轉移或者重建了, 那就中止不會再輸出了。
-F 參數,若是在追蹤此文檔時,此文檔被刪除、轉移或者重建了, 那會再從新try那個同名的那個文檔, 若是重建了, 會繼續追蹤此文檔。web
-f 是--follow[=HOW]的縮寫。"[=HOW]"有兩個寫法,一個"=descriptor",另外一個是"=name"。[=HOW]省略時,默認使用的是"--follow=descriptor"。-f 等價 -follow 等價--follow=descriptor。第一個窗口[root@cftest2 ~]# helll test2第二個窗口[root@cftest2 ~]# rm: remove regular file `messages.3'? y [root@cftest2 ~]# echo "helll test3">>messages.3可是第一個窗口的tail -f 命令不會出現 hello test3tail -f messages.3rm messages.3
descriptor 雖然是默認的參數,可是不必定是最有用的。好比在tail 一個log文件的時候,這個文件極可能是按照日期或者大小滾動,文件滾動以後這個tail -f 命令,就失效了。
若是你跟蹤的文件被被刪除、轉移或者重建, 你還想繼續tail它, 你可使用這個 tail --follow=name 或者 tail -F sql
-F 是 -follow=name --retry 的縮寫。--follow=name 是按照文件名跟蹤文件,能夠按期去從新打開文件檢查文件是否被其它程序刪除並從新創建。 --retry 這個參數,保證文件從新創建後,能夠繼續被跟蹤。第一個窗口[root@cftest2 ~]# helll test1 tail: `messages.3' has become inaccessible: No such file or directory tail: `messages.3' has appeared; following end of new file helll test2第二個窗口[root@cftest2 ~]# rm: remove regular file `messages.3'? y [root@cftest2 ~]# echo "helll test3">>messages.3第一個窗口能夠看到,中間刪除了messages.3,但從新建立後並輸入helll test2,會繼續顯示出來。tail -F messages.3rm messages.3
tail -F功能的強大,它等同於--follow=name --retry。若是你跟蹤的文件被移動或者更名後, 你還想繼續tail它, 你可使用這個選項。
tail手冊頁中關於--retry的說明:keep trying to open a file even if it is inaccessible when tail starts or if it becomes inaccessible later; useful when following by name, i.e., with --follow=name。 tail命令開始執行時文件不存在或者執行過程當中文件不能訪問,會不斷重試。
關於--follow的說明:-f, --follow[={name|descriptor}] output appended data as the file grows; -f, --follow, and --follow=descriptor are equivalent 。--follow=descriptor代表跟蹤的是文件描述符,--follow=name代表跟蹤的是文件名稱。
若是文件名稱改掉以後,還想繼續跟蹤原文件名稱對應的尾部內容,就得使用 -F 選項而不是 -f 選項了。vim
[root@web imx_server]# 14:13:28.892 INFO ImxConnection[6] imx.server.ImxConnection - RX IMX_ACTIVE_TEST{seq=3460,client_id=1291343201649042,presence_status=1(presence_status_online),} 14:13:28.892 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006417 (01/02/00) - Connection #9 served 14:13:28.892 INFO ImxConnection[6] imx.dbo.ImxOnlineInfoRow - EXEC SQL UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:28.0' WHERE account = 'zhy' 14:13:28.894 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:28.0' WHERE account = 'zhy'; (1 milliseconds) 14:13:28.894 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006417 (00/02/00) - Connection #9 returned (now AVAILABLE) 14:13:29.625 INFO ImxConnection[6] imx.server.ImxConnection - RX IMX_ACTIVE_TEST{seq=3461,client_id=1291343201649042,presence_status=1(presence_status_online),} 14:13:29.626 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006418 (01/02/00) - Connection #8 served 14:13:29.626 INFO ImxConnection[6] imx.dbo.ImxOnlineInfoRow - EXEC SQL UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:29.0' WHERE account = 'zhy' 14:13:29.627 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - UPDATE imx_online_info SET last_active_time = '2010-12-03 14:13:29.0' WHERE account = 'zhy'; (0 milliseconds) 14:13:29.653 DEBUG ImxConnection[6] org.logicalcobwebs.proxool.ImxDB - 006418 (00/02/00) - Connection #8 returned (now AVAILABLE) [root@web imx_server]# 總結一下:要想跟蹤會改名的日誌的話,用tail -F 而不是tail -f tail -F log/IMX.LOGCtrl+C