網(wǎng)站備案真實核驗單制作網(wǎng)頁教程
1. 輸入輸出重定向
在linux工作必須掌握的命令一文中,我們已經(jīng)掌握了幾乎所有基礎(chǔ)常用的Linux命令,那么接下來的任務(wù)就是把多個命令適當?shù)慕M合到一起,使其協(xié)同工作,會更高效的處理數(shù)據(jù),做到這一點就必須搞清楚命令的輸入重定向和輸出重定向的原理。
簡而言之,輸入重定向就是把文件導入到命令中,而輸出重定向則是指把原本輸出到屏幕的數(shù)據(jù)信息寫入到指定文件中。在日常工作中,相較于輸入重定向,輸出重定向的頻率更高,所以又將輸出重定向分為了標準輸出重定向和錯誤輸出重定向兩種不同的技術(shù),以及清空寫入與追加寫入兩種模式。
- 標準輸入重定向(STDIN,文件描述符為0):默認從鍵盤輸入,也可以從其他文件或命令輸入。
- 標準輸出重定向(STDOUT,文件描述符為1):默認輸出到屏幕。
- 錯誤輸出重定向(STDERR,文件描述符為2):默認輸出到屏幕。
比如我們分別查看兩個文件的屬性信息,其中第二個文件時不存在的,雖然針對這兩個文件的操作都分別會在屏幕上輸出一些數(shù)據(jù)信息,但這兩個操作的差異其實很大:
[root@root test]# ls -l test1.txt
-rw-r--r--. 1 root root 8 1月 22 17:10 test1.txt
[root@root test]# ls -l test2.txt
ls: 無法訪問test2.txt: 沒有那個文件或目錄
在上述命令中,名為test1.txt文件是存在的,輸出的是該文件的一些權(quán)限、所有者、所屬組、文件大小以及修改時間等信息,這也是該命令的標準輸出信息,而名為test2.txt文件是不存在的,因此在執(zhí)行l(wèi)s 命令后顯示的報錯提示信息也是該命令的錯誤輸出信息。那么,要想把原本輸出到屏幕上的數(shù)據(jù)轉(zhuǎn)而寫入到文件當中,就要區(qū)別對待這兩種輸出信息。
對于輸入重定向來講,用到的符號及其作用如表:
符號 | 輸入重定向符號作用 |
---|---|
命令 < 文件 | 將文件作為命令的標準輸入 |
命令 << 文件 | 從標準輸入中讀入,直到遇見分解符才停止 |
命令 < 文件1 > 文件2 | 將文件1作為命令的標準輸入并將標準輸出到文件2 |
對于輸出重定向來講,用到的符號以及作用如下表:
符號 | 輸出重定向符號以及作用 |
---|---|
命令 > 文件 | 將標準輸出重定向到一個文件中(清空原有文件的數(shù)據(jù)) |
命令 2> 文件 | 將錯誤輸出重定向到一個文件中(清空原有文件的數(shù)據(jù)) |
命令 >> 文件 | 將標準輸出重定向到一個文件中 (追加到原有內(nèi)容的后面) |
命令 2>> 文件 | 將錯誤輸出重定向到一個文件中 (追加到原有內(nèi)容的后面) |
命令 >> 文件 2 >&1 或 命令 &>> 文件 | 將標準輸出與錯誤輸出共同寫入到文件中(追加到原有內(nèi)容的后面) |
對于重定向中的標準輸出模式,可以省略文件描述符1 不寫,而錯誤輸出模式的文件描述 2是必須要寫的。我們先來小試牛刀。通過標準輸出重定向?qū)an bash 命令原本要輸出到屏幕的信息寫入到readme.txt中,然后顯示readme.txt文件中的內(nèi)容。具體命令如下:
有沒有感覺很方便呢?我們接下來嘗試輸出重定向技術(shù)中的覆蓋寫入與追加寫入這2種不同模式帶來的變化。首先通過覆蓋寫入模式向readme.txt文件寫入一行數(shù)據(jù),然后再通過追加寫入模式向文件再寫入一次數(shù)據(jù),其命令如下:
[root@root test]# echo "welcome to china!" > readme.txt
[root@root test]# echo "china is very beautiful!" >> readme.txt
在執(zhí)行cat命令之后,可以看到如下所示的文件內(nèi)容:
[root@root test]# cat readme.txt
welcome to china!
china is very beautiful!
雖然都是輸出重定向技術(shù),但是不同命令的標準輸出和錯誤輸出還是有區(qū)別的。例如查看當前目錄中某個文件的信息,這里以readme.txt為例,因為這個文件是真實存在的,因此使用標準輸出即可將原本要輸出到屏幕的信息寫入到文件中,而錯誤的輸出重定向則依然把信息輸出到了屏幕上。
如果想把命令的報錯信息輸出寫入到文件,該怎么操作呢?當用戶在執(zhí)行一個自動化的Shell腳本時,這個操作會特別有用,因為它把整個腳本執(zhí)行過程中的報錯信息都記錄到了文件中,便于安裝后的排錯工作,接下來我們以一個不存在的文件進行演示:
[root@root test]# ls -l xxx
ls: 無法訪問xxx: 沒有那個文件或目錄
[root@root test]# ls -l xxx > test4.txt
ls: 無法訪問xxx: 沒有那個文件或目錄
[root@root test]# ls -l xxx 2> test4.txt
[root@root test]# cat test4.txt
ls: 無法訪問xxx: 沒有那個文件或目錄
輸入重定向相對來說有些冷門,在工作中遇到的概率會小一點,輸入重定向的作用是把文件直接導入到命令中,接下來使用輸入重定向把readme.txt文件導入給wc -l命令,統(tǒng)計一下文件中的內(nèi)容行數(shù)。
[root@root test]# wc -l < readme.txt
3109 readme.txt
上述命令實際上等同于cat readme.txt | wc -l 管道符命令的組合
2. 管道命令符
管道命令符的作用可以用一句話來概括“把前一個命令原本要輸出到屏幕的標準正常數(shù)據(jù)當作是最后一個命令的標準輸入”,我們通過匹配關(guān)鍵詞/sbin/nologin找出了所有被限制登錄的用戶。
- 找出被限制登錄用戶的命令時 grep “/sbin/nologin” /etc/passwd;
- 統(tǒng)計文本行數(shù)的命令則是 wc-l
把這兩條命令合并為一條就是
[root@root test]# grep "/sbin/nologin" /etc/passwd | wc -l
33
這個管道符就像一個法寶,我們可以將它套用到其他不同的命令上,比如用翻頁的形式查看 /etc 目錄中文件列表及屬性信息。
[root@root test]# ls -l /etc | more
總用量 1036
-rw-r--r--. 1 root root 16 8月 23 2022 adjtime
-rw-r--r--. 1 root root 1529 4月 1 2020 aliases
-rw-r--r--. 1 root root 12288 8月 23 2022 aliases.db
drwxr-xr-x. 2 root root 236 8月 23 2022 alternatives
-rw-------. 1 root root 541 8月 9 2019 anacrontab
-rw-r--r--. 1 root root 55 8月 8 2019 asound.conf
drwxr-x---. 3 root root 43 8月 23 2022 audisp
drwxr-x---. 3 root root 83 8月 23 2022 audit
drwxr-xr-x. 2 root root 68 1月 9 2023 bash_completion.d
-rw-r--r--. 1 root root 2853 4月 1 2020 bashrc
drwxr-xr-x. 2 root root 6 10月 2 2020 binfmt.d
-rw-r--r--. 1 root root 37 10月 23 2020 centos-release
-rw-r--r--. 1 root root 51 10月 23 2020 centos-release-upstream
drwxr-xr-x. 2 root root 6 10月 13 2020 chkconfig.d
-rw-r--r--. 1 root root 1108 8月 8 2019 chrony.conf
-rw-r-----. 1 root chrony 481 8月 8 2019 chrony.keys
drwxr-xr-x. 2 root root 25 1月 9 2023 containerd
--More--
3. 命令行通配符
大家都有遇到提筆忘記的尷尬,有時候明明 一個文件名稱就在嘴邊但就是想不起來,如果記得一個文件的開頭幾個字母,想遍歷找出所有以這個關(guān)鍵詞開頭的文件,該怎么操作呢?又比如,假設(shè)想要批量批量查看所有硬盤文件的相關(guān)權(quán)限屬性,一種方式是這樣的:
[root@root test]# ls -l /dev/sda
brw-rw----. 1 root disk 8, 0 1月 21 08:42 /dev/sda
[root@root test]# ls -l /dev/sda1
brw-rw----. 1 root disk 8, 1 1月 21 08:42 /dev/sda1
[root@root test]# ls -l /dev/sda2
brw-rw----. 1 root disk 8, 2 1月 21 08:42 /dev/sda2
[root@root test]# ls -l /dev/sda3
brw-rw----. 1 root disk 8, 3 1月 21 08:42 /dev/sda3
[root@root test]# ls -l /dev/sda4
ls: 無法訪問/dev/sda4: 沒有那個文件或目錄
幸虧我的硬盤文件和分區(qū)只有4個,要是有幾百個,估計要花一天時間來忙這個事情了,由此可見,這種方式的效率確實。比如,這些硬盤設(shè)備文件都是以sda開頭并且存放到了/dev目錄中,這樣一來,即使我們不知道硬盤的分區(qū)編號和具體分區(qū)的個數(shù),也可以使用通配符來搞定。顧名思義,通配符就是通用的匹配信息的符號,比如星號(*)代表匹配零個或多個字符,問號(?)代表匹配單個字符,中括號內(nèi)加上數(shù)字[0-9]代表匹配0~9之間的的單個數(shù)字字符,而中括號內(nèi)加上字母[abc] 則是代表匹配a、b、c三個字符中任意一個字符,其實就是編程中正則表達式。
[root@root test]# ls -l /dev/sda*
brw-rw----. 1 root disk 8, 0 1月 21 08:42 /dev/sda
brw-rw----. 1 root disk 8, 1 1月 21 08:42 /dev/sda1
brw-rw----. 1 root disk 8, 2 1月 21 08:42 /dev/sda2
brw-rw----. 1 root disk 8, 3 1月 21 08:42 /dev/sda3
4. 常用轉(zhuǎn)義字符
為了能夠更好的理解用戶的表達,Shell解釋器還提供了特別豐富的轉(zhuǎn)義字符來處理輸入的特殊數(shù)據(jù)。
4個最常用的轉(zhuǎn)義字符如下所示:
反斜杠(\):是反斜杠后面的一個變量變?yōu)閱渭兊淖址?br /> 單引號(‘’):轉(zhuǎn)義其中所有的變量為單純的字符串。
雙引號(“”):保留其中的變量屬性,不進行轉(zhuǎn)義處理。
反引號(``):把其中的命令執(zhí)行后返回結(jié)果。
我們先定義一個名為PRICE的變量并賦值為5,然后輸出以雙引號括起來的字符串與變量信息:
[root@root test]# PRICE=5
[root@root test]# echo "Price is $PRICE"
price is 5
接下來,我們希望能夠輸出“Price is $5
” ,即價格是5美元的字符串內(nèi)容,但碰巧美元符號與變量提取符號合并后的$$
作用是顯示當前程序的進程ID號碼,于是命令執(zhí)行后輸出的內(nèi)容并不是我們所預期的:
[root@root test]# [root@root test]# echo "price is $$PRICE"
price is 7142PRICE
要想讓第一個“$” 乖乖的作為美元符號,那么就需要反斜杠(\)來進行轉(zhuǎn)義,將這個命令提取符轉(zhuǎn)義稱單純的文本,去除其特殊功能。
[root@root test]# [root@root test]# echo "price is \$$PRICE"
price is $5
而如果只需要某個命令的輸出值時,可以像“命令”這樣,將命令用反引號括起來,達到預期效果。例如,將反引號與uname -a命令結(jié)合,然后使用echo命令來查看本機的Linux版本和內(nèi)核信息:
[root@root test]# echo `uname -a`
Linux root 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
5. 重要的環(huán)境變量
變量是計算機系統(tǒng)用于保存可變值的數(shù)據(jù)類型。在Linux系統(tǒng)中,變量名稱一般都是大寫的,這是一種約定俗成的規(guī)范。我們可以直接通過變量名稱來提取到對應(yīng)的變量值。Linux系統(tǒng)中環(huán)境變量是用來定義系統(tǒng)運行環(huán)境的一些參數(shù),比如每個用戶不同的家目錄、郵件存放位置等。
在Linux系統(tǒng)中一切都是文件,Linux命令也不例外,那么在用戶執(zhí)行了一條命令之后,Linux系統(tǒng)中到底發(fā)生了什么事情呢?簡單來說,命令在Linux中的執(zhí)行分為4個步驟。
第一步: 判斷用戶是否以絕對路徑或相對路徑的方式輸入命令(如/bin/ls),如果是的話則直接執(zhí)行。
第二步: Linux系統(tǒng)檢查用戶輸入的命令是否為“別名命令”,即用一個自定義的命令名稱來替換原本的命令名稱??梢杂?alias 命令來創(chuàng)建一個屬于自己的命令別名,格式為 “alias 別名=命令” 。若要取消一個命令別名,則是用unalias命令,格式為:“unalias 別名”。我們之前使用rm 命令刪除文件時,Linux系統(tǒng)都會要求我們再確認是否執(zhí)行刪除操作,其實這就是Linux系統(tǒng)為了防止用戶誤刪文件而特意設(shè)置的rm別名命令。
[root@root test]# alias rm
alias rm='rm -i'
第三步: Bash解釋器判斷用戶輸入的是內(nèi)部命令還是外部命令。內(nèi)部命令時解釋器內(nèi)部的命令,會被直接執(zhí)行;而用戶在絕大部分時間輸入的是外部命令,這些命令交由步驟4處理??梢允褂谩皌ype 命令名稱” 來判斷用戶輸入的命令時內(nèi)部命令還是外部命令。
第四步: 系統(tǒng)在多個路徑中查找用戶輸入的命令文件,而定義這些路徑的變量叫作PATH,可以簡單地把它理解成是“解釋器的小助手”,作用是告訴Bash解釋器待執(zhí)行的命令可能存放的位置,然后Bash解釋器就會乖乖地在這些位置中逐個查找。PATH是由多個路徑值組成的變量,每個路徑值之間用冒號隔開,對這些路徑的增加和刪除操作將影響到Bash解釋器對Linux命令的查找。
[root@root test]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/data/jdk1.8.0_341/bin:/home/data/redis/bin:/home/data/kafka_2.12-3.0.0/bin:/root/bin
Linux系統(tǒng)中最重要的環(huán)境變量
變量名稱 | 作用 |
---|---|
HOME | 用戶的主目錄 |
SHELL | 用戶在使用的Shell解釋器名稱 |
HISTSIZE | 輸出的歷史命令記錄條數(shù) |
HISTFILESIZE | 保存的歷史命令記錄條數(shù) |
郵件保存路徑 | |
LANG | 系統(tǒng)語言、語系名稱 |
RANDOM | 生成一個隨機數(shù)字 |
PSI | Bash解釋器的提示符 |
PATH | 定義解釋器搜索用戶執(zhí)行命令的路徑 |
EDITOR | 用戶默認的文本編輯器 |