Liunx 管道符、重定向與環(huán)境變量

輸入輸出重定向

??輸入重定向是指把文件導(dǎo)入到命令中,而輸出重定向則是把原本要輸出到屏幕的數(shù)據(jù)信息寫入到指定文件中.
? 標(biāo)準(zhǔn)輸入重定向(STDIN,文件描述符為0):默認(rèn)從鍵盤輸入,也可從其他文件或命令中輸入.
? 標(biāo)準(zhǔn)輸出重定向(STDOUT,文件描述符為1):默認(rèn)輸出到屏幕
? 錯(cuò)誤輸出重定向(STDERR,文件描述符為2):默認(rèn)輸出到屏幕
??對于輸入重定向來講,用到的符號(hào)及其作用如表 3-1 所示。

??????????????表3-1 ???? 輸入重定向中用到的符號(hào)及其作用

符號(hào) 作用
命令 < 文件 將文件作為命令的標(biāo)準(zhǔn)輸入
命令 <<分界符 從標(biāo)準(zhǔn)輸入中讀入,直到遇見分界符才停止
命令 <文件1> 文件2 將文件1作為命令的標(biāo)準(zhǔn)輸入并將標(biāo)準(zhǔn)輸出到文件2

??對于輸出重定向來講,用到的符號(hào)及其作用如表3-2所示例.

??????????????表3-2 ????輸出重定向中用到的符號(hào)及其作用

符號(hào) 作用
命令 > 文件 將標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中(清空原有文件的數(shù)據(jù))
命令 2> 文件 將錯(cuò)誤輸出重定向到一個(gè)文件中(清空原有文件的數(shù)據(jù))
命令 >> 文件 將標(biāo)準(zhǔn)輸出重定向到一個(gè)文件中(追加到原有內(nèi)容的后面)
命令 2>> 文件 將錯(cuò)誤輸出重定向到一個(gè)文件中(追加到原有內(nèi)容的后面)
命令 >> 文件 2>&1 或 命令 &>> 文件 將標(biāo)準(zhǔn)輸出與錯(cuò)誤輸出共同寫入到文件中(追加到原有內(nèi)容的后面)

??通過標(biāo)準(zhǔn)輸出重定向?qū)an bash命令原本要輸出到屏幕的信息寫入到文件readme.txt中,然后顯示readme.txt文件中的內(nèi)容:

[root@linuxprobe ~]# man bash > readme.txt
[root@linuxprobe ~]# cat readme.txt
BASH(1)
General Commands Manual
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.
..................省略部分輸出信息..................

??輸出重定向技術(shù)中的覆蓋寫入與追加寫入:首先通過覆蓋寫入模式向readme.txt文件寫入一行數(shù)據(jù)(該文件中包含了上一個(gè)實(shí)驗(yàn)的man 命令信息),然后再通過追加寫入模式向文件再寫入一次數(shù)據(jù),其命令如下:

[root@linuxprobe ~]# echo "Welcome to LinuxProbe.Com" > readme.txt
[root@linuxprobe ~]# echo "Quality linux learning materials" >> readme.txt

??在執(zhí)行 cat 命令之后,可以看到如下所示的文件內(nèi)容:

[root@linuxprobe ~]# cat readme.txt
Welcome to LinuxProbe.Com
Quality linux learning materials 

??不同命令的標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出還是有區(qū)別的:

zheng@zheng-Vostro-3667:~/下載$ ls -l xx
ls: 無法訪問'xx': 沒有那個(gè)文件或目錄
zheng@zheng-Vostro-3667:~/下載$ ls -l xx > readme.txt 
ls: 無法訪問'xx': 沒有那個(gè)文件或目錄
zheng@zheng-Vostro-3667:~/下載$ cat readme.txt 
zheng@zheng-Vostro-3667:~/下載$ ls -l xx 2> readme.txt 
zheng@zheng-Vostro-3667:~/下載$ cat readme.txt 
ls: 無法訪問'xx': 沒有那個(gè)文件或目錄
zheng@zheng-Vostro-3667:~/下載$ 

管道命令符

??同時(shí)按下鍵盤上的Shift+\鍵即可輸入管道符,其執(zhí)行格式為 "命令A(yù)|命令B".管道命令符的作用也可以用一句話來概括"把前一個(gè)命令原本要輸出到屏幕的標(biāo)準(zhǔn)正常數(shù)據(jù)當(dāng)作是后一個(gè)命令的標(biāo)準(zhǔn)輸入".
??例如,我們可以把兩條命令合并為一條:
? 找出被限制登錄用戶的命令是 grep "/sbin/nologin" /etc/passwd
? 統(tǒng)計(jì)文本行數(shù)的命令則是wc -l

