溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

揭開UNIX高手的那些重大秘密

發(fā)布時間:2020-06-09 21:11:59 來源:網(wǎng)絡(luò) 閱讀:185 作者:glying 欄目:系統(tǒng)運(yùn)維

Pixel, Byte, and Comma的軟件開發(fā)者M(jìn)artin Streicher 在本文中為我們揭示了UNIX高手的秘密。Martin Streicher 是一位 Ruby on Rails 的自由開發(fā)人員和 Linux Magazine 的前任主編。Martin 畢業(yè)于 Purdue University 并獲得計算機(jī)科學(xué)學(xué)位,從 1986 年起他一直從事 UNIX 類系統(tǒng)的編程工作。他喜歡收集藝術(shù)品和玩具。

保存環(huán)境變量

大多數(shù) UNIX 用戶在 .bashrc(針對 Bash shell)和 .zshrc(針對 Z shell)等 shell 啟動文件中塞滿大量用戶設(shè)置,以便一次又一次地重建鐘愛的 shell 環(huán)境。啟動文件能夠創(chuàng)建別名、設(shè)置 shell 選項(xiàng)、創(chuàng)建函數(shù)、以及設(shè)置環(huán)境變量。關(guān)鍵的環(huán)境變量包括 HOME(指向您的主目錄)、PATH(列舉從中搜索應(yīng)用程序的目錄)和 MANPATH(列舉從中搜索手冊頁的目錄)。要查看您的 shell 中設(shè)置了哪些環(huán)境變量,鍵入 printenv 命令。查閱 shell 手冊頁,獲取可用環(huán)境變量的完整列表。

與 shell 一樣,可以通過環(huán)境變量定制其他許多 UNIX 應(yīng)用程序。例如,Java 子系統(tǒng)要求定義 JAVA_HOME 來指向 Java 運(yùn)行時的根。同樣,Amazon Web Services (AWS) 實(shí)用程序套件強(qiáng)制使用 AWS_CREDENTIAL_FILE 來指向一個包含有效私匙憑證的文件。單獨(dú)的應(yīng)用程序也提供環(huán)境變量,關(guān)鍵是如何發(fā)現(xiàn)這些變量。幸運(yùn)的是,這種工作不需要非法***;相反,只需查詢手邊的實(shí)用工具手冊頁,查找標(biāo)題為 “Environment Variables” 的章節(jié)即可。

例如,分頁實(shí)用程序 less 定義了幾個有用的環(huán)境變量:

◆環(huán)境變量 LESS 存儲一些命令行選項(xiàng),以在您每次調(diào)用該分頁程序時減少鍵入量。例如,如果您需要閱讀大量日志文件,可將以下語句添加到一個 shell 啟動文件中:

export LESS='--RAW-CONTROL-CHARACTERS --squeeze-lines --ignore-case'



上述選項(xiàng)將分別解譯控制字符(通常是語法著色),將多個空行壓縮為一行,并忽略字符串匹配中的大小寫。如果您使用代碼,可嘗試以下選項(xiàng):

export LESS='--LINE-NUMBERS --quit-if-one-screen --quit-on-intr'

◆名為 LESSKEY 的環(huán)境設(shè)置指向一個密匙綁定文件??梢允褂妹艹捉壎▉矶ㄖ?less 的行為,比如,匹配另一個頁面或編輯器的行為。

◆與 shell 一樣,less 能保留多個調(diào)用之間的歷史。設(shè)置 LESSHISTFILE 和 LESSHISTSIZE 分別指向一個持久命令文件和設(shè)置要記錄的命令的最大條數(shù)。

GNU Compiler Collection (GCC) 是另一個典型的環(huán)境變量應(yīng)用示例。GCC 定義各種環(huán)境變量來定制其操作。LIBRARY_PATH,顧名思義,是一個目錄列表,用于搜索要鏈接到的庫;COMPILER_PATH 的工作方式與 shell 的 PATH 非常相似,但是由 GCC 在內(nèi)部使用,用于查找編譯過程中使用的子程序。

