1. 程式人生 > >8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向

8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向

8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向

8.1 shell介紹

8.2 命令歷史

8.3 命令補全和別名

8.4 通配符

8.5 輸入輸出重定向

# Linux shell 基礎

# 8.1 shell 介紹
- 什麽是shell
1. shell 是一個命令解釋器,提供用戶和機器之間的交互
2. 支持特定語法,比如邏輯判斷、循環
3. 每個用戶都可以有自己特定的shell
4. CentOS7 默認shell 為bash (Bourne Agin Shell)
5. 還有zsh、ksh等
```
[[email protected] ~]# 
[[email protected] ~]# yum list |grep zsh
autojump-zsh.noarch                     22.3.0-3.el7                   epel     
zsh.x86_64                              5.0.2-25.el7_3.1               updates  
zsh-html.x86_64                         5.0.2-25.el7_3.1               updates  
zsh-lovers.noarch                       0.9.0-1.el7                    epel     
[[email protected] ~]# yum list |grep ksh
ksh.x86_64                              20120801-26.el7                base     
mksh.x86_64                             46-5.el7                       base     
python-XStatic-Rickshaw.noarch          1.5.0.0-4.el7                  epel     
python-moksha-common.noarch             1.2.3-2.el7                    epel     
python-moksha-hub.noarch                1.4.8-1.el7                    epel     
python-moksha-wsgi.noarch               1.2.2-2.el7                    epel     
[[email protected] ~]# 
```


# 8.2  命令歷史

![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170814/225032244.png?imageslim)

- 很多系統裏面的命令都是存在用戶的家目錄下, /root/.bash_history
```
[[email protected] ~]# ls /root/.bash_history
/root/.bash_history
[[email protected] ~]# cat /root/.bash_history

echo $?
yum list |grep -i apr
yum list |grep -i pcre
yum install -y pcre.x86_64
yum install -y pcre-devel.x86_64
./configure --prefix=/usr/local/apache2
echo $?
make
echo $?
make install
echo $?
ls /usr/local/apache2
init 0
[[email protected] ~]# 
[[email protected] ~]# echo $HISTSIZE
1000
[[email protected] ~]#
```
- 這是我們之前存的命令,這個文件裏最大可以存1000條

- histroy -c 僅僅是把內存當中的命令給清空了,並不會去刪除配置文件
```
[[email protected] ~]# history -c
[[email protected] ~]# history
    8  history
    
[[email protected] ~]# cat .bash_history

[[email protected] ~]# ls -l .bash_history
-rw-------. 1 root root 15810 8月  12 23:03 .bash_history
[[email protected] ~]# 


```

- 變量HISTSIZE 可以定義的,在/etc/profile
```
[[email protected] ~]# vi /etc/profile


HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
```
- 可以把HISTSIZE=1000 改為5000 保存
```
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=5000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
-- INSERT --
```
- 雖然改了,但是並沒有生效
```
[[email protected] ~]# vi /etc/profile
[[email protected] ~]# echo $HISTSIZE
1000
[[email protected] ~]# 
```

- 使用命令source /etc/profile 或者重新進入終端,才會生效
```
[[email protected] ~]# source /etc/profile
[[email protected] ~]# echo $HISTSIZE
5000
[[email protected] ~]# 

```
- 會記錄日期時間,這個效果是由環境變量改變的,但是只是在當前終端下生效,
```
[[email protected] ~]# history
    8  history
    9  cat .bash_history
   10  ls -l .bash_history
   11  vi /etc/profile
   12  echo $HISTSIZE
   13  source /etc/profile
   14  echo $HISTSIZE
   15  history
[[email protected] ~]# 

改變命令歷史的格式
[[email protected] ~]# HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
[[email protected] ~]# echo $HISTTIMEFORMAT
%Y/%m/%d %H:%M:%S
[[email protected] ~]# history
    8  2017/08/14 23:07:03 history
    9  2017/08/14 23:09:09 cat .bash_history
   10  2017/08/14 23:10:08 ls -l .bash_history
   11  2017/08/14 23:28:55 vi /etc/profile
   12  2017/08/14 23:33:10 echo $HISTSIZE
   13  2017/08/14 23:34:10 source /etc/profile
   14  2017/08/14 23:34:13 echo $HISTSIZE
   15  2017/08/14 23:35:40 history
   16  2017/08/14 23:39:00 HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
   17  2017/08/14 23:39:15 echo $HISTTIMEFORMAT
   18  2017/08/14 23:39:28 history
[[email protected] ~]# 
```

