認識與學習Bash [Linux鳥哥 Ch10]

Posted by Kubeguts on 2020-01-28

Bash shell 功能

打過的指令都是記錄在 ./bash_history.

注意駭客可以透過 history 來查看你先前打過指令 ex: MySQL 登入帳戶密碼資訊

alias 取代很長的指定

若不想要每次打這麼長指令,可以用alias 來取代
例如: ls -a 可以透過 alias lm='ls -al'lm來取代

type 查看指令是內部指令或外部指令

像上面例子 lm='ls -al' 的lm 為我們自行定義的外部指令
cd, ls這些則是內部指令

透過 type lm, 可以看到lm 為外部指令

若覺得下的指令太長 可以透過 \

將三個檔案cp到 /root內…並用 \來接續指令

1
2
cp /var/spool/mail/root /etc/crontab \ 
> /etc/fstab /root

取得版本號

uname -r

可用變數將版本號存起來

1
2
3
version=$(uname -r) // 將版本號放到version變數

echo $version

變數設定規則

等號不能有空格

1
myname=VBird

變數內容有空白,可用"" 或 ''包起來

1
var="lang is $LANG"

可用跳脫字元 “” 將特殊符號變成一般字元

變數為擴增變數內容時,可以用$變數名稱 或${變數} 累加內容

1
PATH=$PATH:/home/bin

變數需要在其他子程序執行,需要以 export 來使變數成為環境變數

1
export PATH

什麼是子程序? 在目前的shell情況下,開啟另外一個shell亦即為子程序

取消變數的方法為 unset

$() 被兩個逗號包起來的指令會優先執行

1
2
3
cd /lib/modules/$(uname -r)/kernal

先用 uname -r 取得當前linux kernal版本號,再cd到該版本的目錄

透過 env 可以看到目前設置的環境變數

  • HOME: 家目錄
  • SHELL:目前shell使用的程式,預設是 /bin/bash
  • HISTSIZE: 紀錄歷史指令得數目
  • PATH: 執行黨搜尋的路徑
  • LANG: 語系資料
  • RANDOM: 隨機亂數

RANDOM會產出 0~32767
若想要隨機取出0~9
declare -i number=$RANDOM*10/32768 ; echo $number

透過 set 可以看到所有變數 (環境變數+自定義變數)

透過 PS1 設定 提示字元

ex: PS1='[\u@\h \w \A #\#]\$ '
設定命令提示字元顯示目前輸入幾次指令 !

變數鍵盤的讀取、陣列與宣告: read, array, declare

read: 讀取來自使用者 鍵盤的輸入

ex: 提示使用者30秒內輸入自己的大名,並將大名塞入 $named 變數內

1
2
3
read -p "Please keyin your name: " -t 30 named

echo $named

delcare: 宣告變數的類型

1
2
3
4
5
6
declare [-aixr] variable

-a : 將後面名為variable定義為 array類型
-i : integer
-x : 變成環境變數
-r : 設置成read only

注意:若sum=100+300+200 echo $sum 會得到 "100+300+200"字串,並非是600的結果,需要用 declare -i sum 才能得到integer sum

unlimit 檔案系統與程序的限制關係

限制使用者所使用的系統資源,
包括CPU時間,記憶體數量

1
2
3
4
5
6
7
8
9
ulimit [-SHacdltu] [配額]

-H : hard limit 嚴德的限制,若超過則不能再用
-S : Soft limit 警告的限制,超過只是會警告
-a : 列出目前限制的數量,若不接參數則列出全部
-c : 當某些程式發生錯誤,系統會將該程式在記憶體的資訊寫成檔案 (可除錯用)
-f : 此shell 可以建立的最大檔案容量
-u : 單一使用者可以使用的最大process數量
...

變數的刪除、取代與替換

直接看範例:

刪除

  • \#:從前面開始刪除, 刪除符合取代文字的 『最短的』那一個

  • \##: ....『最長的』

  • \%:從後面開始刪除,…刪除『最短的』

  • \%%: 『最長的』