zheng@zheng-Vostro-3667:~/go/src/gitlab.fz.stevegame.red/back-end/room/log$ grep /sbin/nologin /etc/passwd |wc -l
34

??我們可以將它套用到其他不同的命令上,比如用翻頁的形式查看/etc目錄中的文件列表及屬性信息(這些內(nèi)容默認(rèn)會(huì)一股腦兒地顯示到屏幕上,根本看不清除):

zheng@zheng-Vostro-3667:~/go/src/gitlab.fz.stevegame.red/back-end/room/log$ ls -l /etc/ |more
總用量 1172
drwxr-xr-x  3 root root    4096 7月  25  2018 acpi
-rw-r--r--  1 root root    3028 7月  25  2018 adduser.conf
drwxr-xr-x  2 root root    4096 7月  31  2018 alternatives
-rw-r--r--  1 root root     401 5月  30  2017 anacrontab
drwxr-xr-x  3 root root    4096 7月  28  2018 apache2
-rw-r--r--  1 root root     433 10月  2  2017 apg.conf
drwxr-xr-x  6 root root    4096 7月  25  2018 apm
drwxr-xr-x  3 root root    4096 10月  6 06:31 apparmor
drwxr-xr-x  8 root root    4096 2月  14 06:12 apparmor.d
drwxr-xr-x  4 root root    4096 10月 23 10:00 apport
-rw-r--r--  1 root root     769 4月   4  2018 appstream.conf
drwxr-xr-x  6 root root    4096 2月  12 14:35 apt
drwxr-xr-x  3 root root    4096 2月   1 06:01 avahi
--更多--

命令行的通配符

??假設(shè)想要批量查看所有硬盤文件的相關(guān)權(quán)限屬性,一種方式是這樣的:

root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 2月  18 14:15 /dev/sda
root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda1
brw-rw---- 1 root disk 8, 1 2月  18 14:15 /dev/sda1
root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda2
brw-rw---- 1 root disk 8, 2 2月  18 14:15 /dev/sda2
root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda3
ls: 無法訪問'/dev/sda3': 沒有那個(gè)文件或目錄

??這些硬盤設(shè)備文件都是以sda開頭并且存放到了/dev目錄中,這樣一來,即使我們不知道硬盤的分區(qū)編號(hào)和具體分區(qū)的個(gè)數(shù),也可以使用通配符來搞定.
??通配符就是通用的匹配信息的符號(hào),比如 * 代表匹配零個(gè)或多個(gè)字符, ?代表匹配單個(gè)字符,中括號(hào)內(nèi)加上數(shù)字[0-9]代表匹配 0~9 之間的單個(gè)數(shù)字的字符,而中括號(hào)內(nèi)加上字母[abc]則是代表匹配a、b、c三個(gè)字符中的任意一個(gè)字符
??例如,下面來匹配所有在/dev目錄中且以sda開頭的文件:

root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda*
brw-rw---- 1 root disk 8, 0 2月  18 14:15 /dev/sda
brw-rw---- 1 root disk 8, 1 2月  18 14:15 /dev/sda1
brw-rw---- 1 root disk 8, 2 2月  18 14:15 /dev/sda2
brw-rw---- 1 root disk 8, 5 2月  18 14:15 /dev/sda5

root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda?
brw-rw---- 1 root disk 8, 1 2月  18 14:15 /dev/sda1
brw-rw---- 1 root disk 8, 2 2月  18 14:15 /dev/sda2
brw-rw---- 1 root disk 8, 5 2月  18 14:15 /dev/sda5

root@zheng-Vostro-3667:/home/zheng/go/src/gitlab.fz.stevegame.red/back-end/room/log# ls -l /dev/sda[0-9]
brw-rw---- 1 root disk 8, 1 2月  18 14:15 /dev/sda1
brw-rw---- 1 root disk 8, 2 2月  18 14:15 /dev/sda2
brw-rw---- 1 root disk 8, 5 2月  18 14:15 /dev/sda5

常用的轉(zhuǎn)義字符