- 改變命令歷史的格式,這個只針對當前終端下生效,如果想要所有的都生效,需要編輯vi/etc/profile 文件 把HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S " 加入到文件裏面  vi/etc/profile

```
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=5000
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "   加入這一行

if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups


[[email protected] ~]# vi /etc/profile
[[email protected] ~]# source !$
source /etc/profile
[[email protected] ~]# 
```
- 這時候再打開另一個終端就可以看到生效了
![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170814/234805048.png?imageslim)

```
[[email protected] ~]# echo $HISTTIMEFORMAT
%Y/%m/%d %H:%M:%S
[[email protected] ~]#
  987  2017/08/14 23:46:55 echo $?
  988  2017/08/14 23:46:55 yum list |grep -i apr
  989  2017/08/14 23:46:55 yum list |grep -i pcre
  990  2017/08/14 23:46:55 yum install -y pcre.x86_64
  991  2017/08/14 23:46:55 yum install -y pcre-devel.x86_64
  992  2017/08/14 23:46:55 ./configure --prefix=/usr/local/apache2
  993  2017/08/14 23:46:55 echo $?
  994  2017/08/14 23:46:55 make
  995  2017/08/14 23:46:55 echo $?
  996  2017/08/14 23:46:55 make install
  997  2017/08/14 23:46:55 echo $?
  998  2017/08/14 23:46:55 ls /usr/local/apache2
  999  2017/08/14 23:46:55 init 0
 1000  2017/08/14 23:46:57 clear
 1001  2017/08/14 23:47:07 echo $HISTTIMEFORMAT
 1002  2017/08/14 23:48:13 history
[[email protected] ~]# 

```
- 改變命令歷史的格式就成功了

- 永久保存命令歷史 chattr +a ~/.bash_history
```
[[email protected] ~]# chattr +a ~/.bash_history
```
- 這樣運行過的命令都會記錄下來,
- 但是如果不正常退出,有時候敲了一些命令,但是你沒有logout ,exit 退出,而是直接關閉終端,那樣就會記錄不全,命令就保存的不全。