如果您針對單個平臺寫代碼并構(gòu)建二進(jìn)制文件,您可能永遠(yuǎn)也不會用到這些環(huán)境變量,但是,如果您跨平臺交叉編譯相同的代碼,那么這些變量對于訪問每個平臺的不同的頭部和庫至關(guān)重要。您可以將這些變量設(shè)置為不同的值集合,一個集合針對一種機(jī)器,而另一個集合針對另一種風(fēng)格的系統(tǒng)。

事實(shí)上,您可以從 GCC 獲得一個暗示:可以為每個應(yīng)用程序維護(hù)多個環(huán)境變量集合,根據(jù)手邊的工作從一個集合切換到另一個集合。一種方法是在每個項(xiàng)目目錄中保存一個環(huán)境初始化文件并根據(jù)需要source 它。例如,許多 Ruby 開發(fā)人員使用這種方法來在不同的 Ruby 版本間切換,根據(jù)需要更改環(huán)境變量 PATH、GEM_HOME 和 GEM_PATH,從一個版本跳到另一個版本。

“點(diǎn)綴” 環(huán)境

與環(huán)境變量非常相似的是,許多 Linux和 UNIX 應(yīng)用程序都提供一個點(diǎn) 文件 — 文件名以圓點(diǎn)開始的小文件 — 來進(jìn)行定制。與環(huán)境變量不同的是:環(huán)境變量采集少量標(biāo)記和相對較少的信息量,而點(diǎn)文件可能更廣泛、更復(fù)雜,擁有自己獨(dú)特的語法規(guī)則、甚至自己的編程語言。點(diǎn)文件是保存選項(xiàng)和設(shè)置的理想位置,因?yàn)椋ǜ鶕?jù) UNIX 傳統(tǒng))以一個圓點(diǎn)開始的文件名不會出現(xiàn)在標(biāo)準(zhǔn)的目錄清單中。(使用 ls -a 來查看這些所謂的隱藏文件。)點(diǎn)文件是純文本文件,只是文件名比較特別而已。

點(diǎn)文件通常位于您的主目錄內(nèi),但有些實(shí)用程序也在當(dāng)前工作目錄中查找點(diǎn)文件。如果一個應(yīng)用程序支持多個點(diǎn)文件,則該程序通常應(yīng)用于優(yōu)先規(guī)則,來表明一個文件比另一個文件優(yōu)先。通常,“本地” 點(diǎn)文件 — 位于當(dāng)前工作目錄 — 優(yōu)先級最高,然后是主目錄中的點(diǎn)文件,最后是一個系統(tǒng)范圍配置文件。這些文件可以全部存在,也可以存在一個,或者都不存在,這取決于應(yīng)用程序?qū)⑦@些文件視為互斥的還是遞增的。在第一種情況下,優(yōu)先鏈中第一個點(diǎn)文件的優(yōu)先權(quán)是不容置疑的。在后一種情況下,配置可以級聯(lián)或融解到最終結(jié)果中。

less 的密匙綁定文件是一個簡單點(diǎn)文件示例,位于 $HOME/.lesskey 中。文件中的每一行都是一對(一個按鍵和一條命令),如下所示:



\r        forw-line
\n        forw-line
e         forw-line
j         forw-line
^E        forw-line
^N        forw-line
k         back-line
y         back-line
^Y        back-line



fetchmail 是比較復(fù)雜的點(diǎn)文件示例。這個實(shí)用程序在本地從多個遠(yuǎn)程源提取電子郵件并傳送消息。這個實(shí)用程序的操作只通過 $HOME/.fetchmailrc 控制。(參見手冊頁了解它的眾多選項(xiàng)。)cron、git、vi,以及其他許多命令都能識別點(diǎn)文件。同樣,請閱讀這個應(yīng)用程序的手冊頁,了解可以在點(diǎn)文件中配置的內(nèi)容。有些點(diǎn)文件內(nèi)容豐富,足以占用一個單獨(dú)的手冊頁,比如 crontab。

噓……關(guān)于 SSH 的秘密

