使用配置文件定製bash
放入配置文件中的常見命令如下:
# 定義ls命令使用的顏色
LS_COLORS='no=00:di=01;46:ln=00;36:pi=40;33:so=00;35:bd=40;33;01'
export LS_COLORS
# 主提示符
PS1='Hello $USER'; export PS1
# 正常路徑之外的個人應用程序安裝目錄
PATH=$PATH:/opt/MySpecialApplication/bin; export PATH 9 # 常用命令的便捷方式
function lc () {/bin/ls -C $* ; }
當用戶登錄shell時,會執行下列文件:
注意,如果你是通過圖形化登錄管理器登入的話,是不會執行/etc/profile、 HOME/.bash_profile這3個文件的。這是因爲圖形化窗口管理器 並不會啓動shell。當你打開終端窗口時纔會創建shell,但這個shell也不是登錄shell。
如果.bash_profile或.bash_login文件存在,則不會去讀取.profile文件。
/etc/profile, $HOME/.profile, $HOME/.bash_login, $HOME/.bash_profile /
交互式shell(如X11終端會話)或ssh執行單條命令(如ssh 192.168.1.1 ls /tmp)時,
會讀取並執行以下文件:
/etc/bash.bashrc $HOME/.bashrc
如果運行如下腳本:
$> cat myscript.sh
#!/bin/bash
echo "Running"
```
不會執行任何配置文件,除非定義了環境變量BASH_ENV:
```bash
$> export BASH_ENV=~/.bashrc
$> ./myscript.sh
使用ssh運行下列命令時:會啓動一個bash shell,讀取並執行/etc/bash.bashrc和$HOME/.bashrc,但不包括/etc/profile或.profile。
ssh 192.168.1.100 ls /tmp
如果調用ssh登錄會話:
ssh 192.168.1.100
這會創建一個新的登錄bash shell,該shell會讀取並執行以下文件:
/etc/profile
/etc/bash.bashrc
$HOME/.profile or .bashrc_profile
危險:像傳統的Bourne shell、ash、dash以及ksh這類shell,也會讀取配置文件。 但是這些shell並不支持線性數組(列表)和關聯數組。因此要避免在/etc/profile或 $HOME/.profile中使用這類不支持的特性。
可以使用這些文件定義所有用戶所需要的非導出項(如別名)。例如:
alias l "ls -l"
/etc/bash.bashrc /etc/bashrc
當用戶登出會話時,會執行下列文件:
$HOME/.bash_logout 5
例如,遠程登錄的用戶需要在登出的時候清屏:
$> cat ~/.bash_logout # 遠程登出之後清屏 Clear
比較與測試
用於比較和測試的各種方法:
if條件
if condition;
then
commands;
fi
else if和else
if condition;
then
commands;
else if condition; then
commands;
else
commands;
fi
面向列表的for循環
for var in list;
do
commands; #使用變量$var
done
list可以是一個字符串,也可以是一個值序列。
我們可以使用echo命令生成各種值序列:
echo {1..50}; #生成一個從1~50的數字序列
echo {a..z} {A..Z}; #生成大小寫字母序列
下面的代碼中,變量i在每次迭代的過程裏都會保存一個範圍在a到z之間的字符: for i in {a..z}; do actions; done;
迭代指定範圍的數字
for((i=0;i<10;i++))
{
commands; #使用變量$i
}
循環到條件滿足爲止
當條件爲真時,while循環繼續執行;當條件不爲真時,until循環繼續執行。
while condition
do
commands;
done
用true作爲循環條件能夠產生無限循環。
until循環
在Bash中還可以使用一個特殊的循環until。它會一直循環,直到給定的條件爲真。例如:
x=0;
until[$x-eq9]; #條件是[$x-eq9] do
let x++; echo $x;
done
將一個命令的輸出發送給另一個命令
(1)先從組合兩個命令開始:
$ ls | cat -n > out.txt
ls(列出當前目錄內容)的輸出被傳給cat -n,後者爲通過stdin所接收到的輸入內容 加上行號,然後將輸出重定向到文件out.txt。
(2)將命令序列的輸出賦給變量:
cmd_output=$(COMMANDS)
這種方法叫作子shell法。例如:
cmd_output=$(ls | cat -n)
echo $cmd_output
另一種方法叫作反引用(有些人也稱它爲反標記),也可以用於存儲命令輸出:
cmd_output=`COMMANDS`
例如:
cmd_output=`ls | cat -n`
echo $cmd_output
在不按下回車鍵的情況下讀入n個字符
(1) 下面的語句從輸入中讀取n個字符並存入變量variable_name:
read -n number_of_chars variable_name
例如:
$ read -n 2 var
$ echo $var
(2) 用無回顯的方式讀取密碼:
read -s var
(3) 使用read顯示提示信息:
read -p "Enter input:" var
(4) 在給定時限內讀取輸入:
read -t timeout var
例如:
$ read -t 2 var #在2秒內將鍵入的字符串讀入變量var
(5) 用特定的定界符作爲輸入行的結束: read -d delim_char var
例如:
$ read -d ":" var
hello: #var被設置爲hello
持續運行命令直至執行成功
定義如下函數:
repeat()
{
while true
do
$@ && return
done
}
或者把它放入shell的rc文件,更便於使用:
repeat() { while true; do $@ && return; done }
加入延時
假設你要用repeat()從Internet上下載一個暫時不可用的文件,不過這個文件只需要等一會
就能下載。一種方法如下:
repeat wget -c http://www.example.com/software-0.1.tar.gz
如果採用這種形式,會產生很多發往www.example.com的流量,有可能會對服務器造成影響。 (可能也會牽連到你自己;如果服務器認爲你是在向其發起攻擊,就會把你的IP地址列入黑名單。)
要解決這個問題,我們可以修改函數,加入一段延時:
repeat() { while :; do $@ && return; sleep 30; done }
這樣命令每30秒纔會運行一次。