替換

username=${username-root}
若username為空值,替換成root

若加上: 可以強制替換
username=${username:-root}

加上? 可以判斷是否有無此變數

bash的進站與歡迎訊息 : /etc/issue, /etc/motd

1
cat /etc/issue

bash的環境設定檔

login 與 non-login shell

  • login shell
    取得bash時需要完整輸入登入流程(輸入帳號密碼)

/etc/profile: 系統整體的設定(最好別修改)

~/.bash_profile ~/.bash_login ~/.profile: 屬於使用者個人設定

系統登入shell時,優先載入 /etc/profile

再來才會依序載入使用者設定檔

1
2
3
~/.bash_profile
~/.bash_login
~/.profile

只會讀取上面的一個,由上而下
然而上面三個檔案可能會有包含執行 ~/.bashrc 的內容。。。

1
2
3
4
5
6
7
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then # here is the .bashrc
. "$HOME/.bashrc"
fi
fi
  • non-login shell
    直接打開另外一個終端機(shell),該shell為 non-login shell

在non-login shell內要載入使用者, 得手動 ./bashrc

>, >>, |

> : 取代
>> : 累加

命令執行的判斷依據: ; , && ||

分號 ; : 可以執行連續指令

1
sync; sync; shutdown -h now

$? 、 && 、 || 可以判斷指令是否成功執行

$?:若前一個指令執行的結果正確,在linux底下會回傳一個 $?=0的值

(cmd1 && cmd2):

  • 若cmd1執行完畢且正確執行($?=0),則開始執行 cmd2
  • 若cmd1執行完畢且執行錯誤($? != 0),則不執行 cmd2

(cmd1 || cmd2):

  • 若cmd1執行完畢且正確執行($?=0),則cmd2不執行
  • 若cmd1執行完畢且執行錯誤($? != 0),則開始執行 cmd2

pipe 管線命令: 資料需要經過多個處理手續

1
ls -al /etc | less

透過 | 可以將 /etc 撈出來的資訊給 less解讀

擷取命令: cut, grep

  • cut: 將某一段訊息切割出來
1
echo $PATH | cut -d ':' -f 3,5

列出 PATH中的第3和第5個路徑

  • grep: 過濾出

有符合字元的訊息

排序命令: sort, wc, uniq

sort 可以使語系統一 LANG=C 讓資料排序好一些

1
cat /etc/passwd | sort

uniq: 排序完成 並將重複的資料僅列出一個顯示

1
2
last | cut -d ' ' -f1 | sort | uniq -c
知道每位使用者的登入次數

wc: 知道某個檔案的組成

1
cat /etc/man.config | wc

tee: 雙向重新導向

last | tee last.list | cut -d " " -fi:

這個範例可以讓我們將last 的輸出存一份到last.list 檔案中

last | /home | tee ~/homefile | more:

這個範例是將 ls 的資料存一份到 ~/homefile ,同時螢幕也有輸出訊息

字元轉換命令: tr, col, join, paste, expand

tr: 刪除一段訊息中的文字、或者是進行文字的轉換

col: 經常被用來將 man page 轉存為純文字檔案以方便查閱

1
man col | col -b > /root/col.man

join: 兩個檔案當中,有相同資料的那一行,才將它加在一起

分割命令: split

1
cat termcap* >> termcapback

使用 ls -al / 輸出的資訊中,每十行紀錄變成一個檔案

1
ls -al / | split -l 10 lsroot
1
wc -l lsroot*

參數代換: xargs: 產生某個指令的參數

有些指令不其實並不支援管線命令,因此我們可以透過xarg該指令引用 standard input之用。

減號 -的用途

tar -cvf - /home | tar -xvf -

我將/home裡面的檔案給他打包,但打包的資料不是記錄到檔案,而是傳送到stdout; 經過管線後,將tar -cvf - /home 傳送給後面的tar -xvf -

後面 - 取用前一個指令的stdout, 因此不需要使用file