中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

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

發布時間:2020-06-09 21:11:59 來源:網絡 閱讀:192 作者:glying 欄目:系統運維

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

保存環境變量

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

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

例如,分頁實用程序 less 定義了幾個有用的環境變量:

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

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



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

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

◆名為 LESSKEY 的環境設置指向一個密匙綁定文件。可以使用密匙綁定來定制 less 的行為,比如,匹配另一個頁面或編輯器的行為。

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

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

如果您針對單個平臺寫代碼并構建二進制文件,您可能永遠也不會用到這些環境變量,但是,如果您跨平臺交叉編譯相同的代碼,那么這些變量對于訪問每個平臺的不同的頭部和庫至關重要。您可以將這些變量設置為不同的值集合,一個集合針對一種機器,而另一個集合針對另一種風格的系統。

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

“點綴” 環境

與環境變量非常相似的是,許多 Linux和 UNIX 應用程序都提供一個點 文件 — 文件名以圓點開始的小文件 — 來進行定制。與環境變量不同的是:環境變量采集少量標記和相對較少的信息量,而點文件可能更廣泛、更復雜,擁有自己獨特的語法規則、甚至自己的編程語言。點文件是保存選項和設置的理想位置,因為(根據 UNIX 傳統)以一個圓點開始的文件名不會出現在標準的目錄清單中。(使用 ls -a 來查看這些所謂的隱藏文件。)點文件是純文本文件,只是文件名比較特別而已。

點文件通常位于您的主目錄內,但有些實用程序也在當前工作目錄中查找點文件。如果一個應用程序支持多個點文件,則該程序通常應用于優先規則,來表明一個文件比另一個文件優先。通常,“本地” 點文件 — 位于當前工作目錄 — 優先級最高,然后是主目錄中的點文件,最后是一個系統范圍配置文件。這些文件可以全部存在,也可以存在一個,或者都不存在,這取決于應用程序將這些文件視為互斥的還是遞增的。在第一種情況下,優先鏈中第一個點文件的優先權是不容置疑的。在后一種情況下,配置可以級聯或融解到最終結果中。

less 的密匙綁定文件是一個簡單點文件示例,位于 $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 是比較復雜的點文件示例。這個實用程序在本地從多個遠程源提取電子郵件并傳送消息。這個實用程序的操作只通過 $HOME/.fetchmailrc 控制。(參見手冊頁了解它的眾多選項。)cron、git、vi,以及其他許多命令都能識別點文件。同樣,請閱讀這個應用程序的手冊頁,了解可以在點文件中配置的內容。有些點文件內容豐富,足以占用一個單獨的手冊頁,比如 crontab。

噓……關于 SSH 的秘密

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

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



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



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



ssh -i ~/.ssh/id_rsa_worker



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



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



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



:22



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

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



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



這條命令的意思是:通過 example.com 進行連接,并在本地機器上的端口 5000 和名為 “localhost” 的機器上的端口 3306(MySQL 服務器端口)之間建立一條通道。由于 localhost 在 example.com 上解釋(因為通道已建立),因此 localhost 就是 example.com。由于出站通道 — 以前稱為本地轉發(local forward)— 已建立,本地客戶端能夠連接到端口 5000,并與 example.com 上運行的 MySQL 服務器通信。

通道創建的常規形式如下:



$ ssh proxyhost
localport:targethost:targetport



其中,proxyhost 是可以通過 SSH 訪問的機器,并且擁有一個到 targethost 的網絡連接(不通過 SSH)。localport 是您的本地系統上的一個非特權端口(1024 以上的任一未用端口),targetport 是您要連接到的服務的端口。

前面的命令從您的機器發送出去,到達外部世界。 也可以使用 SSH 發送進來,或者從外部世界連接到您的本地系統。入站通道的常規形式如下:



$ ssh user@proxyhost -R proxyport:targethosttargetport



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



$ ssh -R 8080:localhost:80



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

除了分別用于本地和遠程轉發的 -L 和 -R 之外,SSH 還提供 -D 參數來在遠程機器上創建一個 HTTP 代理。請參見 SSH 手冊頁了解正確語法。

使用歷史記錄重寫

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



export HISTCONTROL=ignoreboth
shopt -s histappend



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

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

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

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

與擴展名無關的自動解壓

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



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
}



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



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



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



$ find ~ -type f -mtime 0



命令 -type f 查找純文本文件,-mtime 0 查找自當天午夜以來創建的文件。

更多秘密

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西畴县| 阳山县| 九江市| 南投县| 曲麻莱县| 台东市| 昭通市| 阳山县| 丰县| 巩留县| 乐平市| 青田县| 柯坪县| 冕宁县| 收藏| 聂荣县| 鹤岗市| 沾益县| 五大连池市| 阜康市| 华亭县| 临城县| 桐庐县| 颍上县| 安图县| 三门县| 苏尼特右旗| 泰安市| 雷山县| 张家界市| 伽师县| 和平县| 惠水县| 邵武市| 辽宁省| 夏河县| 濮阳县| 临清市| 棋牌| 封丘县| 葵青区|