??4個(gè)最常用的轉(zhuǎn)義字符如下所示
?反斜杠 \ :使反斜杠后面的一個(gè)變量變?yōu)閱渭兊淖址?
?單引號(hào) '': 轉(zhuǎn)義其中所有的變量為單純的字符串
?雙引號(hào) "": 保留其中的變量屬性,不進(jìn)行轉(zhuǎn)義處理
?反引號(hào) ``:把其中的命令執(zhí)行后返回

??先定義一個(gè)名為PRICE的變量并賦值為5,然后輸出雙引號(hào)括起來的字符串與變量信息:

zheng@zheng-Vostro-3667:~$ PRICE=5
zheng@zheng-Vostro-3667:~$ echo "Price is $PRICE"
Price is 5
zheng@zheng-Vostro-3667:~$ echo "PRICE"
PRICE

??如果我們希望輸出"Price is $5",$$作用是顯示當(dāng)前程序的進(jìn)程ID號(hào)碼,那么就需要使用反斜杠( \ )來進(jìn)行轉(zhuǎn)義,將這個(gè)命令提取符轉(zhuǎn)義成單純的文本,去除其特殊功能.

zheng@zheng-Vostro-3667:~$ echo "Price is $$PRICE"
Price is 27790PRICE
zheng@zheng-Vostro-3667:~$ echo "Price is \$$PRICE"
Price is $5
zheng@zheng-Vostro-3667:~$ 

??如果只需要某個(gè)命令的輸出值時(shí),可以像`命令`這樣,將命令用反引號(hào)括起來,達(dá)到預(yù)期的效果.例如,將反引號(hào)與 uname-a 命令結(jié)合, 然后使用echo 命令來查看本機(jī)的Liunx版本和內(nèi)核信息:

zheng@zheng-Vostro-3667:~$ echo `uname -a`
Linux zheng-Vostro-3667 4.15.0-45-generic #48-Ubuntu SMP Tue Jan 29 16:28:13 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

??在Liunx系統(tǒng)中一切都是文件,Liunx命令也不例外.那么,在用戶執(zhí)行了一條命令之后,Liunx系統(tǒng)中到底發(fā)生了什么事情呢?簡單來說,命令在Liunx中的執(zhí)行分為4個(gè)步驟.

第1步: 判斷用戶是否以絕對路徑或相對路徑的方式輸入命令(如 /bin/ls), 如果是的話則直接執(zhí)行.

第2步: Liunx系統(tǒng)檢查用戶輸入的命令是否是"別名命令",即用一個(gè)自定義的命令名稱來替換原本的命令名稱.可以用alias命令來創(chuàng)建一個(gè)屬于自己的命令別名,格式為"alias 別名=命令".若要取消一個(gè)命令別名,則是用unalias命令,格式為
"unalias 別名". 我們之前在使用rm命令刪除文件時(shí),Liunx系統(tǒng)都會(huì)要求我們再確認(rèn)是否執(zhí)行刪除操作,其實(shí)這就是Liunx系統(tǒng)為了防止用戶誤刪除文件而特意設(shè)置的rm別名命令,接下來我們把它取消掉:

zheng@zheng-Vostro-3667:~$ alias rm='rm -i'
zheng@zheng-Vostro-3667:~$ rm gold_change:room-127.0.0.1-13001.diskqueue.meta.dat
rm:是否刪除普通文件 'gold_change:room-127.0.0.1-13001.diskqueue.meta.dat'? ^C
zheng@zheng-Vostro-3667:~$ unalias rm
zheng@zheng-Vostro-3667:~$ rm gold_change:room-127.0.0.1-13001.diskqueue.meta.dat

第3步:Bash解釋器判斷用戶輸入的是內(nèi)部命令還是外部命令.內(nèi)部命令是解釋器內(nèi)部的指令,會(huì)被直接執(zhí)行;而用戶在絕大部分時(shí)間輸入的是外部命令,這些命令交由步驟4繼續(xù)處理.可以使用"type 命令名稱"來判斷用戶輸入的命令是內(nèi)部命令還是外部命令

zheng@zheng-Vostro-3667:~$ type rm
rm 已被錄入哈希表 (/bin/rm)
zheng@zheng-Vostro-3667:~$ type ls
ls 是 `ls --color=auto' 的別名
zheng@zheng-Vostro-3667:~$ type cat
cat 是 /bin/cat
zheng@zheng-Vostro-3667:~$ type cd
cd 是 shell 內(nèi)建
zheng@zheng-Vostro-3667:~$ type grep
grep 是 `grep --color=auto' 的別名