- 命令 !! 2個!其實就是你運行的 上一條命令(最後一條命令)
```
[[email protected] ~]# ls
111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1
123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt
[[email protected] ~]# !!
ls
111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1
123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt
[[email protected] ~]# 
```
- !n 表示運行history裏面的第n條命令
```
[[email protected] ~]# history
    8  2017/08/14 23:07:03 history
    9  2017/08/14 23:09:09 cat .bash_history
   10  2017/08/14 23:10:08 ls -l .bash_history
   11  2017/08/14 23:28:55 vi /etc/profile
   12  2017/08/14 23:33:10 echo $HISTSIZE
   13  2017/08/14 23:34:10 source /etc/profile
   14  2017/08/14 23:34:13 echo $HISTSIZE
   15  2017/08/14 23:35:40 history
   16  2017/08/14 23:39:00 HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
   17  2017/08/14 23:39:15 echo $HISTTIMEFORMAT
   18  2017/08/14 23:39:28 history
   19  2017/08/14 23:43:15 vi /etc/profile
   20  2017/08/14 23:45:50 source /etc/profile
   21  2017/08/14 23:51:50 chattr +a ~/.bash_history
   22  2017/08/14 23:54:18 history
   23  2017/08/14 23:55:50 ls
   24  2017/08/14 23:56:13 history
[[email protected] ~]# !10
ls -l .bash_history
-rw-------. 1 root root 15881 8月  14 23:51 .bash_history
[[email protected] ~]# 
```
- !word  它會在命令歷史裏面倒著往上找第一個有word的命令
- 比如運行命令!echo 就是運行命令歷史裏 倒著數第一個有ehco 相關的命令
```
[[email protected] ~]# history
    8  2017/08/14 23:07:03 history
    9  2017/08/14 23:09:09 cat .bash_history
   10  2017/08/14 23:10:08 ls -l .bash_history
   11  2017/08/14 23:28:55 vi /etc/profile
   12  2017/08/14 23:33:10 echo $HISTSIZE
   13  2017/08/14 23:34:10 source /etc/profile
   14  2017/08/14 23:34:13 echo $HISTSIZE
   15  2017/08/14 23:35:40 history
   16  2017/08/14 23:39:00 HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
   17  2017/08/14 23:39:15 echo $HISTTIMEFORMAT
   18  2017/08/14 23:39:28 history
   19  2017/08/14 23:43:15 vi /etc/profile
   20  2017/08/14 23:45:50 source /etc/profile
   21  2017/08/14 23:51:50 chattr +a ~/.bash_history
   22  2017/08/14 23:54:18 history
   23  2017/08/14 23:55:50 ls
   24  2017/08/14 23:56:13 history
[[email protected] ~]# !10
ls -l .bash_history
-rw-------. 1 root root 15881 8月  14 23:51 .bash_history
[[email protected] ~]# !echo
echo $HISTTIMEFORMAT
%Y/%m/%d %H:%M:%S
[[email protected] ~]# 
```
- 命令歷史裏 關於ehco的命令是 echo $HISTTIMEFORMAT%Y/%m/%d %H:%M:%S,所以 !echo 就是運行這個命令echo  $HISTTIMEFORMAT%Y/%m/%d %H:%M:%S



#  8.3 命令補全和別名
![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170815/220451944.png?imageslim)

- 按tab一下補全命令,tab按倆下 列出以命令開頭的命令
```
[[email protected] ~]# ls
ls        lsblk     lsinitrd  lslocks   lsmod     lspci     
lsattr    lscpu     lsipc     lslogins  lsns      lsscsi    
[[email protected] ~]# mk
mkdict            mkfifo            mkfs.ext2         mkfs.xfs          mknod
mkdir             mkfs              mkfs.ext3         mkhomedir_helper  mkpasswd
mkdumprd          mkfs.btrfs        mkfs.ext4         mkinitrd          mkswap
mke2fs            mkfs.cramfs       mkfs.minix        mklost+found      mktemp
[[email protected] ~]# mktemp
```
- 運行mk  tab倆下就會顯示一堆以mk開頭的命令,按mkt tab一下就會自動補全mktemp
- centos7 裏面支持參數補全
1. 需要安裝一個包
```
[[email protected] ~]# systemctl restart network^C
[[email protected] ~]# yum install -y bash-completion

已安裝:
  bash-completion.noarch 1:2.1-6.el7                                                       
完畢!
[[email protected] ~]#
```
2. 安裝完需要重啟下系統才可以reboot 或者 init 6
3. 重啟系統之後,先看下那個包是否安裝,然後輸入部分命令嘗試按下tab 看看是否會補全
```
[[email protected] ~]# rpm -qa bash-completion
bash-completion-2.1-6.el7.noarch
[[email protected] ~]# systemctl res
rescue        reset-failed  restart       
[[email protected] ~]# systemctl res
rescue        reset-failed  restart       
[[email protected] ~]# systemctl res
rescue        reset-failed  restart       
[[email protected] ~]# systemctl restart network
network-online.target  network.service        
[[email protected] ~]# systemctl restart network.service
[[email protected] ~]# 
```
- alias 別名 給名重新起個名字   用alias 把systemctl restart network.service 改為 restartnet 
```
[[email protected] ~]# systemctl restart network.service 
[[email protected] ~]# alias restartnet=‘systemctl restart network.service‘
[[email protected] ~]# restartnet

把系統裏所有的alias 都列出來
[[email protected] ~]# alias
alias cp=‘cp -i‘
alias egrep=‘egrep --color=auto‘
alias fgrep=‘fgrep --color=auto‘
alias grep=‘grep --color=auto‘
alias l.=‘ls -d .* --color=auto‘
alias ll=‘ls -l --color=auto‘
alias ls=‘ls --color=auto‘
alias mv=‘mv -i‘
alias restartnet=‘systemctl restart network.service‘
alias rm=‘rm -i‘
alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde‘
[[email protected] ~]# 
```
- 取消自定義別名
```
[[email protected] profile.d]# unalias restartnet
[[email protected] profile.d]# restartnet
-bash: restartnet: 未找到命令
[[email protected] profile.d]# 
```

