新聞中心
Shell是系統(tǒng)的用戶界面,提供了用戶與內(nèi)核進行交互操作的一種接口。它接收用戶輸入的命令并把它送入內(nèi)核去執(zhí)行。是在Linux內(nèi)核與用戶之間的解釋器程序,現(xiàn)在Linux通常指/bin/bash解釋器來負責(zé)向內(nèi)核翻譯以及傳達用戶/程序指令,shell相當(dāng)于操作系統(tǒng)的“外殼”

創(chuàng)新互聯(lián)公司服務(wù)項目包括墨玉網(wǎng)站建設(shè)、墨玉網(wǎng)站制作、墨玉網(wǎng)頁制作以及墨玉網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,墨玉網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到墨玉省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
1、標(biāo)準(zhǔn)輸入和命令參數(shù)的區(qū)別。
2、在后臺運行命令在退出終端后也全部退出了。
3、單引號和雙引號表示字符串的區(qū)別。
4、有的命令和sudo一起用就 command not found。
一、標(biāo)準(zhǔn)輸入和參數(shù)的區(qū)別
這個問題一定是最容易讓人迷惑的,具體來說,就是搞不清什么時候用管道符|和文件重定向>,
比如說,我現(xiàn)在有個自動連接寬帶的 shell 腳本connect.sh,存在我的家目錄:
$ where connect.sh
/home/fdl/bin/connect.sh
如果我想刪除這個腳本,而且想少敲幾次鍵盤,應(yīng)該怎么操作呢?我曾經(jīng)這樣嘗試過:
$ where connect.sh | rm
實際上,這樣操作是錯誤的,正確的做法應(yīng)該是這樣的:
$ rm $(where connect.sh)
前者試圖將where的結(jié)果連接到rm的標(biāo)準(zhǔn)輸入,后者試圖將結(jié)果作為命令行參數(shù)傳入。
標(biāo)準(zhǔn)輸入就是編程語言中諸如scanf或者readline這種命令;而參數(shù)是指程序的main函數(shù)傳入的args字符數(shù)組。
管道符和重定向符是將數(shù)據(jù)作為程序的標(biāo)準(zhǔn)輸入,而$(cmd)是讀取cmd命令輸出的數(shù)據(jù)作為參數(shù),前文畫圖解釋過:
輸入重定向就是說,程序想讀取數(shù)據(jù)的時候就會去 files[0] 讀取,所以我們只要把 files[0] 指向一個文件,那么程序就會從這個文件中讀取數(shù)據(jù),而不是從鍵盤。
同理,輸出重定向就是把files[1]指向一個文件,那么程序的輸出就不會寫入到顯示器,而是寫入到這個文件中。
管道符其實也是異曲同工,把一個進程的輸出流和另一個進程的輸入流接起一條「管道」,數(shù)據(jù)就在其中傳遞:
Linux 進程、線程、文件描述符的底層原理
用剛才的例子說,rm命令源代碼中肯定不接受標(biāo)準(zhǔn)輸入,而是接收命令行參數(shù),刪除相應(yīng)的文件。作為對比,cat命令是既接受標(biāo)準(zhǔn)輸入,又接受命令行參數(shù):
$ cat filename
...file text...
$ cat echo 'hello world' | cat
hello world
如果命令能夠讓終端阻塞,說明該命令接收標(biāo)準(zhǔn)輸入,反之就是不接受,比如你只運行cat命令不加任何參數(shù),終端就會阻塞,等待你輸入字符串并回顯相同的字符串。
二、后臺運行程序
比如說你遠程登錄到服務(wù)器上,運行一個 Django web 程序:
$ python manager.py runserver 0.0.0.0
Listening on 0.0.0.0:8080...
現(xiàn)在你可以通過服務(wù)器的 IP 地址測試 Django 服務(wù),但是終端此時就阻塞了,你輸入什么都不響應(yīng),除非輸入 Ctrl-C 或者 Ctrl-/ 終止 python 進程。
可以在命令之后加一個&符號,這樣命令行不會阻塞,可以響應(yīng)你后續(xù)輸入的命令,但是如果你退出服務(wù)器的登錄,就不能訪問該網(wǎng)頁了。
如果你想在退出服務(wù)器之后仍然能夠訪問 web 服務(wù),應(yīng)該這樣把命令包裹成這樣(cmd &):
$ (python manager.py runserver 0.0.0.0 &)
Listening on 0.0.0.0:8080...
$ logout
底層原理是這樣的:
每一個命令行終端都是一個 shell 進程,你在這個終端里執(zhí)行的程序?qū)嶋H上都是這個 shell 進程分出來的子進程。正常情況下,shell 進程會阻塞,等待子進程退出才重新接收你輸入的新的命令。加上&號,只是讓 shell 進程不再阻塞,可以繼續(xù)響應(yīng)你的新命令。但是無論如何,你如果關(guān)掉了這個 shell 命令行端口,依附于它的所有子進程都會退出。
而(cmd &)這樣運行命令,則是將cmd命令掛到一個systemd系統(tǒng)守護進程名下,認(rèn)systemd做爸爸,這樣當(dāng)你退出當(dāng)前終端時,對于剛才的cmd命令就完全沒有影響了。
類似的,還有一種后臺運行常用的做法是這樣:
$ nohup some_cmd &
nohup命令也是類似的原理,不過通過我的測試,還是(cmd &)這種形式更加穩(wěn)定。
三、單引號和雙引號的區(qū)別
不同的 shell 行為會有細微區(qū)別,但有一點是確定的,對于$,(,)這幾個符號,單引號包圍的字符串不會做任何轉(zhuǎn)義,雙引號包圍的字符串會轉(zhuǎn)義。
shell 的行為可以測試,使用set -x命令,會開啟 shell 的命令回顯,你可以通過回顯觀察 shell 到底在執(zhí)行什么命令:
可見 echo 和(cmd)”,結(jié)果差不多,但是仍然有區(qū)別。注意觀察,雙引號轉(zhuǎn)義完成的結(jié)果會自動增加單引號,而前者不會。
也就是說,如果 $ 讀取出的參數(shù)字符串包含空格,應(yīng)該用雙引號括起來,否則就會出錯。
四、sudo 找不到命令
有時候我們普通用戶可以用的命令,用sudo加權(quán)限之后卻報錯 command not found:
$ connect.sh
network-manager: Permission denied
$ sudo connect.sh
sudo: command not found
原因在于,connect.sh這個腳本僅存在于該用戶的環(huán)境變量中:
$ where connect.sh
/home/fdl/bin/connect.sh
當(dāng)使用sudo時,系統(tǒng)認(rèn)為是 root 用戶在執(zhí)行命令,所以會去搜索 root 用戶的環(huán)境變量,而這個腳本在 root 的環(huán)境變量目錄中當(dāng)然是找不到的。
解決方法是使用腳本文件的路徑,而不是僅僅通過腳本名稱:
$ sudo /home/fdl/bin/connect.sh
以上就是全部內(nèi)容,對于出現(xiàn)的一些難以理解的現(xiàn)象,要多思考和嘗試,熟練之后,shell 命令行真的可以帶來很大的便利。
網(wǎng)站標(biāo)題:學(xué)習(xí)Linuxshell必須要知道的知識點
鏈接地址:http://m.5511xx.com/article/coeeode.html


咨詢
建站咨詢
