The Linux Command Line读书笔记(二)
第七章:
字符展開:
通過展開,你輸入的字符,在 shell 對它起作用之前,會展開成為別的字符。
[me@linuxbox ~]$ echo * Desktop Documents ls-output.txt Music Pictures Public Templates Videosshell 把 “*” 展開成了另外的東西(在這種情況下,就是在當前工作目錄下的文件名字),在 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 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 bhlk@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 ~]$ !88bash 也具有按遞增順序來搜索歷史列表的能力。這意味著隨著字符的輸入,我們可以告訴 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 -更改文件模式:
更改文件或目錄的模式(權限),可以利用 chmod 命令。注意只有文件的所有者或者超級用戶才能更改文件或目錄的模式。chmod 命令支持兩種不同的方法來改變文件模式:八進制數字表示法,或符號表示法。
| Octal | Binary | File Mode |
| 0 | 000 | --- |
| 1 | 001 | --x |
| 2 | 010 | -w- |
| 3 | 011 | -wx |
| 4 | 100 | r-- |
| 5 | 101 | r-x |
| 6 | 110 | rw- |
| 7 | 111 | rwx |
通過使用 3 個八進制數字,我們能夠設置文件所有者,用戶組,和其他人的權限
[me@linuxbox ~]$ > foo.txt [me@linuxbox ~]$ ls -l foo.txt -rw-rw-r-- 1 me me 0 2008-03-06 14:52 foo.txt [me@linuxbox ~]$ chmod 600 foo.txt [me@linuxbox ~]$ ls -l foo.txt -rw------- 1 me me 0 2008-03-06 14:52 foo.txtchmod 命令支持一種符號表示法,來指定文件模式。符號表示法分為三部分:更改會影響誰,要執行哪個操作,要設置哪種權限。通過字符“u”,“g”,“o”,and “a”的組合來指定要影響的對象,如下所示:
| u | “user”的簡寫,意思是文件或目錄的所有者 |
| g | 用戶組 |
| o | “others”的簡寫,意思是其他所有的人 |
| a | “all”的簡寫,是“u”,“g”,和“o”三者的聯合 |
如果沒有指定字符,則假定使用“all”。執行的操作可能是一個“+”字符,表示加上一個權限,一個“-”,表示刪掉一個權限,或者是一個“=”,表示只有指定的權限可用,其它所有的權限被刪除。
權限由“r”, “w”, and “x”來指定。這里是一些符號表示法的實例:
| u+x | 為文件所有者添加可執行權限 |
| u-x | 刪除文件所有者的可執行權限 |
| +x | 為文件所有者,用戶組,和其他所有人添加可執行權限。等價于 a+x |
| o-rw | 除了文件所有者和用戶組,刪除其他人的讀權限和寫權限 |
| go=rw | 給群組的主人和任意文件擁有者的人讀寫權限。如果群組的主人或全局之前已經有了執行的權限,他們將被移除 |
| u+x,go=rw | 給文件擁有者執行權限并給組和其他人讀和執行的權限。多種設定可以用逗號分開 |
要注意“--recursive”選項:它可以同時作用于文件和目錄
umask -設置默認權限
當創建一個文件時,umask 命令控制著文件的默認權限。umask 命令使用八進制表示法來表達從文件模式屬性中刪除一個位掩碼。
[me@linuxbox ~]$ rm -f foo.txt [me@linuxbox ~]$ umask 0002 [me@linuxbox ~]$ > foo.txt [me@linuxbox ~]$ ls -l foo.txt -rw-rw-r-- 1 me me 0 2008-03-06 14:53 foo.txt當掩碼設置為 0000(實質上是關掉它)之后,我們看到其他人能夠讀寫文件。
[me@linuxbox ~]$ rm foo.txt [me@linuxbox ~]$ umask 0000 [me@linuxbox ~]$ > foo.txt [me@linuxbox ~]$ ls -l foo.txt -rw-rw-rw- 1 me me 0 2008-03-06 14:58 foo.txt| Original file mode | --- rw- rw- rw- |
| Mask | 000 000 000 010 |
| Result | --- rw- rw- r-- |
su -以其他用戶身份和組 ID 運行一個 shell:
su [-[l]] [user]如果包含 “-l” 選項,那么會為指定用戶啟動一個需要登錄的 shell。這意味著會加載此用戶的 shell 環境,并且工作目錄會更改到這個用戶的主目錄。這通常是我們所需要的。如果不指定用戶,那么就假定是超級用戶。注意(不可思議地),選項 “-l” 可以縮寫為”-”,這是經常用到的形式。
也可以只執行單個命令,而不是啟動一個新的可交互的 shell:
su -c 'command'使用這種模式,命令傳遞到一個新 shell 中執行。把命令用單引號引起來很重要,因為我們不想命令在我們的 shell 中展開,但需要在新 shell 中展開。
[me@linuxbox ~]$ su -c 'ls -l /root/*'sudo -以另一個用戶身份執行命令:
管理員能夠配置 sudo 命令,從而允許一個普通用戶以不同的身份(通常是超級用戶),通過一種非??煽氐姆绞絹韴绦忻?。尤其是,只有一個用戶可以執行一個或多個特殊命令時,(更體現了 sudo命令的方便性)。另一個重要差異是 sudo 命令不要求超級用戶的密碼。使用 sudo 命令時,用戶使用他/她自己的密碼來認證。
su 和 sudo 之間的一個重要區別是 sudo 不會重新啟動一個 shell,也不會加載另一個用戶的 shell 運行環境。這意味者命令不必用單引號引起來。
chown -更改文件所有者和用戶組:
chown 命令被用來更改文件或目錄的所有者和用戶組。使用這個命令需要超級用戶權限。chown 命令的語法看起來像這樣:
chown [owner][:[group]] file..chown 命令可以更改文件所有者和/或文件用戶組,依據于這個命令的第一個參數。
chgrp -更改用戶組所有權:
更改用戶密碼:
passwd [user]?
shell 環境:
linux下的變量:
shell 在環境中存儲了兩種基本類型的數據。它們是環境變量和 shell 變量。Shell 變量是由 bash 存放的一很少數據,而環境變量基本上就是其它的所有數據。除了變量,shell 也存儲了一些可編程的數據,命名為別名和shell 函數。
檢查環境變量:
set命令可以顯示 shell 和環境變量兩者,而 printenv 只是顯示環境變量。
printenv 命令也能夠列出特定變量的數值:
[me@linuxbox ~]$ printenv USER me當使用沒有帶選項和參數的 set 命令時,shell 和環境變量二者都會顯示,同時也會顯示定義的 shell 函數。不同于 printenv 命令,set 命令的輸出結果很禮貌地按照字母順序排列。
也可以通過 echo 命令來查看一個變量的內容。
[me@linuxbox ~]$ echo $HOME /home/me如果 shell 環境中的一個成員既不可用 set 命令也不可用 printenv 命令顯示,則這個變量是別名。輸入不帶參數的 alias 命令來查看它們。
如何建立 shell 環境:
當我們登錄系統后,啟動 bash 程序,并且會讀取一系列稱為啟動文件的配置腳本,這些文件定義了默認的可供所有用戶共享的 shell 環境。然后是讀取更多位于我們自己主目錄中的啟動文件,這些啟動文件定義了用戶個人的 shell 環境。精確的啟動順序依賴于要運行的 shell 會話類型。有兩種 shell 會話類型:一個是登錄 shell 會話,另一個是非登錄 shell 會話。登錄 shell 會話會提示用戶輸入用戶名和密碼。
登錄 shell 會讀取一個或多個啟動文件:
| 文件 | 內容 |
| /etc/profile? | 應用于所有用戶的全局配置腳本 |
| ?/.bash_profile | 用戶私人的啟動文件。可以用來擴展或重寫全局配置腳本中的設置 |
| ?/.bash_login | 如果文件 ?/.bash profile 沒有找到,bash 會嘗試讀取這個腳本 |
| ?/.profile | 如果文件 ?/.bash profile 或文件 ?/.bash login 都沒有找到,bash 會試圖讀取這個文件。這是基于 Debian 發行版的默認設置 |
非登錄 shell 會話會讀取以下啟動文件:
| 文件 | 內容 |
| /etc/bash.bashrc | 應用于所有用戶的全局配置文件 |
| ?/.bashrc | 用戶私有的啟動文件。可以用來擴展或重寫全局配置腳本中的設置 |
除了讀取以上啟動文件之外,非登錄 shell 會話也會繼承它們父進程的環境設置,通常是一個登錄 shell。
我們應該修改哪個文件:
按照通常的規則,添加目錄到你的 PATH 變量或者是定義額外的環境變量,要把這些更改放置到.bash profile 文件中(或者其替代文件中,根據不同的發行版。例如,Ubuntu 使用.profile 文件)。對于其它的更改,要放到.bashrc 文件中。
激活我們的修改:
我們對于文件.bashrc 的修改不會生效,直到我們關閉終端會話,再重新啟動一個新的會話,因為.bashrc 文件只是在剛開始啟動終端會話時讀取。然而,我們可以強迫 bash 重新讀取修改過的.bashrc 文件,使用下面的命令:
[me@linuxbox ~]$ source .bashrc?
轉載于:https://www.cnblogs.com/hlk09/p/9574113.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的The Linux Command Line读书笔记(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript 数字转汉字+ele
- 下一篇: Django-分页扩展