The Linux Command Line讀書筆記(二)
第七章:
字符展開:
通過展開,你輸入的字符,在 shell 對它起作用之前,會展開成為別的字符。
[me@linuxbox ~]$ echo * Desktop Documents ls-output.txt Music Pictures Public Templates Videos
shell 把 “*” 展開成了另外的東西(在這種情況下,就是在當前工作目錄下的文件名字),在 echo 命令被執行前。當回車鍵被按下時,shell 在命令被執行前在命令行上自動展開任何符合條件的字符。
路徑名展開:
通配符工作機制叫做路徑名展開。
[me@linuxbox ~]$ echo D* Desktop Documents [me@linuxbox~]$ echo *s Documents Pictures Templates Videos [me@linuxbox ~]$ echo [[:upper:]]* Desktop Documents Music Pictures Public Templates Videos
波浪線展開:
波浪線字符 (“~”) 有特殊的意思。當它用在一個單詞的開頭時,它會展開成指定用戶的主目錄名,如果沒有指定用戶名,則是當前用戶的主目錄:
[me@linuxbox ~]$ echo ~
/home/me
如果有用戶 “foo” 這個帳號,然後:
[me@linuxbox ~]$ echo ~foo/home/foo
算數表達式展開:
shell 允許算術表達式通過展開來執行。這允許我們把 shell 提示當作計算器來使用:
[me@linuxbox ~]$ echo $((2 + 2)) 4
算術表達式展開使用這種格式:
$((expression))
算術表達式只支持整數(全部是數字,不帶小數點),但是能執行很多不同的操作。其中去冪是**。
在算術表達式中空格並不重要,並且表達式可以嵌套。例如,5 的平方乘以 3:
[me@linuxbox ~]$ echo $(($((5**2)) * 3)) 75 [me@linuxbox ~]$ echo $(((5**2) * 3))75
花括號展開:
通過花括號展開,可以從一個包含花括號的模式中創建多個文本字符串。
[me@linuxbox ~]$ echo Front-{A,B,C}-Back Front-A-Back Front-B-Back Front-C-Back [me@linuxbox ~]$ echo Number_{1..5} Number_1 Number_2 Number_3 Number_4 Number_5 [me@linuxbox ~]$ echo {Z..A} Z Y X W V U T S R Q P O N M L K J I H G F E D C B A [me@linuxbox ~]$ echo a{A{1,2},B{3,4}}b aA1b aA2b aB3b aB4b
例如創建一系列以“年-月”形式命名的目錄:
[me@linuxbox ~]$ mkdir Pics [me@linuxbox ~]$ cd Pics [me@linuxbox Pics]$ mkdir {2007..2009}-0{1..9} {2007..2009}-{10..12} [me@linuxbox Pics]$ ls 2007-01 2007-07 2008-01 2008-07 2009-01 2009-07 2007-02 2007-08 2008-02 2008-08 2009-02 2009-08 2007-03 2007-09 2008-03 2008-09 2009-03 2009-09 2007-04 2007-10 2008-04 2008-10 2009-04 2009-10 2007-05 2007-11 2008-05 2008-11 2009-05 2009-11 2007-06 2007-12 2008-06 2008-12 2009-06 2009-12
參數展開:
例如,叫做 “USER” 的變量包含你的用戶名。喚醒參數展開,揭示 USER 中的內容,可以這樣做:
[me@linuxbox ~]$ echo $USER me
通過參數展開,如果你拼寫錯了一個變量名,展開仍然會進行,只是展成一個空字符串。
命令替換:
命令替換允許我們把一個命令的輸出作為一個展開模式來使用:
[me@linuxbox ~]$ echo $(ls) Desktop Documents ls-output.txt Music Pictures Public Templates Videos [me@linuxbox ~]$ ls -l $(which cp) -rwxr-xr-x 1 root root 71516 2007-12-05 08:58 /bin/cp
這裏我們把 which cp 的執行結果作為一個參數傳遞給 ls 命令,因此要想得到 cp 程序的輸出列表,不必知道它完整的路徑名。我們不只限制於簡單命令。也可以使用整個管道線(只展示部分輸出):
[me@linuxbox ~]$ file $(ls /usr/bin/* | grep zip) /usr/bin/bunzip2: symbolic link to `bzip2‘ ....
雙引號:
如果你把文本放在雙引號中,shell 使用的特殊字符,除了 $,\ (反斜杠),和 ‘(倒引號)之外,則失去它們的特殊含義,被當作普通字符來看待。這意味著單詞分割,路徑名展開,波浪線展開,和花括號展開都被禁止,然而參數展開,算術展開,和命令替換仍然執行。使用雙引號,我們可以處理包含空格的文件名。比方說我們是不幸的名為 two words.txt 文件的受害者。如果我們試圖在命令行中使用這個文件,單詞分割機制會導致這個文件名被看作兩個獨自的參數,而不是所期望的單個參數:
[me@linuxbox ~]$ ls -l two words.txt ls: cannot access two: No such file or directory ls: cannot access words.txt: No such file or directory
使用雙引號,我們可以阻止單詞分割,得到期望的結果;進一步,我們甚至可以修復破損的文件名。
[me@linuxbox ~]$ ls -l "two words.txt" -rw-rw-r-- 1 me me 18 2008-02-20 13:03 two words.txt [me@linuxbox ~]$ mv "two words.txt" two_words.txt
在雙引號中,參數展開,算術表達式展開,和命令替換仍然有效:
[me@linuxbox ~]$ echo "$USER $((2+2)) $(cal)" me 4 February 2008 Su Mo Tu We Th Fr Sa ....
單引號:
如果需要禁止所有的展開,我們使用單引號。以下例子是無引用,雙引號,和單引號的比較結果:
[me@linuxbox ~]$ echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER text /home/me/ls-output.txt a b foo 4 me [me@linuxbox ~]$ echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER" text ~/*.txt {a,b} foo 4 me [me@linuxbox ~]$ echo ‘text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER‘ text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
註意:
hlk@hlk-Lenovo-XiaoXin-700-15ISK:~$ echo x {a,b} x a b hlk@hlk-Lenovo-XiaoXin-700-15ISK:~$ echo x_{a,b} x_a x_b
轉義字符:
有時候我們只想引用單個字符。我們可以在字符之前加上一個反斜杠,在這個上下文中叫做轉義字符。經常在雙引號中使用轉義字符,來有選擇地阻止展開。
[me@linuxbox ~]$ echo "The balance for user $USER is: \$5.00" The balance for user me is: $5.00 [me@linuxbox ~]$ mv bad\&filename good_filename
鍵盤高級操作技巧:
移動光標:
按鍵 | 行動 |
Ctrl-a | 移動光標到行首 |
Ctrl-e | 移動光標到行尾 |
Ctrl-f | 光標前移一個字符;和右箭頭作用一樣 |
Ctrl-b | 光標後移一個字符;和左箭頭作用一樣 |
Alt-f | 光標前移一個字 |
Alt-b | 光標後移一個字 |
Ctrl-l | 清空屏幕 |
修改文本:
按鍵 | 行動 |
Ctrl-d | 刪除光標位置的字符 |
Ctrl-t | 光標位置的字符和光標前面的字符互換位置 |
Alt-t | 光標位置的字和其前面的字互換位置 |
Alt-l | 把從光標位置到字尾的字符轉換成小寫字母 |
Alt-u | 把從光標位置到字尾的字符轉換成大寫字母 |
剪切和粘貼文本:
搜索歷史命令:
在任何時候,我們都可以瀏覽歷史列表的內容,通過:
[me@linuxbox ~]$ history | less
比方說我們想要找到列出目錄/usr/bin 內容的命令。一種方法,我們可以這樣做:
[me@linuxbox ~]$ history | grep /usr/bin
比方說在我們的搜索結果之中,我們得到一行,包含了有趣的命令,像這樣;
88 ls -l /usr/bin > ls-output.txt
數字 “88” 是這個命令在歷史列表中的行號。隨後在使用另一種展開類型時,叫做歷史命令展開,我們會用到這個數字。我們可以這樣做,來使用我們所發現的行:
[me@linuxbox ~]$ !88
bash 也具有按遞增順序來搜索歷史列表的能力。這意味著隨著字符的輸入,我們可以告訴 bash 去搜索歷史列表,每一個附加字符都進一步提煉我們的搜索。啟動遞增搜索,們可以告訴 bash 去搜索歷史列表,每一個附加字符都進一步提煉我們的搜索。啟動遞增搜索,輸入 Ctrl-r,其後輸入你要尋找的文本。當你找到它以後,你可以敲入 Enter 來執行命令,或者輸入 Ctrl-j,從歷史列表中復制這一行到當前命令行。再次輸入 Ctrl-r,來找到下一個匹配項(向上移動歷史列表)。輸入 Ctrl-g 或者 Ctrl-c,退出搜索。
首先輸入 Ctrl-r:
(reverse-i-search)`‘:
提示符改變,顯示我們正在執行反向遞增搜索。搜索過程是 “反向的”,因為我們按照從”現在” 到過去某個時間段的順序來搜尋。下一步,我們開始輸入要查找的文本。在這個例子裏是 “/usr/bin”:
(reverse-i-search)`/usr/bin‘: ls -l /usr/bin > ls-output.txt
即刻,搜索返回我們需要的結果。我們可以執行這個命令,按下 Enter 鍵,或者我們可以復制這個命令到我們當前的命令行,來進一步編輯它,輸入 Ctrl-j。復制它,輸入 Ctrl-j:
[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt
歷史命令展開:
序列 | 行為 |
!! | 重復最後一次執行的命令 |
!number | 重復歷史列表中第 number 行的命令 |
!string | 重復最近歷史列表中,以這個字符串開頭的命令 |
!?string | 重復最近歷史列表中,包含這個字符串的命令 |
權限:
擁有者,組成員,和其他人:
可以用 id 命令,來找到關於你自己身份的信息:
hlk@hlk-Lenovo-XiaoXin-700-15ISK:~$ id uid=1000(hlk) gid=1000(hlk) 組=1000(hlk),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
當用戶創建帳戶之後,系統會給用戶分配一個號碼,叫做用戶 ID或者 uid,然後,為了符合人類的習慣,這個 ID 映射到一個用戶名。系統又會給這個用戶分配一個原始的組 ID 或者是 gid,這個 gid 可能屬於另外的組。
用戶帳戶定義在/etc/passwd 文件裏面,用戶組定義在/etc/group 文件裏面。當用戶帳戶和用戶組創建以後,這些文件隨著文件/etc/shadow 的變動而修改,文件/etc/shadow 包含了關於用戶密碼的信息。對於每個用戶帳號,文件/etc/passwd 定義了用戶(登錄)名,uid,gid,帳號的真實姓名,主目錄,和登錄 shell。
讀取,寫入,和執行:
對於文件和目錄的訪問權力是根據讀訪問,寫訪問,和執行訪問來定義的。
hlk@hlk-Lenovo-XiaoXin-700-15ISK:~$ >foo.txt hlk@hlk-Lenovo-XiaoXin-700-15ISK:~$ ls -l foo.txt -rw-rw-r-- 1 hlk hlk 0 9月 2 16:35 foo.txt
列表的前十個字符是文件的屬性。這十個字符的第一個字符表明文件類型。如下表所示:
屬性 | 文件類型 |
- | 一個普通文件 |
d | 一個目錄 |
l | 一 個 符 號 鏈 接。註 意 對 於 符 號 鏈 接 文 件,剩 余 的 文 件 屬 性 總是”rwxrwxrwx”,而且都是虛擬值。真正的文件屬性是指符號鏈接所指向的文件的屬性 |
c | 一個字符設備文件。這種文件類型是指按照字節流,來處理數據的設備。比如說終端機,或者調制解調器 |
b | 一個塊設備文件。這種文件類型是指按照數據塊,來處理數據的設備,例如一個硬盤,或者 CD-ROM 盤 |
剩下的九個字符,叫做文件模式,代表著文件所有者,文件組所有者,和其他人的讀,寫,執行權限。
chmod -更改文件模式:
The Linux Command Line讀書筆記(二)