第4步:系統(tǒng)在多個(gè)路徑中查找用戶輸入的命令文件,而定義這些路徑的變量叫做PATH,可以簡單地把它理解成是"解釋器的小助手",作用是告訴Bash解釋器執(zhí)行的命令可能存放的位置,每個(gè)路徑值之間用冒號(hào)間隔,對這些路徑的增加和刪除操作將影響到Bash解釋器對Liunx命令的查找.

zheng@zheng-Vostro-3667:~$ echo $PATH
/home/zheng/.local/bin:/home/zheng/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/zheng/go/bin:=/home/zheng/go/bin:/home/zheng/software/go1.10.3.linux-amd64/go/bin:/home/zheng/software/nsq-1.0.0-compat.linux-amd64.go1.8/bin
zheng@zheng-Vostro-3667:~$ PATH=$PATH:/zheng
zheng@zheng-Vostro-3667:~$ echo $PATH
/home/zheng/.local/bin:/home/zheng/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/zheng/go/bin:=/home/zheng/go/bin:/home/zheng/software/go1.10.3.linux-amd64/go/bin:/home/zheng/software/nsq-1.0.0-compat.linux-amd64.go1.8/bin:/zheng

我們可以用env命令來查看到Liunx系統(tǒng)中的所有環(huán)境變量

表 3-3 Linux 系統(tǒng)中最重要的 10 個(gè)環(huán)境變量

變量命令 作用
HOME 用戶的主目錄(即家目錄)
SHELL 用戶在使用的 Shell 解釋器名稱
HISTSIZE 輸出的歷史命令記錄條數(shù)
HISTFILESIZE 保存的歷史命令記錄條數(shù)
MAIL 郵件保存路徑
LANG 系統(tǒng)語言、語系名稱
RANDOM 生成一個(gè)隨機(jī)數(shù)字
PS1 Bash 解釋器的提示符
PATH 定義解釋器搜索用戶執(zhí)行命令的路徑
EDITOR 用戶默認(rèn)的文本編輯器

??Liunx作為一個(gè)多用戶多任務(wù)的操作系統(tǒng),能夠?yàn)槎鄠€(gè)用戶提供獨(dú)立的、合適的工作運(yùn)行環(huán)境,因此,一個(gè)相同的變量會(huì)因?yàn)橛脩羯矸莸牟煌哂胁煌闹?例如,我們使用下述命令來查看HOME變量在不同用戶身份下都有哪些值:

zheng@zheng-Vostro-3667:~$ echo $HOME
/home/zheng
zheng@zheng-Vostro-3667:~$ su - root
密碼: 
root@zheng-Vostro-3667:~# echo $HOME
/root
root@zheng-Vostro-3667:~# 

??其實(shí)變量是由固定的變量名與用戶或系統(tǒng)設(shè)置的變量值兩部分組成,我們完全可以自行創(chuàng)建變量,來滿足工作需求.例如設(shè)置一個(gè)名稱為WORKDIR的變量,方便用戶更輕松地進(jìn)入一個(gè)層次較深的目錄:

zheng@zheng-Vostro-3667:~$ sudo rm -rf /home/workdir
zheng@zheng-Vostro-3667:~$ sudo mkdir /home/workdir
zheng@zheng-Vostro-3667:~$ WORKDIR=/home/workdir
zheng@zheng-Vostro-3667:~$ echo $WORKDIR
/home/workdir
zheng@zheng-Vostro-3667:~$ sudo rm -rf /home/workdir
zheng@zheng-Vostro-3667:~$ echo $WORKDIR
/home/workdir
zheng@zheng-Vostro-3667:~$ 

??但是這樣的變量不具有全局性,作用范圍也有限,默認(rèn)情況下不能被其他用戶使用,如果工作需要,可以使用export命令將其提升為全局變量,這樣其他用戶也就可以使用它了:

[root@linuxprobe workdir]# su linuxprobe
Last login: Fri Mar 20 20:52:10 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ cd $WORKDIR
[linuxprobe@linuxprobe ~]$ echo $WORKDIR
[linuxprobe@linuxprobe ~]$ exit
[root@linuxprobe ~]# export WORKDIR
[root@linuxprobe ~]# su linuxprobe
Last login: Fri Mar 20 21:52:10 CST 2017 on pts/0
[linuxprobe@linuxprobe ~]$ cd $WORKDIR
[linuxprobe@linuxprobe workdir]$ pwd
/home/workdir
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容