Secure Shell (SSH) 是一個功能強(qiáng)大的子系統(tǒng),用于安全地登錄到遠(yuǎn)程系統(tǒng)、復(fù)制文件并穿越防火墻。由于 SSH 是一個子系統(tǒng),它提供大量選項(xiàng)來定制和簡化其操作。事實(shí)上,SSH 提供名為 $HOME/.ssh 的整個 “點(diǎn)目錄” 來包含其所有數(shù)據(jù)。(您的 .ssh 目錄必須是模式 600,以阻止他人訪問。非 600 模式將干擾正常的操作。)特別是,文件 $HOME/.ssh/config 可以定義大量快捷方式,包括機(jī)器名稱的別名、每主機(jī)訪問控制等。

下面是位于 $HOME/.ssh/config 中的一個典型代碼塊,用于定制一個特定主機(jī)的 SSH:



Host worker
HostName worker.example.com
IdentityFile ~/.ssh/id_rsa_worker
User joeuser



~/.ssh/config 中的每個塊配置一個或多個主機(jī)。不同的塊使用一個空行分隔。這個塊使用 4 個選項(xiàng):Host、HostName、IdentityFile 和 User。Host 為 HostName 指定的機(jī)器創(chuàng)建一個昵稱。昵稱允許您鍵入 ssh worker,而不是 ssh worker.example.com。另外,IdentityFile 和 User 選項(xiàng)指定如何登錄到 worker。前者指向此主機(jī)使用的一個私匙,后者提供登錄 ID。這樣,這個代碼塊就等同于以下命令:



ssh -i ~/.ssh/id_rsa_worker



ControlMaster 是一個鮮為人知的強(qiáng)大選項(xiàng)。如果設(shè)置,同一個主機(jī)的多個 SSH 會話將共享單個連接。一旦第一個連接建立,后續(xù)連接就不再需要憑證,從而消除了每次連接同一機(jī)器都需要鍵入密碼的麻煩。ControlMaster 非常方便,您可能愿意為每臺機(jī)器啟用它。啟用方法非常簡單,只需使用主機(jī)通配符 *:



Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p



如您所料,標(biāo)記了 Host * 的塊將應(yīng)用到每個主機(jī),甚至是那些在配置文件中沒有明確指定的主機(jī)。ControlMaster auto 嘗試使用一個現(xiàn)有連接,并在沒有發(fā)現(xiàn)共享連接時創(chuàng)建一個新連接。ControlPath 指向一個文件,以便持久化一個控制套接字以供共享。%r 用遠(yuǎn)程登錄用戶名替換,%h 用目標(biāo)主機(jī)名替換,%p 代替連接使用的端口。(您還可以使用 %l,它使用本地主機(jī)名替換。)上述規(guī)范使用類似于下面的文件名創(chuàng)建控制套接字:



:22



當(dāng)?shù)竭h(yuǎn)程主機(jī)的所有連接都被切斷時,每個控制套接字都就會被移除。如果您想隨時了解連接到了哪些主機(jī),只需鍵入 ls ~/.ssh 并查看控制套接字的主機(jī)名部分(%h)。

SSH 配置文件非常大,它也有自己的手冊頁。鍵入 man ssh_config 查看所有可能的選項(xiàng)。這里有一個巧妙的 SSH 技巧:可以通過 SSH 從本地系統(tǒng)進(jìn)入遠(yuǎn)程系統(tǒng)。要用到的命令行如下所示:



$ ssh example.com -L 5000:localhost:3306



這條命令的意思是:通過 example.com 進(jìn)行連接,并在本地機(jī)器上的端口 5000 和名為 “localhost” 的機(jī)器上的端口 3306(MySQL 服務(wù)器端口)之間建立一條通道。由于 localhost 在 example.com 上解釋(因?yàn)橥ǖ酪呀ⅲ?,因?localhost 就是 example.com。由于出站通道 — 以前稱為本地轉(zhuǎn)發(fā)(local forward)— 已建立,本地客戶端能夠連接到端口 5000,并與 example.com 上運(yùn)行的 MySQL 服務(wù)器通信。

