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

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

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