一)bash的基礎特性
1)命令歷史
命令:history
環境變量:
* [root@fenfa ~]# echo $HISTSIZE 默認情況,命令歷史記錄的條數
1000
* [root@fenfa ~]# echo $HISTFILE 每一個用戶都有一個獨立的命令歷史文件,該文件在用戶的家目錄下以.bash_history
/root/.bash_history
* [root@fenfa ~]# history -d 751 刪除某一條命令歷史
* [root@fenfa ~]# history -c 清空命令歷史
* [root@fenfa ~]# history # 顯示歷史中最近的#條記錄
* [root@fenfa ~]# history
1 cd /etc/profile.d/
2 ll
3 vim history.sh
[root@fenfa ~]# !1 通過!# 執行某一條命令
cd /etc/profile.d/
[root@fenfa profile.d]# !! 通過!! 指定上一條命令
cd /etc/profile.d/
[root@fenfa ~]# ls -l !$ 通過!$調用上一個命令的參數
ls -l /etc/fstab
-rw-r--r--. 1 root root 779 Aug 14 11:25 /etc/fstab
* 詳細記錄history
[root@fenfa profile.d]# cat history.sh
USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
export HISTTIMEFORMAT="[%F %T][`whoami`][${USER_IP}] "
You have mail in /var/spool/mail/root
[root@fenfa profile.d]# source history.sh
查看
[root@fenfa ~]# history
1 [2018-01-08 11:18:16][root][10.2.18.231] history
* 運行命令不記錄到history
通過環境變量HISTCONTROL
ignoredups 忽略重復的命令
ignorespace 忽略空白開頭的命令
ignoreboth 以上2中都生效
[root@fenfa ~]# echo $HISTCONTROL
ignoredups 默認為忽略重復的命令(該命令為連續且重復的,只會記錄一條)
[root@fenfa ~]# export HISTCONTROL=ignorespace 或者
[root@fenfa ~]# export HISTCONTROL=ignoreboth
[root@fenfa ~]# history -c
[root@fenfa ~]# ls -l /root/
total 80
-rw-------. 1 root root 1127 Aug 14 11:27 anaconda-ks.cfg
[root@fenfa ~]# history
1 [2018-01-08 11:35:44][root][10.2.18.231] history
發現以空格開頭的命令沒有記錄到history中
注意:以上修改只對當前shell及子shell有效
針對所有用戶都生效,修改/etc/profile目錄
if [ "$HISTCONTROL" = "ignoredups" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignorespace
fi
2)命令補全
案例:比如執行clear命令
bash會根據path環境變量中設置好路徑,從左往右依次查找,與命令cle開頭的文件名,當找到了,而且這個是唯一的,就可以按table鍵,直接補全。如果不唯一,連續按2次table鍵,就會以列表的形式顯示出來
案例:比如執行pwd命令,當你輸入pw連續按2次table鍵,如下
[root@fenfa tmp]# pw
pwck pwconv pwd pwdx pwunconv
3)路徑補全
把用戶給出的字符串當作路徑開頭,并在指定上級目錄下搜索以指定的字符串開頭的文件名,如果唯一,則直接補全,如果不唯一,再次按tab,顯示出列表
4)命令行展開
~ 展開用戶的主目錄
~username 展開指定目錄的家目錄
{} 可承載一個以逗號分隔的路徑列表,并將其展開為多個路徑
[root@fenfa tmp]# mkdir -p /tmp/x/{y1,y2}/{a,b}
[root@fenfa tmp]# mkdir -p /tmp/{bin,sbin,usr/{bin,sbin}}
[root@fenfa tmp]# tree /tmp/
/tmp/
├── bin
├── sbin
├── usr
│?? ├── bin
│?? └── sbin
5)命令的執行狀態結果
成功 0
失敗 1-255
bash內部用一個特殊變量$?保存上一個命令(最近一個)的執行結果,其中0表示執行,1-255都表示執行失敗
[root@fenfa tmp]# mkdir /tmp/test2
[root@fenfa tmp]# echo $?
0 --------成功
[root@fenfa tmp]# mkdir /tmp/test2
mkdir: cannot create directory `/tmp/test2': File exists
[root@fenfa tmp]# echo $?
1----------失敗
[root@fenfa tmp]# mkddir /tmp/test2
-bash: mkddir: command not found
[root@fenfa tmp]# echo $?
127---------失敗
5)命令別名
通過alias設置
[root@fenfa ~]# echo "alias cdnet='cd /etc/sysconfig/network-scripts/'" >> /etc/bashrc
You have mail in /var/spool/mail/root
[root@fenfa ~]# source /etc/bashrc
[root@fenfa ~]# alias ----顯示當前shell進程下所有的alias別名
alias cdnet='cd /etc/sysconfig/network-scripts/'
alias cp='cp -i'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
6)bash的快捷鍵
ctrl+a 回到行首
ctrl+e 回到尾部
ctrl+k 刪除光標所在到命令行尾部的所有內容
ctrl+u 刪除光標所在到命令行首部的所有內容
7)bash的IO重定向及管道
讀入數據: input
輸出數據: output
一個程序要讀入數據,需要考慮這個程序是從哪里讀入數據呢?
標準輸入: 鍵盤輸入,0
標準輸出: 顯示器,1
標準錯誤輸出: 顯示器,2
輸出重定向: COMMAND > file 覆蓋重定向
COMMAND >> file 追加重定向
2> 覆蓋重定向的錯誤數據流
2>> 追加重定向錯誤數據流
標準輸出和錯誤輸出各自定向到不同位置:
command >> /path/to/file.out 2>> /path/to/error.out
[root@fenfa tmp]# ls /etc/ > a.out
[root@fenfa tmp]# set -C------》禁止將內容覆蓋輸出到已有文件中
You have mail in /var/spool/mail/root
[root@fenfa tmp]# ls /etc/ > a.out
-bash: a.out: cannot overwrite existing file
[root@fenfa tmp]# tail -100 /etc/rc.d/rc.sysinit > /tmp/sysinit.out 2> /tmp/sysinit.error
You have mail in /var/spool/mail/root
[root@fenfa tmp]# cat /tmp/sysinit.out
# Reread in network configuration data.
if [ -f /etc/sysconfig/network ]; then
. /etc/sysconfig/network
此處生成文檔
[root@fenfa tmp]# cat <<EOF
> 1、install http server
> 2、install php server
> 3、install mysql server
> EOF
1、install http server
2、install php server
3、install mysql server
You have mail in /var/spool/mail/root
[root@fenfa tmp]# cat >> /tmp/test.out <<EOF
1、install http server
2、install php server
3、install mysql server
EOF
管道:
第一個命令的輸出結果當第二個命令的輸入
[root@fenfa tmp]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@fenfa tmp]# echo $PATH | tr 'a-z' 'A-Z'
/USR/LOCAL/SBIN:/USR/LOCAL/BIN:/SBIN:/BIN:/USR/SBIN:/USR/BIN:/ROOT/BIN
二)glob 文件名通配符
功能:bash中用于實現文件名通配的機制
通配符:
* 任意長度任意字符
? 任意單個字符
【】
a*b 以a開頭,b結尾,中間可以跟0個或任意多個字符
[root@fenfa glob]# touch ab aab a12b abc a@b aMb
[root@fenfa glob]# ll
total 0
-rw-r--r-- 1 root root 0 Jan 8 14:51 a12b
-rw-r--r-- 1 root root 0 Jan 8 14:51 aab
-rw-r--r-- 1 root root 0 Jan 8 14:51 ab
-rw-r--r-- 1 root root 0 Jan 8 14:51 abc
-rw-r--r-- 1 root root 0 Jan 8 14:51 a@b
-rw-r--r-- 1 root root 0 Jan 8 14:51 aMb
[root@fenfa glob]# ls a*b
a12b aab ab
[root@fenfa glob]# ls a?b
aab
[root@fenfa glob]# ls a[0-9]b
a2b
[root@fenfa glob]# ls a[a-z]b
aab aMb-----------(不區分字符的大小寫)
[root@fenfa glob]# ls a[A-Z]b
aMb
[root@fenfa glob]# ls a[^0-9a-z]b
a@b
[root@fenfa glob]# ls a[^[:alnum:]]b
a@b
專用字符集合
【:digit:】相當于0-9
【:alnum:】相當于a-z A-Z 0-9
【:alpha:】 相當于a-z A-Z
【:space:】相當于空格字符
【:punct:】相當于所有標點符號
三)Bash的配置文件
按其生效范圍劃分,存在以下兩類
全局配置:/etc/profile /etc/bashrc /etc/profile.d/*.sh
個人配置: ~/.bash_profile ~/.bashrc
shell登錄:
交互式登錄:
直接通過終端登錄 或者通過su - username
/etc/profile-----/etc/profile.d/*.sh----~/.bash_profile--->~/.bashrc--->/etc/bashrc
非交互式登錄:
su username
圖形界面下打開的為終端
執行腳本
~/.bashrc--->/etc/bashrc---->/etc/profile.d/*.sh
profile類公用:
1)用于定義環境變量
2)用于運行命令或腳本
全局:
/etc/profile
/etc/profile.d/*.sh
個人:
~/.bash_profile
bashrc類公用:
1)定義命令別名
2)定義本地變量
全局:
/etc/bashrc
個人
~/.bashrc
四)在bash中如何進行算術運算