通道創(chuàng)建的常規(guī)形式如下:



$ ssh proxyhost
localport:targethost:targetport



其中,proxyhost 是可以通過 SSH 訪問的機(jī)器,并且擁有一個到 targethost 的網(wǎng)絡(luò)連接(不通過 SSH)。localport 是您的本地系統(tǒng)上的一個非特權(quán)端口(1024 以上的任一未用端口),targetport 是您要連接到的服務(wù)的端口。

前面的命令從您的機(jī)器發(fā)送出去,到達(dá)外部世界。 也可以使用 SSH 發(fā)送進(jìn)來,或者從外部世界連接到您的本地系統(tǒng)。入站通道的常規(guī)形式如下:



$ ssh user@proxyhost -R proxyport:targethosttargetport



建立一條入站通道 — 以前稱為遠(yuǎn)程轉(zhuǎn)發(fā) — 時,proxyhost 和 targethost 的角色將被反轉(zhuǎn):目標(biāo)是您的本地機(jī)器,代理是遠(yuǎn)程機(jī)器。user 是您在代理上的登錄名。以下命令提供了一個具體示例:



$ ssh -R 8080:localhost:80



這條命令的意思是:用戶 Joe 連接到 example.com,并將遠(yuǎn)程端口連接到本地端口 80。這條命令向 example.com 上的用戶提供一個通道,以連接到 Joe 的機(jī)器上。遠(yuǎn)程用戶能夠連接到 8080,以便連接 Joe 機(jī)器上的 Web 服務(wù)器。

除了分別用于本地和遠(yuǎn)程轉(zhuǎn)發(fā)的 -L 和 -R 之外,SSH 還提供 -D 參數(shù)來在遠(yuǎn)程機(jī)器上創(chuàng)建一個 HTTP 代理。請參見 SSH 手冊頁了解正確語法。

使用歷史記錄重寫

如果您經(jīng)常在 shell 提示符中花費(fèi)大量時間,保存 shell 歷史記錄可以節(jié)約時間和輸入。但是如果歷史記錄不能被修改,就會導(dǎo)致一些麻煩:記錄重復(fù)的命令,且多個 shell 實(shí)例可能會干擾各自的歷史記錄。這兩個問題很容易解決,只需在您的 .bashrc 中添加兩行:



export HISTCONTROL=ignoreboth
shopt -s histappend



第一行將移除您的 shell 歷史記錄中連續(xù)的重復(fù)命令。如果您想移除所有零散的副本,可將ignoreboth 更改為 erasedups。第二行在 shell 退出時將 shell 的歷史記錄附加到您的記錄文件。默認(rèn)情況下,Bash 記錄文件命名為 ~/~/.bash_history (不錯,這是一個點(diǎn)文件)??梢酝ㄟ^設(shè)置 HISTFILE(不錯,這是一個環(huán)境變量)來更改它的位置。如果您想將一個 shell 的最近 10,000 命令保存在一個包含 100,000 條目的記錄文件中,將 export HISTSIZE=10000 HISTFILESIZE=100000 添加到您的 shell 啟動文件中。要查看一個 shell 的歷史記錄,在任意提示處鍵入 history 即可。

如果不能調(diào)用,那么保存的命令歷史記錄就用處不大。而這正是 shell !(或 bang)操作符的作用所在:

    * !! (“bang bang”) 完整地重復(fù)最后一條命令。
    * !:0 是前一條命令的名稱。
    * !^ 是前一條命令的第一個參數(shù)。!:2、!:3 … !$ 等命令是前一條命令的第二、第三……以及最后一個參數(shù)。
    * !* 是最后一條命令的所有參數(shù),命令名除外。
    * !n 重復(fù)歷史中編號為 n 的命令。
    * !handle 重復(fù)以 handle 中的字符開始的最后一條命令。例如,!ca 將重復(fù)以字符 ca 開始的最后一條命令,如 cat README。
    * !?handle 重復(fù)包含 handle 中的字符組成的字符串的最后一條命令。例如,!?READ 還會匹配 cat README。
    * ^original^substitution 使用 substitution 替換 original 的第一個 實(shí)例。例如,如果前一條命令是 cat README,,命令 ^README^license.txt 將生成一條新命令 cat license.txt。
    * !:gs/original/substitution 將使用 substitution 替換 original 的所有 實(shí)例(!:gs 表示 “全局替換[global substitution]”)。
    * !-2 是倒數(shù)第二條命令,!-3 是倒數(shù)第三條命令,以此類推。