- 這些alias存在哪裏呢 .bashrc , /etc/profile.d
```
[[email protected] ~]# vi .bashrc

# .bashrc

# User specific aliases and functions

alias rm=‘rm -i‘
alias cp=‘cp -i‘
alias mv=‘mv -i‘

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
~                                                                                          
~                                               
```
2. 這個/etc/profile.d文件下面的 colorls.sh ,colorgrep.sh 也有
```
[[email protected] ~]# cd /etc/profile.d
[[email protected] profile.d]# ls
256term.csh         colorgrep.csh  colorls.sh  less.csh  vim.sh
256term.sh          colorgrep.sh   lang.csh    less.sh   which2.csh
bash_completion.sh  colorls.csh    lang.sh     vim.csh   which2.sh
[[email protected] profile.d]# vi colorls.sh
~                                                                                          
".bashrc" 12L, 176C



  alias ll=‘ls -l‘ 2>/dev/null
  alias l.=‘ls -d .*‘ 2>/dev/null

  INCLUDE=
  COLORS=

  for colors in "$HOME/.dir_colors.$TERM" "$HOME/.dircolors.$TERM"       "$HOME/.dir_colors" "$HOME/.dircolors"; do
    [ -e "$colors" ] && COLORS="$colors" &&     INCLUDE="`/usr/bin/cat "$COLORS" | /usr/bin/grep ‘^INCLUDE‘ | /usr/bin/cut -d ‘ ‘ -f2-`" &&     break
  done

/alias
```
3. colorgrep.sh 文件也有
```
# color-grep initialization

/usr/libexec/grepconf.sh -c || return

alias grep=‘grep --color=auto‘ 2>/dev/null
alias egrep=‘egrep --color=auto‘ 2>/dev/null
alias fgrep=‘fgrep --color=auto‘ 2>/dev/null
~                                                                                          
                                                                                        
"colorgrep.sh" 7L, 201C
```


# 8.4 通配符
![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170815/223720549.png?imageslim)

