摘自鸟站
http://linux.vbird.org/
22.2.5 RPM 驗證與數位簽章 (Verify/signature)
rpm -Va
-Va :列出目前系統上面所有可能被更動過的檔案;
21.6 檢驗軟體正確性
21.6.1 md5sum / sha1sum / sha256sum
21.4.2 Tarball 安裝的基本步驟
OK!我們底下約略提一下大部分的 tarball 軟體之安裝的指令下達方式:
- ./configure
這個步驟就是在建立 Makefile 這個檔案囉!通常程式開發者會寫一支 scripts 來檢查你的 Linux 系統、相關的軟體屬性等等,這個步驟相當的重要, 因為未來你的安裝資訊都是這一步驟內完成的!另外,這個步驟的相關資訊應該要參考一下該目錄下的 README 或 INSTALL 相關的檔案! - make clean
make 會讀取 Makefile 中關於 clean 的工作。這個步驟不一定會有,但是希望執行一下,因為他可以去除目標檔案!因為誰也不確定原始碼裡面到底有沒有包含上次編譯過的目標檔案 (*.o) 存在,所以當然還是清除一下比較妥當的。 至少等一下新編譯出來的執行檔我們可以確定是使用自己的機器所編譯完成的嘛! - make
make 會依據 Makefile 當中的預設工作進行編譯的行為!編譯的工作主要是進行 gcc 來將原始碼編譯成為可以被執行的 object files ,但是這些 object files 通常還需要一些函式庫之類的 link 後,才能產生一個完整的執行檔!使用 make 就是要將原始碼編譯成為可以被執行的可執行檔,而這個可執行檔會放置在目前所在的目錄之下, 尚未被安裝到預定安裝的目錄中; - make install
通常這就是最後的安裝步驟了,make 會依據 Makefile 這個檔案裡面關於 install 的項目,將上一個步驟所編譯完成的資料給他安裝到預定的目錄中,就完成安裝啦!
创建目录
第六章、Linux 檔案與目錄管理
- 6.1.2 目錄的相關操作: cd, pwd, mkdir, rmdir
- mkdir (建立新目錄)
[root@study ~]# mkdir [-mp] 目錄名稱 選項與參數: -m :設定檔案的權限喔!直接設定,不需要看預設權限 (umask) 的臉色~ -p :幫助你直接將所需要的目錄(包含上層目錄)遞迴建立起來! 範例:請到/tmp底下嘗試建立數個新目錄看看: [root@study ~]# cd /tmp [root@study tmp]# mkdir test <==建立一名為 test 的新目錄 [root@study tmp]# mkdir test1/test2/test3/test4 mkdir: cannot create directory ‘test1/test2/test3/test4’: No such file or directory # 話說,系統告訴我們,沒可能建立這個目錄啊!就是沒有目錄才要建立的!見鬼嘛? [root@study tmp]# mkdir -p test1/test2/test3/test4 # 原來是要建 test4 上層沒先建 test3 之故!加了這個 -p 的選項,可以自行幫你建立多層目錄! 範例:建立權限為rwx--x--x的目錄 [root@study tmp]# mkdir -m 711 test2 [root@study tmp]# ls -ld test* drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 # 仔細看上面的權限部分,如果沒有加上 -m 來強制設定屬性,系統會使用預設屬性。 # 那麼你的預設屬性為何?這要透過底下介紹的 umask 才能瞭解喔! ^_^
复制档案或目录
- 6.2.2 複製、刪除與移動: cp, rm, mv
- cp (複製檔案或目錄)
[root@study ~]# cp [-adfilprsu] 來源檔(source) 目標檔(destination)
[root@study ~]# cp [options] source1 source2 source3 .... directory
選項與參數:
-a :相當於 -dr --preserve=all 的意思,至於 dr 請參考下列說明;(常用)
-d :若來源檔為連結檔的屬性(link file),則複製連結檔屬性而非檔案本身;
-f :為強制(force)的意思,若目標檔案已經存在且無法開啟,則移除後再嘗試一次;
-i :若目標檔(destination)已經存在時,在覆蓋時會先詢問動作的進行(常用)
-l :進行硬式連結(hard link)的連結檔建立,而非複製檔案本身;
-p :連同檔案的屬性(權限、用戶、時間)一起複製過去,而非使用預設屬性(備份常用);
-r :遞迴持續複製,用於目錄的複製行為;(常用)
-s :複製成為符號連結檔 (symbolic link),亦即『捷徑』檔案;
-u :destination 比 source 舊才更新 destination,或 destination 不存在的情況下才複製。
--preserve=all :除了 -p 的權限相關參數外,還加入 SELinux 的屬性, links, xattr 等也複製了。
最後需要注意的,如果來源檔有兩個以上,則最後一個目的檔一定要是『目錄』才行!
|
tar
8.3.1 tar
tar 的選項與參數非常的多!我們只講幾個常用的選項,更多選項您可以自行 man tar 查詢囉!
[dmtsai@study ~]$ tar [-z|-j|-J] [cv] [-f 待建立的新檔名] filename... <==打包與壓縮
[dmtsai@study ~]$ tar [-z|-j|-J] [tv] [-f 既有的 tar檔名] <==察看檔名
[dmtsai@study ~]$ tar [-z|-j|-J] [xv] [-f 既有的 tar檔名] [-C 目錄] <==解壓縮
選項與參數:
-c :建立打包檔案,可搭配 -v 來察看過程中被打包的檔名(filename)
-t :察看打包檔案的內容含有哪些檔名,重點在察看『檔名』就是了;
-x :解打包或解壓縮的功能,可以搭配 -C (大寫) 在特定目錄解開
特別留意的是, -c, -t, -x 不可同時出現在一串指令列中。
-z :透過 gzip 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.gz
-j :透過 bzip2 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.bz2
-J :透過 xz 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.xz
特別留意, -z, -j, -J 不可以同時出現在一串指令列中
-v :在壓縮/解壓縮的過程中,將正在處理的檔名顯示出來!
-f filename:-f 後面要立刻接要被處理的檔名!建議 -f 單獨寫一個選項囉!(比較不會忘記)
-C 目錄 :這個選項用在解壓縮,若要在特定目錄解壓縮,可以使用這個選項。
其他後續練習會使用到的選項介紹:
-p(小寫) :保留備份資料的原本權限與屬性,常用於備份(-c)重要的設定檔
-P(大寫) :保留絕對路徑,亦即允許備份資料中含有根目錄存在之意;
--exclude=FILE:在壓縮的過程中,不要將 FILE 打包!
|
其實最簡單的使用 tar 就只要記憶底下的方式即可:
- 壓 縮:tar -jcv -f filename.tar.bz2 要被壓縮的檔案或目錄名稱
- 查 詢:tar -jtv -f filename.tar.bz2
- 解壓縮:tar -jxv -f filename.tar.bz2 -C 欲解壓縮的目錄
The downloaded GZip’d TAR archive can be extracted with the command tar -xvzf 文件名
- rm (移除檔案或目錄)
[root@study ~]# rm [-fir] 檔案或目錄
選項與參數:
-f :就是 force 的意思,忽略不存在的檔案,不會出現警告訊息;
-i :互動模式,在刪除前會詢問使用者是否動作
-r :遞迴刪除啊!最常用在目錄的刪除了!這是非常危險的選項!!!
範例一:將剛剛在 cp 的範例中建立的 bashrc 刪除掉!
[root@study ~]# cd /tmp
[root@study tmp]# rm -i bashrc
rm: remove regular file `bashrc'? y
# 如果加上 -i 的選項就會主動詢問喔,避免你刪除到錯誤的檔名!
範例二:透過萬用字元*的幫忙,將/tmp底下開頭為bashrc的檔名通通刪除:
[root@study tmp]# rm -i bashrc*
# 注意那個星號,代表的是 0 到無窮多個任意字元喔!很好用的東西!
範例三:將 cp 範例中所建立的 /tmp/etc/ 這個目錄刪除掉!
[root@study tmp]# rmdir /tmp/etc
rmdir: failed to remove '/tmp/etc': Directory not empty <== 刪不掉啊!因為這不是空的目錄!
[root@study tmp]# rm -r /tmp/etc
rm: descend into directory `/tmp/etc'? y
rm: remove regular file `/tmp/etc/fstab'? y
rm: remove regular empty file `/tmp/etc/crypttab'? ^C <== 按下 [ctrl]+c 中斷
.....(中間省略).....
# 因為身份是 root ,預設已經加入了 -i 的選項,所以你要一直按 y 才會刪除!
# 如果不想要繼續按 y ,可以按下『 [ctrl]-c 』來結束 rm 的工作。
# 這是一種保護的動作,如果確定要刪除掉此目錄而不要詢問,可以這樣做:
[root@study tmp]#
m -r /tmp/etc
# 在指令前加上反斜線,可以忽略掉 alias 的指定選項喔!至於 alias 我們在bash再談!
# 拜託!這個範例很可怕!你不要刪錯了!刪除 /etc 系統是會掛掉的!
範例四:刪除一個帶有 - 開頭的檔案
[root@study tmp]# touch ./-aaa- <==touch這個指令可以建立空檔案!
[root@study tmp]# ls -l
-rw-r--r--. 1 root root 0 Jun 11 19:22 -aaa- <==檔案大小為0,所以是空檔案
[root@study tmp]# rm -aaa-
rm: invalid option -- 'a' <== 因為 "-" 是選項嘛!所以系統誤判了!
Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有給建議的
Try 'rm --help' for more information.
[root@study tmp]# rm ./-aaa-
|
rm -rf 文件名
- df
[root@study ~]# df [-ahikHTm] [目錄或檔名]
選項與參數:
-a :列出所有的檔案系統,包括系統特有的 /proc 等檔案系統;
-k :以 KBytes 的容量顯示各檔案系統;
-m :以 MBytes 的容量顯示各檔案系統;
-h :以人們較易閱讀的 GBytes, MBytes, KBytes 等格式自行顯示;
-H :以 M=1000K 取代 M=1024K 的進位方式;
-T :連同該 partition 的 filesystem 名稱 (例如 xfs) 也列出;
-i :不用磁碟容量,而以 inode 的數量來顯示
範例一:將系統內所有的 filesystem 列出來!
[root@study ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 10475520 3409408 7066112 33% /
devtmpfs 627700 0 627700 0% /dev
tmpfs 637568 80 637488 1% /dev/shm
tmpfs 637568 24684 612884 4% /run
tmpfs 637568 0 637568 0% /sys/fs/cgroup
/dev/mapper/centos-home 5232640 67720 5164920 2% /home
/dev/vda2 1038336 133704 904632 13% /boot
# 在 Linux 底下如果 df 沒有加任何選項,那麼預設會將系統內所有的
# (不含特殊記憶體內的檔案系統與 swap) 都以 1 Kbytes 的容量來列出來!
# 至於那個 /dev/shm 是與記憶體有關的掛載,先不要理他!
|
- lsblk 列出系統上的所有磁碟列表
lsblk 可以看成『 list block device 』的縮寫,就是列出所有儲存裝置的意思!這個工具軟體真的很好用喔!來瞧一瞧!
[root@study ~]# lsblk [-dfimpt] [device]
選項與參數:
-d :僅列出磁碟本身,並不會列出該磁碟的分割資料
-f :同時列出該磁碟內的檔案系統名稱
-i :使用 ASCII 的線段輸出,不要使用複雜的編碼 (再某些環境下很有用)
-m :同時輸出該裝置在 /dev 底下的權限資料 (rwx 的資料)
-p :列出該裝置的完整檔名!而不是僅列出最後的名字而已。
-t :列出該磁碟裝置的詳細資料,包括磁碟佇列機制、預讀寫的資料量大小等
範例一:列出本系統下的所有磁碟與磁碟內的分割資訊
[root@study ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 40G 0 disk # 一整顆磁碟
|-vda1 252:1 0 2M 0 part
|-vda2 252:2 0 1G 0 part /boot
`-vda3 252:3 0 30G 0 part
|-centos-root 253:0 0 10G 0 lvm / # 在 vda3 內的其他檔案系統
|-centos-swap 253:1 0 1G 0 lvm [SWAP]
`-centos-home 253:2 0 5G 0 lvm /home
|
- blkid 列出裝置的 UUID 等參數
雖然 lsblk 已經可以使用 -f 來列出檔案系統與裝置的 UUID 資料,不過,鳥哥還是比較習慣直接使用 blkid 來找出裝置的 UUID 喔! 什麼是 UUID 呢?UUID 是全域單一識別碼 (universally unique identifier),Linux 會將系統內所有的裝置都給予一個獨一無二的識別碼, 這個識別碼就可以拿來作為掛載或者是使用這個裝置/檔案系統之用了。
[root@study ~]# blkid
/dev/vda2: UUID="94ac5f77-cb8a-495e-a65b-2ef7442b837c" TYPE="xfs"
/dev/vda3: UUID="WStYq1-P93d-oShM-JNe3-KeDl-bBf6-RSmfae" TYPE="LVM2_member"
/dev/sda1: UUID="35BC-6D6B" TYPE="vfat"
/dev/mapper/centos-root: UUID="299bdc5b-de6d-486a-a0d2-375402aaab27" TYPE="xfs"
/dev/mapper/centos-swap: UUID="905dc471-6c10-4108-b376-a802edbd862d" TYPE="swap"
/dev/mapper/centos-home: UUID="29979bf1-4a28-48e0-be4a-66329bf727d9" TYPE="xfs"
|
复制目录
範例三:複製 /etc/ 這個目錄下的所有內容到 /tmp 底下
[root@study tmp]# cp /etc/ /tmp
cp: omitting directory `/etc' <== 如果是目錄則不能直接複製,要加上 -r 的選項
[root@study tmp]# cp -r /etc/ /tmp
# 還是要再次的強調喔! -r 是可以複製目錄,但是,檔案與目錄的權限可能會被改變
# 所以,也可以利用『 cp -a /etc /tmp 』來下達指令喔!尤其是在備份的情況下!
|
10.1.4 Bash shell 的功能
- 命令編修能力 (history):
而在很多 distribution 裡頭,預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令幾乎都被記錄下來了。
這麼多的指令記錄在哪裡呢?在你的家目錄內的 .bash_history 啦! 不過,需要留意的是,~/.bash_history 記錄的是前一次登入以前所執行過的指令, 而至於這一次登入所執行的指令都被暫存在記憶體中,當你成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!
如果被駭客入侵了,那麼他只要翻你曾經執行過的指令, 剛好你的指令又跟系統有關 (例如直接輸入 MySQL 的密碼在指令列上面),那你的伺服器可就傷腦筋了! 到底記錄指令的數目越多還是越少越好?這部份是見仁見智啦,沒有一定的答案的。
- 影響 bash 環境操作的變數
這些環境變數例如 PATH、HOME、MAIL、SHELL 等等,都是很重要的, 為了區別與自訂變數的不同,環境變數通常以大寫字元來表示呢!
- 變數的設定規則
- 變數與變數內容以一個等號『=』來連結,如下所示:
『myname=VBird』 - 等號兩邊不能直接接空白字元,如下所示為錯誤:
『myname = VBird』或『myname=VBird Tsai』 - 變數名稱只能是英文字母與數字,但是開頭字元不能是數字,如下為錯誤:
『2myname=VBird』 - 變數內容若有空白字元可使用雙引號『"』或單引號『'』將變數內容結合起來,但
- 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
『var="lang is $LANG"』則『echo $var』可得『lang is zh_TW.UTF-8』 - 單引號內的特殊字元則僅為一般字元 (純文字),如下所示:
『var='lang is $LANG'』則『echo $var』可得『lang is $LANG』
- 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
- 可用跳脫字元『 』將特殊符號(如 [Enter], $, \, 空白字元, '等)變成一般字元,如:
『myname=VBird Tsai』 - 在一串指令的執行中,還需要藉由其他額外的指令所提供的資訊時,可以使用反單引號『`指令`』或 『$(指令)』。特別注意,那個 ` 是鍵盤上方的數字鍵 1 左邊那個按鍵,而不是單引號! 例如想要取得核心版本的設定:
『version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64』 - 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』 - 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數:
『export PATH』 - 通常大寫字元為系統預設變數,自行設定變數可以使用小寫字元,方便判斷 (純粹依照使用者興趣與嗜好) ;
- 取消變數的方法為使用 unset :『unset 變數名稱』例如取消 myname 的設定:
『unset myname』 -
10.2.3 環境變數的功能
- 用 env 觀察環境變數與常見環境變數說明
- 想要知道我們的 shell 的 PID ,就可以用:『 echo $$ 』即可!出現的數字就是你的 PID 號碼。
-
10.2.7 與檔案系統及程序的限制關係: ulimit
- bash 是可以『限制使用者的某些系統資源』的,包括可以開啟的檔案數量, 可以使用的 CPU 時間,可以使用的記憶體總量等等。如何設定?用 ulimit 吧
[dmtsai@study ~]$ ulimit [-SHacdfltu] [配額] 選項與參數: -H :hard limit ,嚴格的設定,必定不能超過這個設定的數值; -S :soft limit ,警告的設定,可以超過這個設定值,但是若超過則有警告訊息。 在設定上,通常 soft 會比 hard 小,舉例來說,soft 可設定為 80 而 hard 設定為 100,那麼你可以使用到 90 (因為沒有超過 100),但介於 80~100 之間時, 系統會有警告訊息通知你! -a :後面不接任何選項與參數,可列出所有的限制額度; -c :當某些程式發生錯誤時,系統可能會將該程式在記憶體中的資訊寫成檔案(除錯用), 這種檔案就被稱為核心檔案(core file)。此為限制每個核心檔案的最大容量。 -f :此 shell 可以建立的最大檔案容量(一般可能設定為 2GB)單位為 Kbytes -d :程序可使用的最大斷裂記憶體(segment)容量; -l :可用於鎖定 (lock) 的記憶體量 -t :可使用的最大 CPU 時間 (單位為秒) -u :單一使用者可以使用的最大程序(process)數量。 範例一:列出你目前身份(假設為一般帳號)的所有限制資料數值 [dmtsai@study ~]$ ulimit -a core file size (blocks, -c) 0 <==只要是 0 就代表沒限制 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited <==可建立的單一檔案的大小 pending signals (-i) 4903 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 <==同時可開啟的檔案數量 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 4096 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 範例二:限制使用者僅能建立 10MBytes 以下的容量的檔案 [dmtsai@study ~]$ ulimit -f 10240 [dmtsai@study ~]$ ulimit -a | grep 'file size' core file size (blocks, -c) 0 file size (blocks, -f) 10240 <==最大量為10240Kbyes,相當10Mbytes [dmtsai@study ~]$ dd if=/dev/zero of=123 bs=1M count=20 File size limit exceeded (core dumped) <==嘗試建立 20MB 的檔案,結果失敗了! [dmtsai@study ~]$ rm 123 <==趕快將這個檔案刪除囉!同時你得要登出再次的登入才能解開 10M 的限制
13.5.5 其他相關檔案
- limits.conf
我們在第十章談到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 設定檔之外,其實系統管理員可以統一藉由 PAM 來管理的! 那就是 /etc/security/limits.conf 這個檔案的設定了。這個檔案的設定很簡單,你可以自行參考一下該檔案內容。 我們這裡僅作個簡單的介紹:
範例一:vbird1 這個用戶只能建立 100MB 的檔案,且大於 90MB 會警告
[root@study ~]# vim /etc/security/limits.conf
vbird1 soft fsize 90000
vbird1 hard fsize 100000
#帳號 限制依據 限制項目 限制值
# 第一欄位為帳號,或者是群組!若為群組則前面需要加上 @ ,例如 @projecta
# 第二欄位為限制的依據,是嚴格(hard),還是僅為警告(soft);
# 第三欄位為相關限制,此例中限制檔案容量,
# 第四欄位為限制的值,在此例中單位為 KB。
# 若以 vbird1 登入後,進行如下的操作則會有相關的限制出現!
[vbird1@study ~]$ ulimit -a
....(前面省略)....
file size (blocks, -f) 90000
....(後面省略)....
[vbird1@study ~]$ dd if=/dev/zero of=test bs=1M count=110
File size limit exceeded
[vbird1@study ~]$ ll --block-size=K test
-rw-rw-r--. 1 vbird1 vbird1 90000K Jul 22 01:33 test
# 果然有限制到了
範例二:限制 pro1 這個群組,每次僅能有一個使用者登入系統 (maxlogins)
[root@study ~]# vim /etc/security/limits.conf
@pro1 hard maxlogins 1
# 如果要使用群組功能的話,這個功能似乎對初始群組才有效喔!而如果你嘗試多個 pro1 的登入時,
# 第二個以後就無法登入了。而且在 /var/log/secure 檔案中還會出現如下的資訊:
# pam_limits(login:session): Too many logins (max 1) for pro1
|
10.3.2 歷史命令:history
[dmtsai@study ~]$ history [n] [dmtsai@study ~]$ history [-c] [dmtsai@study ~]$ history [-raw] histfiles 選項與參數: n :數字,意思是『要列出最近的 n 筆命令列表』的意思! -c :將目前的 shell 中的所有 history 內容全部消除 -a :將目前新增的 history 指令新增入 histfiles 中,若沒有加 histfiles , 則預設寫入 ~/.bash_history -r :將 histfiles 的內容讀到目前這個 shell 的 history 記憶中; -w :將目前的 history 記憶內容寫入 histfiles 中!
- source :讀入環境設定檔的指令
[dmtsai@study ~]$ source 設定檔檔名 範例:將家目錄的 ~/.bashrc 的設定讀入目前的 bash 環境中 [dmtsai@study ~]$ source ~/.bashrc <==底下這兩個指令是一樣的! [dmtsai@study ~]$ . ~/.bashrc
利用 source 或小數點 (.) 都可以將設定檔的內容讀進來目前的 shell 環境中! 舉例來說,我修改了 ~/.bashrc ,那麼不需要登出,立即以 source ~/.bashrc 就可以將剛剛最新設定的內容讀進來目前的環境中!
我們將 bash 預設的組合鍵給他彙整如下:
組合按鍵 | 執行結果 |
Ctrl + C | 終止目前的命令 |
Ctrl + D | 輸入結束 (EOF),例如郵件結束的時候; |
Ctrl + M | 就是 Enter 啦! |
Ctrl + S | 暫停螢幕的輸出 |
Ctrl + Q | 恢復螢幕的輸出 |
Ctrl + U | 在提示字元下,將整列命令刪除 |
Ctrl + Z | 『暫停』目前的命令 |
12.2.2 script 的執行方式差異 (source, sh script, ./script)
source 對 script 的執行方式可以使用底下的圖示來說明! showname.sh 會在父程序中執行的,因此各項動作都會在原本的 bash 內生效!這也是為啥你不登出系統而要讓某些寫入 ~/.bashrc 的設定生效時,需要使用『 source ~/.bashrc 』而不能使用『 bash ~/.bashrc 』是一樣的啊!
12.3.3 Shell script 的預設變數($0, $1...)
- $# :代表後接的參數『個數』,以上表為例這裡顯示為『 4 』;
- "$@" :代表『 "$1" "$2" "$3" "$4" 』之意,每個變數是獨立的(用雙引號括起來);
- "$*" :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字元,預設為空白鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
12.4.3 利用 function 功能
另外, function 也是擁有內建變數的~他的內建變數與 shell script 很類似, 函數名稱代表示 $0 ,而後續接的變數也是以 $1, $2... 來取代的~ 這裡很容易搞錯喔~因為『 function fname() { 程式段 } 』內的 $0, $1... 等等與 shell script 的 $0 是不同的。以上面 show123-2.sh 來說,假如我下達:『 sh show123-2.sh one 』 這表示在 shell script 內的 $1 為 "one" 這個字串。但是在 printit() 內的 $1 則與這個 one 無關。 我們將上面的例子再次的改寫一下,讓你更清楚!
10.5.1 什麼是資料流重導向
再想像一下,如果我要將正確與錯誤資料通通寫入同一個檔案去呢?這個時候就得要使用特殊的寫法了! 我們同樣用底下的案例來說明:
範例五:將指令的資料全部寫入名為 list 的檔案中
[dmtsai@study ~]$ find /home -name .bashrc > list 2> list <==錯誤
[dmtsai@study ~]$ find /home -name .bashrc > list 2>&1 <==正確
[dmtsai@study ~]$ find /home -name .bashrc &> list <==正確
|
2.6 shell script 的追蹤與 debug
[dmtsai@study ~]$ sh [-nvx] scripts.sh 選項與參數: -n :不要執行 script,僅查詢語法的問題; -v :再執行 sccript 前,先將 scripts 的內容輸出到螢幕上; -x :將使用到的 script 內容顯示到螢幕上,這是很有用的參數! 範例一:測試 dir_perm.sh 有無語法的問題? [dmtsai@study ~]$ sh -n dir_perm.sh # 若語法沒有問題,則不會顯示任何資訊! 範例二:將 show_animal.sh 的執行過程全部列出來~
/etc/init.d 许多内建脚本
------------恢复内容开始------------
摘自鸟站
http://linux.vbird.org/
创建目录
第六章、Linux 檔案與目錄管理
- 6.1.2 目錄的相關操作: cd, pwd, mkdir, rmdir
- mkdir (建立新目錄)
[root@study ~]# mkdir [-mp] 目錄名稱 選項與參數: -m :設定檔案的權限喔!直接設定,不需要看預設權限 (umask) 的臉色~ -p :幫助你直接將所需要的目錄(包含上層目錄)遞迴建立起來! 範例:請到/tmp底下嘗試建立數個新目錄看看: [root@study ~]# cd /tmp [root@study tmp]# mkdir test <==建立一名為 test 的新目錄 [root@study tmp]# mkdir test1/test2/test3/test4 mkdir: cannot create directory ‘test1/test2/test3/test4’: No such file or directory # 話說,系統告訴我們,沒可能建立這個目錄啊!就是沒有目錄才要建立的!見鬼嘛? [root@study tmp]# mkdir -p test1/test2/test3/test4 # 原來是要建 test4 上層沒先建 test3 之故!加了這個 -p 的選項,可以自行幫你建立多層目錄! 範例:建立權限為rwx--x--x的目錄 [root@study tmp]# mkdir -m 711 test2 [root@study tmp]# ls -ld test* drwxr-xr-x. 2 root root 6 Jun 4 19:03 test drwxr-xr-x. 3 root root 18 Jun 4 19:04 test1 drwx--x--x. 2 root root 6 Jun 4 19:05 test2 # 仔細看上面的權限部分,如果沒有加上 -m 來強制設定屬性,系統會使用預設屬性。 # 那麼你的預設屬性為何?這要透過底下介紹的 umask 才能瞭解喔! ^_^
复制档案或目录
- 6.2.2 複製、刪除與移動: cp, rm, mv
- cp (複製檔案或目錄)
[root@study ~]# cp [-adfilprsu] 來源檔(source) 目標檔(destination)
[root@study ~]# cp [options] source1 source2 source3 .... directory
選項與參數:
-a :相當於 -dr --preserve=all 的意思,至於 dr 請參考下列說明;(常用)
-d :若來源檔為連結檔的屬性(link file),則複製連結檔屬性而非檔案本身;
-f :為強制(force)的意思,若目標檔案已經存在且無法開啟,則移除後再嘗試一次;
-i :若目標檔(destination)已經存在時,在覆蓋時會先詢問動作的進行(常用)
-l :進行硬式連結(hard link)的連結檔建立,而非複製檔案本身;
-p :連同檔案的屬性(權限、用戶、時間)一起複製過去,而非使用預設屬性(備份常用);
-r :遞迴持續複製,用於目錄的複製行為;(常用)
-s :複製成為符號連結檔 (symbolic link),亦即『捷徑』檔案;
-u :destination 比 source 舊才更新 destination,或 destination 不存在的情況下才複製。
--preserve=all :除了 -p 的權限相關參數外,還加入 SELinux 的屬性, links, xattr 等也複製了。
最後需要注意的,如果來源檔有兩個以上,則最後一個目的檔一定要是『目錄』才行!
|
tar
8.3.1 tar
tar 的選項與參數非常的多!我們只講幾個常用的選項,更多選項您可以自行 man tar 查詢囉!
[dmtsai@study ~]$ tar [-z|-j|-J] [cv] [-f 待建立的新檔名] filename... <==打包與壓縮
[dmtsai@study ~]$ tar [-z|-j|-J] [tv] [-f 既有的 tar檔名] <==察看檔名
[dmtsai@study ~]$ tar [-z|-j|-J] [xv] [-f 既有的 tar檔名] [-C 目錄] <==解壓縮
選項與參數:
-c :建立打包檔案,可搭配 -v 來察看過程中被打包的檔名(filename)
-t :察看打包檔案的內容含有哪些檔名,重點在察看『檔名』就是了;
-x :解打包或解壓縮的功能,可以搭配 -C (大寫) 在特定目錄解開
特別留意的是, -c, -t, -x 不可同時出現在一串指令列中。
-z :透過 gzip 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.gz
-j :透過 bzip2 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.bz2
-J :透過 xz 的支援進行壓縮/解壓縮:此時檔名最好為 *.tar.xz
特別留意, -z, -j, -J 不可以同時出現在一串指令列中
-v :在壓縮/解壓縮的過程中,將正在處理的檔名顯示出來!
-f filename:-f 後面要立刻接要被處理的檔名!建議 -f 單獨寫一個選項囉!(比較不會忘記)
-C 目錄 :這個選項用在解壓縮,若要在特定目錄解壓縮,可以使用這個選項。
其他後續練習會使用到的選項介紹:
-p(小寫) :保留備份資料的原本權限與屬性,常用於備份(-c)重要的設定檔
-P(大寫) :保留絕對路徑,亦即允許備份資料中含有根目錄存在之意;
--exclude=FILE:在壓縮的過程中,不要將 FILE 打包!
|
其實最簡單的使用 tar 就只要記憶底下的方式即可:
- 壓 縮:tar -jcv -f filename.tar.bz2 要被壓縮的檔案或目錄名稱
- 查 詢:tar -jtv -f filename.tar.bz2
- 解壓縮:tar -jxv -f filename.tar.bz2 -C 欲解壓縮的目錄
The downloaded GZip’d TAR archive can be extracted with the command tar -xvzf 文件名
- rm (移除檔案或目錄)
[root@study ~]# rm [-fir] 檔案或目錄
選項與參數:
-f :就是 force 的意思,忽略不存在的檔案,不會出現警告訊息;
-i :互動模式,在刪除前會詢問使用者是否動作
-r :遞迴刪除啊!最常用在目錄的刪除了!這是非常危險的選項!!!
範例一:將剛剛在 cp 的範例中建立的 bashrc 刪除掉!
[root@study ~]# cd /tmp
[root@study tmp]# rm -i bashrc
rm: remove regular file `bashrc'? y
# 如果加上 -i 的選項就會主動詢問喔,避免你刪除到錯誤的檔名!
範例二:透過萬用字元*的幫忙,將/tmp底下開頭為bashrc的檔名通通刪除:
[root@study tmp]# rm -i bashrc*
# 注意那個星號,代表的是 0 到無窮多個任意字元喔!很好用的東西!
範例三:將 cp 範例中所建立的 /tmp/etc/ 這個目錄刪除掉!
[root@study tmp]# rmdir /tmp/etc
rmdir: failed to remove '/tmp/etc': Directory not empty <== 刪不掉啊!因為這不是空的目錄!
[root@study tmp]# rm -r /tmp/etc
rm: descend into directory `/tmp/etc'? y
rm: remove regular file `/tmp/etc/fstab'? y
rm: remove regular empty file `/tmp/etc/crypttab'? ^C <== 按下 [ctrl]+c 中斷
.....(中間省略).....
# 因為身份是 root ,預設已經加入了 -i 的選項,所以你要一直按 y 才會刪除!
# 如果不想要繼續按 y ,可以按下『 [ctrl]-c 』來結束 rm 的工作。
# 這是一種保護的動作,如果確定要刪除掉此目錄而不要詢問,可以這樣做:
[root@study tmp]#
m -r /tmp/etc
# 在指令前加上反斜線,可以忽略掉 alias 的指定選項喔!至於 alias 我們在bash再談!
# 拜託!這個範例很可怕!你不要刪錯了!刪除 /etc 系統是會掛掉的!
範例四:刪除一個帶有 - 開頭的檔案
[root@study tmp]# touch ./-aaa- <==touch這個指令可以建立空檔案!
[root@study tmp]# ls -l
-rw-r--r--. 1 root root 0 Jun 11 19:22 -aaa- <==檔案大小為0,所以是空檔案
[root@study tmp]# rm -aaa-
rm: invalid option -- 'a' <== 因為 "-" 是選項嘛!所以系統誤判了!
Try 'rm ./-aaa-' to remove the file `-aaa-'. <== 新的 bash 有給建議的
Try 'rm --help' for more information.
[root@study tmp]# rm ./-aaa-
|
rm -rf 文件名
- df
[root@study ~]# df [-ahikHTm] [目錄或檔名]
選項與參數:
-a :列出所有的檔案系統,包括系統特有的 /proc 等檔案系統;
-k :以 KBytes 的容量顯示各檔案系統;
-m :以 MBytes 的容量顯示各檔案系統;
-h :以人們較易閱讀的 GBytes, MBytes, KBytes 等格式自行顯示;
-H :以 M=1000K 取代 M=1024K 的進位方式;
-T :連同該 partition 的 filesystem 名稱 (例如 xfs) 也列出;
-i :不用磁碟容量,而以 inode 的數量來顯示
範例一:將系統內所有的 filesystem 列出來!
[root@study ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 10475520 3409408 7066112 33% /
devtmpfs 627700 0 627700 0% /dev
tmpfs 637568 80 637488 1% /dev/shm
tmpfs 637568 24684 612884 4% /run
tmpfs 637568 0 637568 0% /sys/fs/cgroup
/dev/mapper/centos-home 5232640 67720 5164920 2% /home
/dev/vda2 1038336 133704 904632 13% /boot
# 在 Linux 底下如果 df 沒有加任何選項,那麼預設會將系統內所有的
# (不含特殊記憶體內的檔案系統與 swap) 都以 1 Kbytes 的容量來列出來!
# 至於那個 /dev/shm 是與記憶體有關的掛載,先不要理他!
|
- lsblk 列出系統上的所有磁碟列表
lsblk 可以看成『 list block device 』的縮寫,就是列出所有儲存裝置的意思!這個工具軟體真的很好用喔!來瞧一瞧!
[root@study ~]# lsblk [-dfimpt] [device]
選項與參數:
-d :僅列出磁碟本身,並不會列出該磁碟的分割資料
-f :同時列出該磁碟內的檔案系統名稱
-i :使用 ASCII 的線段輸出,不要使用複雜的編碼 (再某些環境下很有用)
-m :同時輸出該裝置在 /dev 底下的權限資料 (rwx 的資料)
-p :列出該裝置的完整檔名!而不是僅列出最後的名字而已。
-t :列出該磁碟裝置的詳細資料,包括磁碟佇列機制、預讀寫的資料量大小等
範例一:列出本系統下的所有磁碟與磁碟內的分割資訊
[root@study ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 40G 0 disk # 一整顆磁碟
|-vda1 252:1 0 2M 0 part
|-vda2 252:2 0 1G 0 part /boot
`-vda3 252:3 0 30G 0 part
|-centos-root 253:0 0 10G 0 lvm / # 在 vda3 內的其他檔案系統
|-centos-swap 253:1 0 1G 0 lvm [SWAP]
`-centos-home 253:2 0 5G 0 lvm /home
|
- blkid 列出裝置的 UUID 等參數
雖然 lsblk 已經可以使用 -f 來列出檔案系統與裝置的 UUID 資料,不過,鳥哥還是比較習慣直接使用 blkid 來找出裝置的 UUID 喔! 什麼是 UUID 呢?UUID 是全域單一識別碼 (universally unique identifier),Linux 會將系統內所有的裝置都給予一個獨一無二的識別碼, 這個識別碼就可以拿來作為掛載或者是使用這個裝置/檔案系統之用了。
[root@study ~]# blkid
/dev/vda2: UUID="94ac5f77-cb8a-495e-a65b-2ef7442b837c" TYPE="xfs"
/dev/vda3: UUID="WStYq1-P93d-oShM-JNe3-KeDl-bBf6-RSmfae" TYPE="LVM2_member"
/dev/sda1: UUID="35BC-6D6B" TYPE="vfat"
/dev/mapper/centos-root: UUID="299bdc5b-de6d-486a-a0d2-375402aaab27" TYPE="xfs"
/dev/mapper/centos-swap: UUID="905dc471-6c10-4108-b376-a802edbd862d" TYPE="swap"
/dev/mapper/centos-home: UUID="29979bf1-4a28-48e0-be4a-66329bf727d9" TYPE="xfs"
|
复制目录
範例三:複製 /etc/ 這個目錄下的所有內容到 /tmp 底下
[root@study tmp]# cp /etc/ /tmp
cp: omitting directory `/etc' <== 如果是目錄則不能直接複製,要加上 -r 的選項
[root@study tmp]# cp -r /etc/ /tmp
# 還是要再次的強調喔! -r 是可以複製目錄,但是,檔案與目錄的權限可能會被改變
# 所以,也可以利用『 cp -a /etc /tmp 』來下達指令喔!尤其是在備份的情況下!
|
10.1.4 Bash shell 的功能
- 命令編修能力 (history):
而在很多 distribution 裡頭,預設的指令記憶功能可以到達 1000 個!也就是說,你曾經下達過的指令幾乎都被記錄下來了。
這麼多的指令記錄在哪裡呢?在你的家目錄內的 .bash_history 啦! 不過,需要留意的是,~/.bash_history 記錄的是前一次登入以前所執行過的指令, 而至於這一次登入所執行的指令都被暫存在記憶體中,當你成功的登出系統後,該指令記憶才會記錄到 .bash_history 當中!
如果被駭客入侵了,那麼他只要翻你曾經執行過的指令, 剛好你的指令又跟系統有關 (例如直接輸入 MySQL 的密碼在指令列上面),那你的伺服器可就傷腦筋了! 到底記錄指令的數目越多還是越少越好?這部份是見仁見智啦,沒有一定的答案的。
- 影響 bash 環境操作的變數
這些環境變數例如 PATH、HOME、MAIL、SHELL 等等,都是很重要的, 為了區別與自訂變數的不同,環境變數通常以大寫字元來表示呢!
- 變數的設定規則
- 變數與變數內容以一個等號『=』來連結,如下所示:
『myname=VBird』 - 等號兩邊不能直接接空白字元,如下所示為錯誤:
『myname = VBird』或『myname=VBird Tsai』 - 變數名稱只能是英文字母與數字,但是開頭字元不能是數字,如下為錯誤:
『2myname=VBird』 - 變數內容若有空白字元可使用雙引號『"』或單引號『'』將變數內容結合起來,但
- 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
『var="lang is $LANG"』則『echo $var』可得『lang is zh_TW.UTF-8』 - 單引號內的特殊字元則僅為一般字元 (純文字),如下所示:
『var='lang is $LANG'』則『echo $var』可得『lang is $LANG』
- 雙引號內的特殊字元如 $ 等,可以保有原本的特性,如下所示:
- 可用跳脫字元『 』將特殊符號(如 [Enter], $, \, 空白字元, '等)變成一般字元,如:
『myname=VBird Tsai』 - 在一串指令的執行中,還需要藉由其他額外的指令所提供的資訊時,可以使用反單引號『`指令`』或 『$(指令)』。特別注意,那個 ` 是鍵盤上方的數字鍵 1 左邊那個按鍵,而不是單引號! 例如想要取得核心版本的設定:
『version=$(uname -r)』再『echo $version』可得『3.10.0-229.el7.x86_64』 - 若該變數為擴增變數內容時,則可用 "$變數名稱" 或 ${變數} 累加內容,如下所示:
『PATH="$PATH":/home/bin』或『PATH=${PATH}:/home/bin』 - 若該變數需要在其他子程序執行,則需要以 export 來使變數變成環境變數:
『export PATH』 - 通常大寫字元為系統預設變數,自行設定變數可以使用小寫字元,方便判斷 (純粹依照使用者興趣與嗜好) ;
- 取消變數的方法為使用 unset :『unset 變數名稱』例如取消 myname 的設定:
『unset myname』 -
10.2.3 環境變數的功能
- 用 env 觀察環境變數與常見環境變數說明
- 想要知道我們的 shell 的 PID ,就可以用:『 echo $$ 』即可!出現的數字就是你的 PID 號碼。
-
10.2.7 與檔案系統及程序的限制關係: ulimit
- bash 是可以『限制使用者的某些系統資源』的,包括可以開啟的檔案數量, 可以使用的 CPU 時間,可以使用的記憶體總量等等。如何設定?用 ulimit 吧
[dmtsai@study ~]$ ulimit [-SHacdfltu] [配額] 選項與參數: -H :hard limit ,嚴格的設定,必定不能超過這個設定的數值; -S :soft limit ,警告的設定,可以超過這個設定值,但是若超過則有警告訊息。 在設定上,通常 soft 會比 hard 小,舉例來說,soft 可設定為 80 而 hard 設定為 100,那麼你可以使用到 90 (因為沒有超過 100),但介於 80~100 之間時, 系統會有警告訊息通知你! -a :後面不接任何選項與參數,可列出所有的限制額度; -c :當某些程式發生錯誤時,系統可能會將該程式在記憶體中的資訊寫成檔案(除錯用), 這種檔案就被稱為核心檔案(core file)。此為限制每個核心檔案的最大容量。 -f :此 shell 可以建立的最大檔案容量(一般可能設定為 2GB)單位為 Kbytes -d :程序可使用的最大斷裂記憶體(segment)容量; -l :可用於鎖定 (lock) 的記憶體量 -t :可使用的最大 CPU 時間 (單位為秒) -u :單一使用者可以使用的最大程序(process)數量。 範例一:列出你目前身份(假設為一般帳號)的所有限制資料數值 [dmtsai@study ~]$ ulimit -a core file size (blocks, -c) 0 <==只要是 0 就代表沒限制 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited <==可建立的單一檔案的大小 pending signals (-i) 4903 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 <==同時可開啟的檔案數量 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 4096 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 範例二:限制使用者僅能建立 10MBytes 以下的容量的檔案 [dmtsai@study ~]$ ulimit -f 10240 [dmtsai@study ~]$ ulimit -a | grep 'file size' core file size (blocks, -c) 0 file size (blocks, -f) 10240 <==最大量為10240Kbyes,相當10Mbytes [dmtsai@study ~]$ dd if=/dev/zero of=123 bs=1M count=20 File size limit exceeded (core dumped) <==嘗試建立 20MB 的檔案,結果失敗了! [dmtsai@study ~]$ rm 123 <==趕快將這個檔案刪除囉!同時你得要登出再次的登入才能解開 10M 的限制
13.5.5 其他相關檔案
- limits.conf
我們在第十章談到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 設定檔之外,其實系統管理員可以統一藉由 PAM 來管理的! 那就是 /etc/security/limits.conf 這個檔案的設定了。這個檔案的設定很簡單,你可以自行參考一下該檔案內容。 我們這裡僅作個簡單的介紹:
範例一:vbird1 這個用戶只能建立 100MB 的檔案,且大於 90MB 會警告
[root@study ~]# vim /etc/security/limits.conf
vbird1 soft fsize 90000
vbird1 hard fsize 100000
#帳號 限制依據 限制項目 限制值
# 第一欄位為帳號,或者是群組!若為群組則前面需要加上 @ ,例如 @projecta
# 第二欄位為限制的依據,是嚴格(hard),還是僅為警告(soft);
# 第三欄位為相關限制,此例中限制檔案容量,
# 第四欄位為限制的值,在此例中單位為 KB。
# 若以 vbird1 登入後,進行如下的操作則會有相關的限制出現!
[vbird1@study ~]$ ulimit -a
....(前面省略)....
file size (blocks, -f) 90000
....(後面省略)....
[vbird1@study ~]$ dd if=/dev/zero of=test bs=1M count=110
File size limit exceeded
[vbird1@study ~]$ ll --block-size=K test
-rw-rw-r--. 1 vbird1 vbird1 90000K Jul 22 01:33 test
# 果然有限制到了
範例二:限制 pro1 這個群組,每次僅能有一個使用者登入系統 (maxlogins)
[root@study ~]# vim /etc/security/limits.conf
@pro1 hard maxlogins 1
# 如果要使用群組功能的話,這個功能似乎對初始群組才有效喔!而如果你嘗試多個 pro1 的登入時,
# 第二個以後就無法登入了。而且在 /var/log/secure 檔案中還會出現如下的資訊:
# pam_limits(login:session): Too many logins (max 1) for pro1
|
10.3.2 歷史命令:history
[dmtsai@study ~]$ history [n] [dmtsai@study ~]$ history [-c] [dmtsai@study ~]$ history [-raw] histfiles 選項與參數: n :數字,意思是『要列出最近的 n 筆命令列表』的意思! -c :將目前的 shell 中的所有 history 內容全部消除 -a :將目前新增的 history 指令新增入 histfiles 中,若沒有加 histfiles , 則預設寫入 ~/.bash_history -r :將 histfiles 的內容讀到目前這個 shell 的 history 記憶中; -w :將目前的 history 記憶內容寫入 histfiles 中!
- source :讀入環境設定檔的指令
[dmtsai@study ~]$ source 設定檔檔名 範例:將家目錄的 ~/.bashrc 的設定讀入目前的 bash 環境中 [dmtsai@study ~]$ source ~/.bashrc <==底下這兩個指令是一樣的! [dmtsai@study ~]$ . ~/.bashrc
利用 source 或小數點 (.) 都可以將設定檔的內容讀進來目前的 shell 環境中! 舉例來說,我修改了 ~/.bashrc ,那麼不需要登出,立即以 source ~/.bashrc 就可以將剛剛最新設定的內容讀進來目前的環境中!
我們將 bash 預設的組合鍵給他彙整如下:
組合按鍵 | 執行結果 |
Ctrl + C | 終止目前的命令 |
Ctrl + D | 輸入結束 (EOF),例如郵件結束的時候; |
Ctrl + M | 就是 Enter 啦! |
Ctrl + S | 暫停螢幕的輸出 |
Ctrl + Q | 恢復螢幕的輸出 |
Ctrl + U | 在提示字元下,將整列命令刪除 |
Ctrl + Z | 『暫停』目前的命令 |
12.2.2 script 的執行方式差異 (source, sh script, ./script)
source 對 script 的執行方式可以使用底下的圖示來說明! showname.sh 會在父程序中執行的,因此各項動作都會在原本的 bash 內生效!這也是為啥你不登出系統而要讓某些寫入 ~/.bashrc 的設定生效時,需要使用『 source ~/.bashrc 』而不能使用『 bash ~/.bashrc 』是一樣的啊!
12.3.3 Shell script 的預設變數($0, $1...)
- $# :代表後接的參數『個數』,以上表為例這裡顯示為『 4 』;
- "$@" :代表『 "$1" "$2" "$3" "$4" 』之意,每個變數是獨立的(用雙引號括起來);
- "$*" :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字元,預設為空白鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
12.4.3 利用 function 功能
另外, function 也是擁有內建變數的~他的內建變數與 shell script 很類似, 函數名稱代表示 $0 ,而後續接的變數也是以 $1, $2... 來取代的~ 這裡很容易搞錯喔~因為『 function fname() { 程式段 } 』內的 $0, $1... 等等與 shell script 的 $0 是不同的。以上面 show123-2.sh 來說,假如我下達:『 sh show123-2.sh one 』 這表示在 shell script 內的 $1 為 "one" 這個字串。但是在 printit() 內的 $1 則與這個 one 無關。 我們將上面的例子再次的改寫一下,讓你更清楚!
10.5.1 什麼是資料流重導向
再想像一下,如果我要將正確與錯誤資料通通寫入同一個檔案去呢?這個時候就得要使用特殊的寫法了! 我們同樣用底下的案例來說明:
範例五:將指令的資料全部寫入名為 list 的檔案中
[dmtsai@study ~]$ find /home -name .bashrc > list 2> list <==錯誤
[dmtsai@study ~]$ find /home -name .bashrc > list 2>&1 <==正確
[dmtsai@study ~]$ find /home -name .bashrc &> list <==正確
|
2.6 shell script 的追蹤與 debug
[dmtsai@study ~]$ sh [-nvx] scripts.sh 選項與參數: -n :不要執行 script,僅查詢語法的問題; -v :再執行 sccript 前,先將 scripts 的內容輸出到螢幕上; -x :將使用到的 script 內容顯示到螢幕上,這是很有用的參數! 範例一:測試 dir_perm.sh 有無語法的問題? [dmtsai@study ~]$ sh -n dir_perm.sh # 若語法沒有問題,則不會顯示任何資訊! 範例二:將 show_animal.sh 的執行過程全部列出來~
/etc/init.d 许多内建脚本
子程序與父程序:
以『 ps -l 』這個指令觀察程序相關的輸出,有看到那個 PID 與 PPID 嗎?第一個 bash 的 PID 與第二個 bash 的 PPID 都是 13928 啊, 因為第二個 bash 是來自於第一個所產生的
那麼 Linux 會有這樣的問題嗎?老實說, Linux 幾乎可以說絕對不會當機的!因為他可以在任何時候, 將某個被困住的程序殺掉,然後再重新執行該程序而不用重新開機!夠炫吧!那麼如果我在 Linux 下以文字界面登入,在螢幕當中顯示錯誤訊息後就掛了~動都不能動,該如何是好!? 這個時候那預設的七個視窗就幫上忙啦!你可以隨意的再按 [Alt]+[F1].....[F7] 來切換到其他的終端機界面,然後以 ps -aux 找出剛剛的錯誤程序,然後給他 kill 一下,哈哈,回到剛剛的終端機界面!恩~棒!又回復正常囉!
- bash 環境下的工作管理 (job control)
[root@study ~]# cp file1 file2 &
|
在這一串指令中,重點在那個 & 的功能,他表示將 file1 這個檔案複製為 file2 ,且放置於背景中執行, 也就是說執行這一個命令之後,在這一個終端介面仍然可以做其他的工作!
16.2 工作管理 (job control) bash下
[root@study ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
如此一來,輸出的資訊都給他傳送到 /tmp/log.txt 當中,當然就不會影響到我們前景的作業了。
- 將『目前』的工作丟到背景中『暫停』:[ctrl]-z
- 觀察目前的背景工作狀態: jobs
[root@study ~]# jobs [-lrs]
選項與參數:
-l :除了列出 job number 與指令串之外,同時列出 PID 的號碼;
-r :僅列出正在背景 run 的工作;
-s :僅列出正在背景當中暫停 (stop) 的工作。
|
- 將背景工作拿到前景來處理:fg
[root@study ~]# fg %jobnumber
選項與參數:
%jobnumber :jobnumber 為工作號碼(數字)。注意,那個 % 是可有可無的!
- 讓工作在背景下的狀態變成運作中: bg
bg %jobnumber
- 管理背景當中的工作: kill
[root@study ~]# kill -signal %jobnumber [root@study ~]# kill -l 選項與參數: -l :這個是 L 的小寫,列出目前 kill 能夠使用的訊號 (signal) 有哪些? signal :代表給予後面接的那個工作什麼樣的指示囉!用 man 7 signal 可知: -1 :重新讀取一次參數的設定檔 (類似 reload); -2 :代表與由鍵盤輸入 [ctrl]-c 同樣的動作; -9 :立刻強制刪除一個工作; -15:以正常的程序方式終止一項工作。與 -9 是不一樣的。
其實, kill 的妙用是很無窮的啦!他搭配 signal 所詳列的資訊 (用 man 7 signal 去查閱相關資料) 可以讓您有效的管理工作與程序 (Process),至於常用的 signal 您至少需要瞭解 1, 9, 15 這三個 signal 的意義才好。
另外, kill 後面接的數字預設會是 PID ,如果想要管理 bash 的工作控制,就得要加上 %數字 了, 這點也得特別留意才行喔!
16.3.1 程序的觀察
既然程序這麼重要,那麼我們如何查閱系統上面正在運作當中的程序呢?很簡單啊! 利用靜態的 ps 或者是動態的 top,還能以 pstree 來查閱程序樹之間的關係喔!
- ps :將某個時間點的程序運作情況擷取下來
[root@study ~]# ps aux <==觀察系統所有的程序資料
[root@study ~]# ps -lA <==也是能夠觀察所有系統的資料
[root@study ~]# ps axjf <==連同部分程序樹狀態
|
如果你發現在某個程序的 CMD 後面還接上 <defunct> 時,就代表該程序是僵屍程序啦,例如:
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct> |