前言:
我個人很喜歡使用 Linux 系統,雖然說 Windows 的圖形化界面做的確實比 Linux 好,但是對腳本的支持太差了,一開始有點不習慣命令列操作,但是熟悉了之后反而發現移動滑鼠點點點才是浪費時間的罪魁禍首,,,
那么對于 Linux 命令列,本文不是介紹某些命令的用法,而是說明一些簡單卻特別容易讓人迷惑的細節問題,
A、標準輸入和命令引數的區別,
B、在后臺運行命令在退出終端后也全部退出了,
C、單引號和雙引號表示字串的區別,
D、有的命令和sudo一起用就 command not found,
一、標準輸入和引數的區別
這個問題一定是最容易讓人迷惑的,具體來說,就是搞不清什么時候用管道符|和檔案重定向>,<,什么時候用變數$,
比如說,我現在有個自動連接寬帶的 shell 腳本connect.sh,存在我的家目錄:

如果我想洗掉這個腳本,而且想少敲幾次鍵盤,應該怎么操作呢?我曾經這樣嘗試過:
實際上,這樣操作是錯誤的,正確的做法應該是這樣的:
前者試圖將where的結果連接到rm的標準輸入,后者試圖將結果作為命令列引數傳入,
標準輸入就是編程語言中諸如scanf或者readline這種命令;而引數是指程式的main函式傳入的args字符陣列,
前文「Linux檔案描述符」說過,管道符和重定向符是將資料作為程式的標準輸入,而$(cmd)是讀取cmd命令輸出的資料作為引數,
用剛才的例子說,rm命令源代碼中肯定不接受標準輸入,而是接收命令列引數,洗掉相應的檔案,作為對比,cat命令是既接受標準輸入,又接受命令列引數:
如果命令能夠讓終端阻塞,說明該命令接收標準輸入,反之就是不接受,比如你只運行cat命令不加任何引數,終端就會阻塞,等待你輸入字串并回顯相同的字串,
二、后臺運行程式
比如說你遠程登錄到服務器上,運行一個 Django web 程式:
現在你可以通過服務器的 IP 地址測驗 Django 服務,但是終端此時就阻塞了,你輸入什么都不回應,除非輸入 Ctrl-C 或者 Ctrl-/ 終止 python 行程,
可以在命令之后加一個&符號,這樣命令列不會阻塞,可以回應你后續輸入的命令,但是如果你退出服務器的登錄,就不能訪問該網頁了,
如果你想在退出服務器之后仍然能夠訪問 web 服務,應該這樣寫命令 (cmd &):
底層原理是這樣的:
每一個命令列終端都是一個 shell 行程,你在這個終端里執行的程式實際上都是這個 shell 行程分出來的子行程,正常情況下,shell 行程會阻塞,等待子行程退出才重新接收你輸入的新的命令,加上&號,只是讓 shell 行程不再阻塞,可以繼續回應你的新命令,但是無論如何,你如果關掉了這個 shell 命令列埠,依附于它的所有子行程都會退出,
而(cmd &)這樣運行命令,則是將cmd命令掛到一個systemd系統守護行程名下,認systemd做爸爸,這樣當你退出當前終端時,對于剛才的cmd命令就完全沒有影響了,
類似的,還有一種后臺運行常用的做法是這樣:
nohub命令也是類似的原理,不過通過我的測驗,還是(cmd &)這種形式更加穩定,
三、單引號和雙引號的區別
不同的 shell 行為會有細微區別,但有一點是確定的,對于$,(,)這幾個符號,單引號包圍的字串不會做任何轉義,雙引號包圍的字串會轉義,
shell 的行為可以測驗,使用set -x命令,會開啟 shell 的命令回顯,你可以通過回顯觀察 shell 到底在執行什么命令:
可見 echo ( c m d ) 和 e c h o " (cmd) 和 echo "(cmd)和echo"(cmd)",結果差不多,但是仍然有區別,注意觀察,雙引號轉義完成的結果會自動增加單引號,而前者不會,
也就是說,如果 $ 讀取出的引數字串包含空格,應該用雙引號括起來,否則就會出錯,
四、sudo 找不到命令
有時候我們普通用戶可以用的命令,用 sudo 加權限之后卻報錯 command not found:
原因在于,connect.sh 這個腳本僅存在于該用戶的環境變數中:
當使用 sudo 時,系統會使用 /etc/sudoers 這個檔案中規定的該用戶的權限和環境變數,而這個腳本在 /etc/sudoers 環境變數目錄中當然是找不到的,
解決方法是使用腳本檔案的路徑,而不是僅僅通過腳本名稱:
在這里推薦一個我自己創建的軟體測驗交流群,qq:642830685,群中會比不定期的分享軟體測驗資源,測驗面試題以及測驗行業資訊,大家可以在群中積極交流技術,還有大佬為你答疑解惑,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/251449.html
標籤:其他
下一篇:會大方的花錢,才能漂亮的賺錢。