- *.txt  *表示任何字符
```
[[email protected] ~]# ls
111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1
123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt
[[email protected] ~]# ls *.txt
1_heard.txt  1_sorft.txt  3.txt  4.txt  biji.txt
[[email protected] ~]# ls *txt
1_heard.txt  1_sorft.txt  3.txt  4.txt  biji.txt
[[email protected] ~]# ls *txt*
1_heard.txt  1_sorft.txt  1.txt~  1.txt.bak  2.txt.bak  3.txt  4.txt  biji.txt
[[email protected] ~]# ls 1*
1_heard.txt  1_sorft.txt  1.txt~  1.txt.bak

111:
12.tx~  12.txt  12_txt.swp  222  4913  aming3

123:
aminglinux.log  yum.log
[[email protected] ~]# 
```
- ls ?.txt    ?表示一個字符 任意的字符
```
[[email protected] ~]# touch 2.txt
[[email protected] ~]# touch 1.txt
[[email protected] ~]# ls ?.txt
1.txt  2.txt  3.txt  4.txt
[[email protected] ~]# touch a.txt
[[email protected] ~]# touch bb.txt
[[email protected] ~]# ls ?.txt
1.txt  2.txt  3.txt  4.txt  a.txt
[[email protected] ~]# 
```
- ls [0-9].txt  []13.txt 或者的意思
```
[[email protected] ~]# ls [0-3].txt
1.txt  2.txt  3.txt
[[email protected] ~]# ls [123].txt
1.txt  2.txt  3.txt
[[email protected] ~]# ls [23].txt
2.txt  3.txt
[[email protected] ~]# ls [13].txt
1.txt  3.txt
[[email protected] ~]# ls [0-9].txt
1.txt  2.txt  3.txt  4.txt
[[email protected] ~]# ls [0-9a-zA-Z].txt
1.txt  2.txt  3.txt  4.txt  a.txt
[[email protected] ~]# 
```
- ls {1,2}.txt
```
[[email protected] ~]# ls {1,2}.txt
1.txt  2.txt
[[email protected] ~]# ls {1,2,3,a}.txt
1.txt  2.txt  3.txt  a.txt
[[email protected] ~]#
```

## 8.5 輸入輸出重定向

- [ ]     >    正確的輸出重定向   cat 1.txt >2.txt
- [ ]     >>   正確的追加        cat 1.txt >>2.txt
-   2> 錯誤的輸出重定向  ls aaa.txt 2>err
-   2>> 錯誤的追加     ls aaa.txt 2>>err

```
[[email protected] ~]# lsaaa
-bash: lsaaa: 未找到命令
[[email protected] ~]# lsaaa 2> a.txt
[[email protected] ~]# cat a.txt
-bash: lsaaa: 未找到命令
[[email protected] ~]# lsaaa 2>>a.txt
[[email protected] ~]# cat a.txt
-bash: lsaaa: 未找到命令
-bash: lsaaa: 未找到命令
[[email protected] ~]# >  >>  2> 2>>  >+2> == &>^C
[[email protected] ~]#
```
- &> 可以把正確和錯誤的放一起
```
[[email protected] ~]# ls [12].txt aaa.txt &> a.txt
[[email protected] ~]# cat a.txt
ls: 無法訪問aaa.txt: 沒有那個文件或目錄
1.txt
2.txt
[[email protected] ~]# 
```
- &> 同樣也支持追加
```
[[email protected] ~]# ls [12].txt aaa.txt &>> a.txt
[[email protected] ~]# cat a.txt
ls: 無法訪問aaa.txt: 沒有那個文件或目錄
1.txt
2.txt
ls: 無法訪問aaa.txt: 沒有那個文件或目錄
1.txt
2.txt
[[email protected] ~]# 
```
- &> 既可以放正確也可以發個錯誤的輸出信息 保存到指定的文件裏
```
[[email protected] ~]# ls [12].txt aaa.txt > 1.txt 2>a.txt
[[email protected] ~]# cat 1.txt
1.txt
2.txt
[[email protected] ~]# cat a.txt
ls: 無法訪問aaa.txt: 沒有那個文件或目錄
[[email protected] ~]# 
```
- 輸入重定向 把右邊的一個文件,文件的內容 給它左邊 輸入到一個命令裏面去
```
[[email protected] ~]# wc -l < 1.txt
2
[[email protected] ~]# 2.txt < 1.txt
-bash: 2.txt: 未找到命令
[[email protected] ~]# 
```
- [ ] 左邊必須是一個命令,不可以是文件  輸入重定向用的比較少,做一個了解


8.1 shell介紹 8.2 命令歷史 8.3 命令補全和別名 8.4 通配符 8.5 輸入輸出重定向