管道與重定向、文件查找-Linux每日一練(7)
攏共有 11 篇 Linux 知識點梳理的文章,這次是第 7 篇,梳理完以后 Linux 每日一練就結束更新了,但是還沒有完結,后續(xù)如果有什么比較重要的 Linux 知識會單獨抽出來再講。

上次我們著重講解了進程管理的知識,這一節(jié)提一下管道、重定向、文件查找。
重定向
在解答上次的重定向問題之前,簡單提一下什么是重定向。
Unix 系統(tǒng)中,每個進程都有 STDIN 、 STDOUT 和 STDERR 這 3 種標準 I/O 。所以幾乎所有語言都有相應的標準 I/O 函數(shù),比如 printf 、 println 、 scanf 等命令,專門用來接收用戶的輸入,或者打印輸出到屏幕、或者文件里。

在 SHELL 里面重定向相當?shù)姆奖?,只需要?> 或 >> 符號就可以了。當然我們也可以直接通過命令把 3 種 I/O 區(qū)別開,分別輸出。
題目一:> 和 >> 有什么區(qū)別?
> 是覆蓋寫入,原來的內容全部清空。
$?echo?no?>?test.txt
$?echo?ok?>?test.txt
$?cat?test.txt
ok
>> 是追加寫入,在原來內容末尾追加。
$?echo?no?>>?test.txt
$?cat?test.txt
ok
no
下面是他的定義,了解一下即可,不用記得。
標準輸入文件(stdin):stdin 的文件描述符為 0,Unix 程序默認從 stdin 讀取數(shù)據(jù)。 標準輸出文件(stdout):stdout 的文件描述符為 1,Unix 程序默認向 stdout 輸出數(shù)據(jù)。 標準錯誤文件(stderr):stderr 的文件描述符為 2,Unix 程序會向 stderr 流中寫入錯誤信息。
好了,我們知道輸出/錯誤輸出信息分別用數(shù)字 1 和 2 代表,你肯定見過下面的寫法
java?-jar?app.jar?>log?2>&1?&
這里的, 2>&1代表把錯誤輸出2合并到1中,并重定向到名為log的文件中去。符號 >&是一個整體,不可分開,分開后就不是上述含義了。比如有些人可能會這么想:2是標準錯誤輸入,1是標準輸出,>是重定向符號,那么"將標準錯誤輸出重定向到標準輸出"是不是就應該寫成2>1就行了?是這樣嗎?如果是嘗試過,你就知道2>1的寫法其實是將標準錯誤輸出重定向到名為1的文件里去了
2>&1 符號必須放到 >log 后面,為什么呢?我們不妨把 1 和 2 都理解是一個指針, 然后來看上面的語句就是這樣的:
本來 1----->屏幕 (1 指向屏幕) 執(zhí)行>log 后, 1----->log (1 指向 log) 執(zhí)行 2>&1 后, 2----->1 (2 指向 1,而 1 指向 log, 因此 2 也指向了 log)
題目二:重定向怎么把錯誤輸出和正確輸出分離開?
正確輸出: 1>1>>等價于>>>錯誤輸出: 2>2>>運維過程中幾乎用不到,就不用記了,hhhh
題目三:怎么快速把一個非常大的文本文件清理掉?
用 rm 或者 echo > filename 都會占用很大的內存,而且速度很慢,建議使用下面的方法
cat?/dev/null?>?filename
/dev/null 是一個特殊的設備文件, 在程序員行話,尤其是 Unix 行話中, /dev/null 被稱為位桶(bit bucket)或者黑洞(black hole)。他會把一些寫入丟棄,如果你讀取它,它會提供無限的空字符(NULL, ASCII NUL, 0x00)。
你肯定也用到過,只不過不一定理解是什么含義,例如在定時任務腳本結尾加上 >/dev/null 2>&1 ,讓所有的輸出流(包括錯誤的和正確的)都定向到空設備丟棄。
*?*?*?*?*?/bin/mysqlbak.sh?>/dev/null?2>&1
題目四:使用管道完成,組合 ps 、 grep 、 awk 、 xargs 、 kill 命令為一行命令,干掉名為 apache 的進程
ps?-ef?|grep?apache?|?awk?'{print?$2}'|?xargs?kill?-9
但是這個命令一般執(zhí)行的時候還是有風險的,而且殺進程也比較粗暴,我們都想做溫柔的人,建議發(fā)送信號給程序,在程序里處理信號做一些析構的工作(當然,我知道大家的程序基本上都懶得寫這些)
也推薦用 systemctl 、 supervisor 、容器等守護進程托管你的程序,比較安全可靠。
拓展運維技巧,向文件中寫入多行內容
下面這種形式很特別
命令?<....
EOF????????????//結束
樣例,輸出是 3:
wc?-l?<a
b
c
EOF
如果你把 wc -l 命令換成 cat 就是打印輸入的內容,然后再將它重定向追加到文件里即可完成向文件寫入多行內容。
比如你想寫入多個 hosts 隱射,你就可以用 EOF 的特性,自己測試下看看吧!
cat<>?/etc/hosts
10.1.1.2?k8smaster
10.1.1.3?k8snode1
10.1.1.4?k8snode2
EOF
小結
>重定向并清空,>>重定向追加2>&1合并正確和錯誤輸出流,如果是打印到屏幕上的腳本,必須要加cat /dev/null > filename快速清理文件內容xxx.sh >/dev/null 2>&1丟球所有輸出流(包括錯誤的和正確的)。ps -ef |grep processname | awk '{print $2}'| xargs kill -9殺進程
參考:
https://blog.csdn.net/zhaominpro/article/details/82630528 https://www.cnblogs.com/lishihai/p/7986565.html
下次主題,軟件包管理、計劃任務
其實軟件包管理我已經在三分鐘手操 yum 源和打 rpm 包是如此的迅速(go 語言之美)兩篇文章中有所提及,大家可以下來了解下
題目一:如何使用 yum 安裝 git 的 1.8.3.1-20.el7 版本包?
題目二:如何安裝和卸載 rpm 包?
題目三:如何使用 crontab 創(chuàng)建一個定時任務,每天晚上 3 點 10 分執(zhí)行一次,并忽略輸出?
