8.1 shell介绍8.2 命令历史8.3 命令补全和别名8.4 通配符8.5 输入输出重定向# Linux shell 基础# 8.1 shell 介绍- 什么是shell1. shell 是一个命令解释器,提供用户和机器之间的交互2. 支持特定语法,比如逻辑判断、循环3. 每个用户都可以有自己特定的shell4. CentOS7 默认shell 为bash (Bourne Agin Shell)5. 还有zsh、ksh等```[root@aminglinux-01 ~]# [root@aminglinux-01 ~]# yum list |grep zshautojump-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     [root@aminglinux-01 ~]# yum list |grep kshksh.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     [root@aminglinux-01 ~]# ```# 8.2  命令历史![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170814/225032244.png?p_w_picpathslim)- 很多系统里面的命令都是存在用户的家目录下, /root/.bash_history```[root@aminglinux-01 ~]# ls /root/.bash_history/root/.bash_history[root@aminglinux-01 ~]# cat /root/.bash_historyecho $?yum list |grep -i apryum list |grep -i pcreyum install -y pcre.x86_64yum install -y pcre-devel.x86_64./configure --prefix=/usr/local/apache2echo $?makeecho $?make installecho $?ls /usr/local/apache2init 0[root@aminglinux-01 ~]# [root@aminglinux-01 ~]# echo $HISTSIZE1000[root@aminglinux-01 ~]#```- 这是我们之前存的命令,这个文件里最大可以存1000条- histroy -c 仅仅是把内存当中的命令给清空了,并不会去删除配置文件```[root@aminglinux-01 ~]# history -c[root@aminglinux-01 ~]# history    8  history    [root@aminglinux-01 ~]# cat .bash_history[root@aminglinux-01 ~]# ls -l .bash_history-rw-------. 1 root root 15810 8月  12 23:03 .bash_history[root@aminglinux-01 ~]# ```- 变量HISTSIZE 可以定义的,在/etc/profile```[root@aminglinux-01 ~]# vi /etc/profileHOSTNAME=`/usr/bin/hostname 2>/dev/null`HISTSIZE=1000if [ "$HISTCONTROL" = "ignorespace" ] ; then    export HISTCONTROL=ignorebothelse    export HISTCONTROL=ignoredupsfiexport 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=5000if [ "$HISTCONTROL" = "ignorespace" ] ; then    export HISTCONTROL=ignorebothelse    export HISTCONTROL=ignoredupsfiexport 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 --```- 虽然改了,但是并没有生效```[root@aminglinux-01 ~]# vi /etc/profile[root@aminglinux-01 ~]# echo $HISTSIZE1000[root@aminglinux-01 ~]# ```- 使用命令source /etc/profile 或者重新进入终端,才会生效```[root@aminglinux-01 ~]# source /etc/profile[root@aminglinux-01 ~]# echo $HISTSIZE5000[root@aminglinux-01 ~]# ```- 会记录日期时间,这个效果是由环境变量改变的,但是只是在当前终端下生效,```[root@aminglinux-01 ~]# 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[root@aminglinux-01 ~]# 改变命令历史的格式[root@aminglinux-01 ~]# HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "[root@aminglinux-01 ~]# echo $HISTTIMEFORMAT%Y/%m/%d %H:%M:%S[root@aminglinux-01 ~]# 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[root@aminglinux-01 ~]# ```- 改变命令历史的格式,这个只针对当前终端下生效,如果想要所有的都生效,需要编辑vi/etc/profile 文件 把HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S " 加入到文件里面  vi/etc/profile```HOSTNAME=`/usr/bin/hostname 2>/dev/null`HISTSIZE=5000HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "   加入这一行if [ "$HISTCONTROL" = "ignorespace" ] ; then    export HISTCONTROL=ignorebothelse    export HISTCONTROL=ignoredups[root@aminglinux-01 ~]# vi /etc/profile[root@aminglinux-01 ~]# source !$source /etc/profile[root@aminglinux-01 ~]# ```- 这时候再打开另一个终端就可以看到生效了![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170814/234805048.png?p_w_picpathslim)```[root@aminglinux-01 ~]# echo $HISTTIMEFORMAT%Y/%m/%d %H:%M:%S[root@aminglinux-01 ~]#  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[root@aminglinux-01 ~]# ```- 改变命令历史的格式就成功了- 永久保存命令历史 chattr +a ~/.bash_history```[root@aminglinux-01 ~]# chattr +a ~/.bash_history```- 这样运行过的命令都会记录下来,- 但是如果不正常退出,有时候敲了一些命令,但是你没有logout ,exit 退出,而是直接关闭终端,那样就会记录不全,命令就保存的不全。- 命令 !! 2个!其实就是你运行的 上一条命令(最后一条命令)```[root@aminglinux-01 ~]# ls111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt[root@aminglinux-01 ~]# !!ls111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt[root@aminglinux-01 ~]# ```- !n 表示运行history里面的第n条命令```[root@aminglinux-01 ~]# 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[root@aminglinux-01 ~]# !10ls -l .bash_history-rw-------. 1 root root 15881 8月  14 23:51 .bash_history[root@aminglinux-01 ~]# ```- !word  它会在命令历史里面倒着往上找第一个有word的命令- 比如运行命令!echo 就是运行命令历史里 倒着数第一个有ehco 相关的命令```[root@aminglinux-01 ~]# 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[root@aminglinux-01 ~]# !10ls -l .bash_history-rw-------. 1 root root 15881 8月  14 23:51 .bash_history[root@aminglinux-01 ~]# !echoecho $HISTTIMEFORMAT%Y/%m/%d %H:%M:%S[root@aminglinux-01 ~]# ```- 命令历史里 关于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?p_w_picpathslim)- 按tab一下补全命令,tab按俩下 列出以命令开头的命令```[root@aminglinux-01 ~]# lsls        lsblk     lsinitrd  lslocks   lsmod     lspci     lsattr    lscpu     lsipc     lslogins  lsns      lsscsi    [root@aminglinux-01 ~]# mkmkdict            mkfifo            mkfs.ext2         mkfs.xfs          mknodmkdir             mkfs              mkfs.ext3         mkhomedir_helper  mkpasswdmkdumprd          mkfs.btrfs        mkfs.ext4         mkinitrd          mkswapmke2fs            mkfs.cramfs       mkfs.minix        mklost+found      mktemp[root@aminglinux-01 ~]# mktemp```- 运行mk  tab俩下就会显示一堆以mk开头的命令,按mkt tab一下就会自动补全mktemp- centos7 里面支持参数补全1. 需要安装一个包```[root@aminglinux-01 ~]# systemctl restart network^C[root@aminglinux-01 ~]# yum install -y bash-completion已安装:  bash-completion.noarch 1:2.1-6.el7                                                       完毕![root@aminglinux-01 ~]#```2. 安装完需要重启下系统才可以reboot 或者 init 63. 重启系统之后,先看下那个包是否安装,然后输入部分命令尝试按下tab 看看是否会补全```[root@aminglinux-01 ~]# rpm -qa bash-completionbash-completion-2.1-6.el7.noarch[root@aminglinux-01 ~]# systemctl resrescue        reset-failed  restart       [root@aminglinux-01 ~]# systemctl resrescue        reset-failed  restart       [root@aminglinux-01 ~]# systemctl resrescue        reset-failed  restart       [root@aminglinux-01 ~]# systemctl restart networknetwork-online.target  network.service        [root@aminglinux-01 ~]# systemctl restart network.service[root@aminglinux-01 ~]# ```- alias 别名 给名重新起个名字   用alias 把systemctl restart network.service 改为 restartnet ```[root@aminglinux-01 ~]# systemctl restart network.service [root@aminglinux-01 ~]# alias restartnet='systemctl restart network.service'[root@aminglinux-01 ~]# restartnet把系统里所有的alias 都列出来[root@aminglinux-01 ~]# aliasalias 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'[root@aminglinux-01 ~]# ```- 取消自定义别名```[root@aminglinux-01 profile.d]# unalias restartnet[root@aminglinux-01 profile.d]# restartnet-bash: restartnet: 未找到命令[root@aminglinux-01 profile.d]# ```- 这些alias存在哪里呢 .bashrc , /etc/profile.d```[root@aminglinux-01 ~]# vi .bashrc# .bashrc# User specific aliases and functionsalias rm='rm -i'alias cp='cp -i'alias mv='mv -i'# Source global definitionsif [ -f /etc/bashrc ]; then        . /etc/bashrcfi~                                                                                          ~                                               ```2. 这个/etc/profile.d文件下面的 colorls.sh ,colorgrep.sh 也有```[root@aminglinux-01 ~]# cd /etc/profile.d[root@aminglinux-01 profile.d]# ls256term.csh         colorgrep.csh  colorls.sh  less.csh  vim.sh256term.sh          colorgrep.sh   lang.csh    less.sh   which2.cshbash_completion.sh  colorls.csh    lang.sh     vim.csh   which2.sh[root@aminglinux-01 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 || returnalias grep='grep --color=auto' 2>/dev/nullalias egrep='egrep --color=auto' 2>/dev/nullalias fgrep='fgrep --color=auto' 2>/dev/null~                                                                                                                                                                                  "colorgrep.sh" 7L, 201C```# 8.4 通配符![mark](http://oqxf7c508.bkt.clouddn.com/blog/20170815/223720549.png?p_w_picpathslim)- *.txt  *表示任何字符```[root@aminglinux-01 ~]# ls111  1_heard.txt  1.txt~     234        3.txt  anaconda-ks.cfg.1123  1_sorft.txt  1.txt.bak  2.txt.bak  4.txt  biji.txt[root@aminglinux-01 ~]# ls *.txt1_heard.txt  1_sorft.txt  3.txt  4.txt  biji.txt[root@aminglinux-01 ~]# ls *txt1_heard.txt  1_sorft.txt  3.txt  4.txt  biji.txt[root@aminglinux-01 ~]# ls *txt*1_heard.txt  1_sorft.txt  1.txt~  1.txt.bak  2.txt.bak  3.txt  4.txt  biji.txt[root@aminglinux-01 ~]# ls 1*1_heard.txt  1_sorft.txt  1.txt~  1.txt.bak111:12.tx~  12.txt  12_txt.swp  222  4913  aming3123:aminglinux.log  yum.log[root@aminglinux-01 ~]# ```- ls ?.txt    ?表示一个字符 任意的字符```[root@aminglinux-01 ~]# touch 2.txt[root@aminglinux-01 ~]# touch 1.txt[root@aminglinux-01 ~]# ls ?.txt1.txt  2.txt  3.txt  4.txt[root@aminglinux-01 ~]# touch a.txt[root@aminglinux-01 ~]# touch bb.txt[root@aminglinux-01 ~]# ls ?.txt1.txt  2.txt  3.txt  4.txt  a.txt[root@aminglinux-01 ~]# ```- ls [0-9].txt  []13.txt 或者的意思```[root@aminglinux-01 ~]# ls [0-3].txt1.txt  2.txt  3.txt[root@aminglinux-01 ~]# ls [123].txt1.txt  2.txt  3.txt[root@aminglinux-01 ~]# ls [23].txt2.txt  3.txt[root@aminglinux-01 ~]# ls [13].txt1.txt  3.txt[root@aminglinux-01 ~]# ls [0-9].txt1.txt  2.txt  3.txt  4.txt[root@aminglinux-01 ~]# ls [0-9a-zA-Z].txt1.txt  2.txt  3.txt  4.txt  a.txt[root@aminglinux-01 ~]# ```- ls {1,2}.txt```[root@aminglinux-01 ~]# ls {1,2}.txt1.txt  2.txt[root@aminglinux-01 ~]# ls {1,2,3,a}.txt1.txt  2.txt  3.txt  a.txt[root@aminglinux-01 ~]#```## 8.5 输入输出重定向- [ ]     >    正确的输出重定向   cat 1.txt >2.txt- [ ]     >>   正确的追加        cat 1.txt >>2.txt-   2> 错误的输出重定向  ls aaa.txt 2>err-   2>> 错误的追加     ls aaa.txt 2>>err```[root@aminglinux-01 ~]# lsaaa-bash: lsaaa: 未找到命令[root@aminglinux-01 ~]# lsaaa 2> a.txt[root@aminglinux-01 ~]# cat a.txt-bash: lsaaa: 未找到命令[root@aminglinux-01 ~]# lsaaa 2>>a.txt[root@aminglinux-01 ~]# cat a.txt-bash: lsaaa: 未找到命令-bash: lsaaa: 未找到命令[root@aminglinux-01 ~]# >  >>  2> 2>>  >+2> == &>^C[root@aminglinux-01 ~]#```- &> 可以把正确和错误的放一起```[root@aminglinux-01 ~]# ls [12].txt aaa.txt &> a.txt[root@aminglinux-01 ~]# cat a.txtls: 无法访问aaa.txt: 没有那个文件或目录1.txt2.txt[root@aminglinux-01 ~]# ```- &> 同样也支持追加```[root@aminglinux-01 ~]# ls [12].txt aaa.txt &>> a.txt[root@aminglinux-01 ~]# cat a.txtls: 无法访问aaa.txt: 没有那个文件或目录1.txt2.txtls: 无法访问aaa.txt: 没有那个文件或目录1.txt2.txt[root@aminglinux-01 ~]# ```- &> 既可以放正确也可以发个错误的输出信息 保存到指定的文件里```[root@aminglinux-01 ~]# ls [12].txt aaa.txt > 1.txt 2>a.txt[root@aminglinux-01 ~]# cat 1.txt1.txt2.txt[root@aminglinux-01 ~]# cat a.txtls: 无法访问aaa.txt: 没有那个文件或目录[root@aminglinux-01 ~]# ```- 输入重定向 把右边的一个文件,文件的内容 给它左边 输入到一个命令里面去```[root@aminglinux-01 ~]# wc -l < 1.txt2[root@aminglinux-01 ~]# 2.txt < 1.txt-bash: 2.txt: 未找到命令[root@aminglinux-01 ~]# ```- [ ] 左边必须是一个命令,不可以是文件  输入重定向用的比较少,做一个了解