您甚至可以合并歷史表達(dá)式來生成 !-2:0 -R !^ !-3:2 這樣的 “魔湯”,該命令將擴(kuò)展為倒數(shù)第二條命令的名稱,加上 -R,再加上前一條命令的第一個參數(shù),以及倒數(shù)第三條命令的第二個參數(shù)。要使這樣的神秘命令更具可讀性,可以在鍵入時擴(kuò)展歷史參考。在任意提示符鍵入命令 bind Space:magic-space ,或者將其添加到一個啟動文件,從而將空格鍵綁定到函數(shù) magic-space,該函數(shù)將擴(kuò)展內(nèi)聯(lián)歷史替換。

與擴(kuò)展名無關(guān)的自動解壓

鑒于 Internet 上有如此眾多的代碼,您可能每天都會下載數(shù)十個文件。可能會出現(xiàn)這樣的情況:所有那些文件都使用不同的方式打包 — 有的是 ZIP 文件,有的是 RAR 文件,還有很多是 tarball 文件,盡管每個包都使用不同的實(shí)用程序壓縮。記住如何解壓縮和擴(kuò)展每種包格式將會使人精疲力盡。那么,為何不在單個命令中完成所有那些任務(wù)呢?下面這個函數(shù)在許多樣例點(diǎn)文件中廣泛可用:



ex () {
  if [ -f $1 ] ; then
    case $1 in
      *.tar.bz2)   tar xjf $1        ;;
      *.tar.gz)    tar xzf $1     ;;
      *.bz2)       bunzip2 $1       ;;
      *.rar)       rar x $1     ;;
      *.gz)        gunzip $1     ;;
      *.tar)       tar xf $1        ;;
      *.tbz2)      tar xjf $1      ;;
      *.tgz)       tar xzf $1       ;;
      *.zip)       unzip $1     ;;
      *.Z)         uncompress $1  ;;
      *.7z)        7z x $1    ;;
      *)           echo "'$1' cannot be extracted via extract()" ;;
    esac
  else
    echo "'$1' is not a valid file"
  fi
}



這個函數(shù) ex 擴(kuò)展了 11 種文件格式;如果要處理其他包類型,該函數(shù)還可以擴(kuò)展。一旦定義 — 例如,在一個 shell 啟動文件中 — 就可以簡單地鍵入 ex somefile,其中 somefile 以以下一種已命名擴(kuò)展結(jié)束:



$ ls
source
$ tar czf source.tgz source
$ ls -1
source
source.tgz
$ rm -rf source
$ ex source.tgz
$ ls -1
source
source.tgz



順便說一下,如果您將今天下載的文件放錯了位置,可以運(yùn)行 find 來查找它:



$ find ~ -type f -mtime 0



命令 -type f 查找純文本文件,-mtime 0 查找自當(dāng)天午夜以來創(chuàng)建的文件。

更多秘密

需要揭開的專家秘密還有很多。在 Web 上搜索 “shell auto-complete”,進(jìn)一步了解自動完成特性,該特性用于在您鍵入一條命令時提供上下文敏感的擴(kuò)展。另外,搜索 “shell prompts” 以了解如何定制您的 shell 提示:可以將其設(shè)置為彩色,可以設(shè)置您的當(dāng)前工作目錄或 Git 分支,還可以顯示歷史數(shù)目 — 如果經(jīng)常調(diào)用歷史,這是一個方便的參考信息。要查看工作示例,可在 Github 中搜索 “dot files”。許多專家都將他們的 shell 配置張貼在 Github 上。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI