1. 標準輸入重定向(STDIN,文件描述符為0):預設從鍵盤輸入,也可以從其他文件或命令中輸入 2. 標準輸出重定向(STDOUT,文件描述符為1):預設輸出到屏幕 3. 錯誤輸出重定向(STDERR,文件描述符為2):預設輸出到屏幕 範例:比如我們分別查看兩個文件的屬性信息,其中第二個文件是不存 ...
1. 標準輸入重定向(STDIN,文件描述符為0):預設從鍵盤輸入,也可以從其他文件或命令中輸入
2. 標準輸出重定向(STDOUT,文件描述符為1):預設輸出到屏幕
3. 錯誤輸出重定向(STDERR,文件描述符為2):預設輸出到屏幕
範例:比如我們分別查看兩個文件的屬性信息,其中第二個文件是不存在的,雖然針對這兩個文件的操作都分別會在屏幕上輸出一些數據信息,但這兩個操作的差異其實很大:
[root@linuxprobe ~]# touch linuxprobe [root@linuxprobe ~]# ls -l linuxprobe total 0 drwxr-xr-x. 3 root root 14 Aug 12 23:13 a [root@linuxprobe ~]# ls -l xxxxxx ls: cannot access xxxxxx: No such file or directory |
輸入重定向中用到的符號及其作用
符號 |
作用 |
命令 < 文件 |
將文件作為命令的標準輸入 |
命令 << 分界符 |
從標準輸入中讀入,直到遇見分界符才停止 |
命令 < 文件1 > 文件2 |
將文件1作為命令的標準輸入並將標準輸出到文件2 |
輸出重定向中用到的符號及其作用
符號 |
作用 |
命令 > 文件 |
將標準輸出重定向到一個文件中(清空原有文件的數據) |
命令 2> 文件 |
將錯誤輸出重定向到一個文件中(清空原有文件的數據) |
命令 >> 文件 |
將標準輸出重定向到一個文件中(追加到原有內容的後面) |
命令 2>> 文件 |
將錯誤輸出重定向到一個文件中(追加到原有內容的後面) |
命令 >> 文件 2>&1 或 命令 &>> 文件 |
將標準輸出與錯誤輸出共同寫入到文件中(追加到原有內容的後面) |
對於重定向中的標準輸出模式,可以省略文件描述符1不寫,而錯誤輸出模式的文件描述符2是必須要寫的。
[root@linuxprobe ~]# man bash > readme.txt [root@linuxprobe ~]# cat readme.txt BASH(1) General Commands Manual BASH(1) NAME bash - GNU Bourne-Again Shell
SYNOPSIS bash [options] [file]
COPYRIGHT Bash is Copyright (C) 1989-2011 by the Free Software Foundation, Inc.
DESCRIPTION Bash is an sh-compatible command language interpreter that executes commands read from the standard input or from a file. Bash also incor‐ porates useful features from the Korn and C shells (ksh and csh).
Bash is intended to be a conformant implementation of the Shell and Utilities portion of the IEEE POSIX specification (IEEE Standard 1003.1). Bash can be configured to be POSIX-conformant by default.
………………省略部分輸出信息……………… |
嘗試輸出重定向技術中的覆蓋寫入與追加寫入這兩種不同模式帶來的變化
範例:首先通過覆蓋寫入模式向readme.txt文件寫入一行數據(該文件中包含上一個實驗的man命令信息),然後再通過追加寫入模式向文件再寫入一次數據
[root@linuxprobe ~]# echo "Welcome to LinuxProbe.Com" > readme.txt [root@linuxprobe ~]# echo "Quality linux learning materials" >> readme.txt [root@linuxprobe ~]# cat readme.txt Welcome to LinuxProbe.Com Quality linux learning materials |
範例:標準輸出和錯誤輸出的區別
[root@linuxprobe ~]# ls -l linuxprobe total 0 drwxr-xr-x. 3 root root 14 Aug 14 00:42 a [root@linuxprobe ~]# ls -l linuxprobe > /root/stderr.txt [root@linuxprobe ~]# ls -l linuxprobe 2> /root/stderr.txt total 0 drwxr-xr-x. 3 root root 14 Aug 14 00:42 a |
範例:把命令的報錯信息寫入到文件
[root@linuxprobe ~]# ls -l xxxxxx ls: cannot access xxxxxx: No such file or directory [root@linuxprobe ~]# ls -l xxxxxx > /root/stderr.txt ls: cannot access xxxxxx: No such file or directory [root@linuxprobe ~]# ls -l xxxxxx 2> /root/stderr.txt [root@linuxprobe ~]# cat /root/stderr.txt ls: cannot access xxxxxx: No such file or directory |
範例:使用輸入重定向把readme.txt文件導入給wc -l命令,統計一下文件中的內容行數
[root@linuxprobe ~]# wc -l < readme.txt 2 |
同時按下鍵盤上的Shift+\鍵即可輸入管道符,其執行格式為“命令A | 命令B”
把下麵這兩條命令合併為一條:
找出被限制登錄用戶的命令是grep "/sbin/nologin" /etc/passwd;
統計文本行數的命令則是wc -l。
[root@linuxprobe ~]# grep "/sbin/nologin" /etc/passwd | wc -l 33 |
範例:使用管道翻頁形式查看/etc目錄中的文件列表及屬性信息
ls -l /etc/ | more total 1396 drwxr-xr-x. 3 root root 97 Aug 14 01:15 abrt -rw-r--r--. 1 root root 16 Aug 14 01:24 adjtime -rw-r--r--. 1 root root 1518 Jun 7 2013 aliases -rw-r--r--. 1 root root 12288 Aug 13 17:40 aliases.db drwxr-xr-x. 2 root root 49 Aug 14 01:15 alsa drwxr-xr-x. 2 root root 4096 Aug 14 01:20 alternatives -rw-------. 1 root root 541 Jan 28 2014 anacrontab -rw-r--r--. 1 root root 55 Jan 29 2014 asound.conf -rw-r--r--. 1 root root 1 Jan 29 2014 at.deny drwxr-xr-x. 2 root root 31 Aug 14 01:17 at-spi2 drwxr-x---. 3 root root 41 Aug 14 01:15 audisp drwxr-x---. 3 root root 79 Aug 14 01:40 audit drwxr-xr-x. 4 root root 94 Aug 14 01:15 avahi --More-- |
範例:通過把管道符用一條命令來完成密碼重置操作
[root@linuxprobe ~]# echo "linuxprobe" | passwd --stdin root Changing password for user root. passwd: all authentication tokens updated successfully. |
範例:使用管道發送郵件
[root@linuxprobe Desktop]# cd -- [root@linuxprobe ~]# echo "Content" | mail -s "Subject" linuxprobe [root@linuxprobe ~]# su - linuxprobe Last login: Sat Aug 17 18:36:48 CST 2019 on pts/0 [linuxprobe@linuxprobe ~]$ mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/linuxprobe": 2 messages 2 new >N 1 root Mon Aug 19 18:19 18/578 "Subject" |
範例:使用管道讓用戶一直輸入內容,遇到自定義分界符時,輸入結束
[root@linuxprobe ~]# mail -s "Readme" [email protected] << over > I think linux is very practical > I hope to learn more > can you teache me? > over [root@linuxprobe ~]# |
問題:作為Linux運維人員,我們有時候也會遇到明明一個文件的名稱就在嘴邊但就是想不起來的情況。如果就記得一個文件的開頭幾個字母,想遍歷查找出所有以這個關鍵詞開頭的文件,該怎麼操作呢?
範例:單個查看硬碟文件
[root@linuxprobe ~]# ls -l /dev/sda brw-rw----. 1 root disk 8, 0 Aug 20 2019 /dev/sda [root@linuxprobe ~]# ls -l /dev/sda1 brw-rw----. 1 root disk 8, 1 Aug 20 2019 /dev/sda1 [root@linuxprobe ~]# ls -l /dev/sda2 brw-rw----. 1 root disk 8, 2 Aug 20 2019 /dev/sda2 [root@linuxprobe ~]# ls -l /dev/sda3 ls: cannot access /dev/sda3: No such file or directory [root@linuxprobe ~]# |
範例:使用通配符*查看文件
[root@linuxprobe ~]# ls -l /dev/sda* brw-rw----. 1 root disk 8, 0 Aug 20 2019 /dev/sda brw-rw----. 1 root disk 8, 1 Aug 20 2019 /dev/sda1 brw-rw----. 1 root disk 8, 2 Aug 20 2019 /dev/sda2 [root@linuxprobe ~]# |
範例:使用?查看文件
[root@linuxprobe ~]# ls -l /dev/sda? brw-rw----. 1 root disk 8, 1 Aug 20 2019 /dev/sda1 brw-rw----. 1 root disk 8, 2 Aug 20 2019 /dev/sda2 |
範例:使用匹配[]查看文件
[root@linuxprobe ~]# ls -l /dev/sda[0-9] brw-rw----. 1 root disk 8, 1 Aug 20 2019 /dev/sda1 brw-rw----. 1 root disk 8, 2 Aug 20 2019 /dev/sda2 [root@linuxprobe ~]# ls -l /dev/sda[135] brw-rw----. 1 root disk 8, 1 Aug 20 2019 /dev/sda1 [root@linuxprobe ~]# |
常用的轉義字元如下:
反斜杠(\):使反斜杠後面的一個變數變為單純的字元串
單引號(''):轉義其中所有的變數為單純的字元串
雙引號(""):保留其中的變數屬性,不進行轉義處理
反引號(``):把其中的命令執行後返回結果
範例:輸出以雙引號括起來的字元串與變數信息
[root@linuxprobe ~]# PRICE=5 [root@linuxprobe ~]# echo "Price is $PRICE" Price is 5 |
範例:輸出“Price is $5”
//這不是我們預期的 [root@linuxprobe ~]# echo "Price is $$PRICE" Price is 3767PRICE |
//想讓第一個“$”乖乖地作為美元符號,那麼就需要使用反斜杠(\)來進行轉義 [root@linuxprobe ~]# echo "Price is \$$PRICE" Price is $5 |
範例:只需要某個命令的輸出值時,可以像`命令`這樣,將命令用反引號括起來
[root@linuxprobe ~]# echo `uname -a` Linux linuxprobe.com 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux [root@linuxprobe ~]# echo uname -a uname -a |
變數是電腦系統用於保存可變值的數據類型。在Linux系統中,變數名稱一般都是大寫的,這是一種約定俗成的規範。我們可以直接通過變數名稱來提取到對應的變數值。
簡單來說,命令在Linux中的執行分為4個步驟。
第1步:判斷用戶是否以絕對路徑或相對路徑的方式輸入命令(如/bin/ls),如果是的話則直接執行。
第2步:Linux系統檢查用戶輸入的命令是否為“別名命令”,即用一個自定義的命令名稱來替換原本的命令名稱。可以用alias命令來創建一個屬於自己的命令別名,格式為“alias 別名=命令”。若要取消一個命令別名,則是用unalias命令,格式為“unalias 別名”。我們之前在使用rm命令刪除文件時,Linux系統都會要求我們再確認是否執行刪除操作,其實這就是Linux系統為了防止用戶誤刪除文件而特意設置的rm別名命令,接下來我們把它取消掉:
[root@linuxprobe ~]# ls anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates Desktop Downloads Music Public Videos [root@linuxprobe ~]# rm anaconda-ks.cfg rm: remove regular file ‘anaconda-ks.cfg’? y [root@linuxprobe~]# alias rm alias rm='rm -i' [root@linuxprobe ~]# unalias rm [root@linuxprobe ~]# rm initial-setup-ks.cfg [root@linuxprobe ~]# |
第3步:Bash解釋器判斷用戶輸入的是內部命令還是外部命令。內部命令是解釋器內部的指令,會被直接執行;而用戶在絕大部分時間輸入的是外部命令,這些命令交由步驟4繼續處理。可以使用“type命令名稱”來判斷用戶輸入的命令是內部命令還是外部命令。
第4步:系統在多個路徑中查找用戶輸入的命令文件,而定義這些路徑的變數叫作PATH,可以簡單地把它理解成是“解釋器的小助手”,作用是告訴Bash解釋器待執行的命令可能存放的位置,然後Bash解釋器就會乖乖地在這些位置中逐個查找。PATH是由多個路徑值組成的變數,每個路徑值之間用冒號間隔,對這些路徑的增加和刪除操作將影響到Bash解釋器對Linux命令的查找。
[root@linuxprobe ~]# echo $PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin [root@linuxprobe ~]# PATH=$PATH:/root/bin [root@linuxprobe ~]# echo $PATH /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/root/bin |
這裡有比較經典的問題:“為什麼不能將當前目錄(.)添加到PATH中呢? ” 原因是,儘管可以將當前目錄(.)添加到PATH變數中,從而在某些情況下可以讓用戶免去輸入命令所在路徑的麻煩。但是,如果黑客在比較常用的公共目錄/tmp中存放了一個與ls或cd命令同名的木馬文件,而用戶又恰巧在公共目錄中執行了這些命令,那麼就極有可能中招了。
所以,作為一名態度謹慎、有經驗的運維人員,在接手了一臺Linux系統後一定會在執行命令前先檢查PATH變數中是否有可疑的目錄,另外讀者從前面的PATH變數示例中是否也感覺到環境變數特別有用呢。
Linux系統中最重要的10個環境變數
變數名稱 |
作用 |
HOME |
用戶的主目錄(即家目錄) |
SHELL |
用戶在使用的Shell解釋器名稱 |
HISTSIZE |
輸出的歷史命令記錄條數 |
HISTFILESIZE |
保存的歷史命令記錄條數 |
|
郵件保存路徑 |
LANG |
系統語言、語系名稱 |
RANDOM |
生成一個隨機數字 |
PS1 |
Bash解釋器的提示符 |
PATH |
定義解釋器搜索用戶執行命令的路徑 |
EDITOR |
用戶預設的文本編輯器 |
範例:查看HOME變數在不同用戶身份下都有哪些值(su是用於切換用戶身份的命令)
[root@linuxprobe ~]# echo $HOME /root [root@linuxprobe ~]# su - linuxprobe Last login: Mon Aug 19 18:20:10 CST 2019 on pts/0 [linuxprobe@linuxprobe ~]$ echo $HOME /home/linuxprobe |
其實變數是由固定的變數名與用戶或系統設置的變數值兩部分組成的,我們完全可以自行創建變數,來滿足工作需求。
範例:設置一個名稱為WORKDIR的變數,方便用戶更輕鬆地進入一個層次較深的目錄
[root@linuxprobe ~]# mkdir /home/workdir [root@linuxprobe ~]# WORKDIR=/home/workdir [root@linuxprobe ~]# cd $WORKDIR [root@linuxprobe workdir]# pwd /home/workdir [root@linuxprobe workdir]# |
範例:使用export命令將其提升為全局變數
[root@linuxprobe workdir]# su linuxprobe [linuxprobe@linuxprobe ~]$ cd $WORKDIR [linuxprobe@linuxprobe ~]$ echo $WORKDIR
[linuxprobe@linuxprobe ~]$ exit exit [root@linuxprobe ~]# export WORKDIR [root@linuxprobe ~]# su linuxprobe [linuxprobe@linuxprobe workdir]$ cd $WORKDIR [linuxprobe@linuxprobe workdir]$ pwd /home/workdir |