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等
```
[root@aminglinux-01 ~]#
[root@aminglinux-01 ~]# 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
[root@aminglinux-01 ~]# 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
[root@aminglinux-01 ~]#
```
# 8.2 命令历史

- 很多系统里面的命令都是存在用户的家目录下, /root/.bash_history
```
[root@aminglinux-01 ~]# ls /root/.bash_history
/root/.bash_history
[root@aminglinux-01 ~]# 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
[root@aminglinux-01 ~]#
[root@aminglinux-01 ~]# echo $HISTSIZE
1000
[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/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 --
```
- 虽然改了,但是并没有生效
```
[root@aminglinux-01 ~]# vi /etc/profile
[root@aminglinux-01 ~]# echo $HISTSIZE
1000
[root@aminglinux-01 ~]#
```
- 使用命令source /etc/profile 或者重新进入终端,才会生效
```
[root@aminglinux-01 ~]# source /etc/profile
[root@aminglinux-01 ~]# echo $HISTSIZE
5000
[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=5000
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S " 加入这一行
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
[root@aminglinux-01 ~]# vi /etc/profile
[root@aminglinux-01 ~]# source !$
source /etc/profile
[root@aminglinux-01 ~]#
```
- 这时候再打开另一个终端就可以看到生效了

```
[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 ~]# 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
[root@aminglinux-01 ~]# !!
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
[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 ~]# !10
ls -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 ~]# !10
ls -l .bash_history
-rw-------. 1 root root 15881 8月 14 23:51 .bash_history
[root@aminglinux-01 ~]# !echo
echo $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 命令补全和别名

- 按tab一下补全命令,tab按俩下 列出以命令开头的命令
```
[root@aminglinux-01 ~]# ls
ls lsblk lsinitrd lslocks lsmod lspci
lsattr lscpu lsipc lslogins lsns lsscsi
[root@aminglinux-01 ~]# 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
[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 6
3. 重启系统之后,先看下那个包是否安装,然后输入部分命令尝试按下tab 看看是否会补全
```
[root@aminglinux-01 ~]# rpm -qa bash-completion
bash-completion-2.1-6.el7.noarch
[root@aminglinux-01 ~]# systemctl res
rescue reset-failed restart
[root@aminglinux-01 ~]# systemctl res
rescue reset-failed restart
[root@aminglinux-01 ~]# systemctl res
rescue reset-failed restart
[root@aminglinux-01 ~]# systemctl restart network
network-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 ~]# 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‘
[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 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 也有
```
[root@aminglinux-01 ~]# cd /etc/profile.d
[root@aminglinux-01 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
[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 || 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 通配符

- *.txt *表示任何字符
```
[root@aminglinux-01 ~]# 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
[root@aminglinux-01 ~]# ls *.txt
1_heard.txt 1_sorft.txt 3.txt 4.txt biji.txt
[root@aminglinux-01 ~]# ls *txt
1_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.bak
111:
12.tx~ 12.txt 12_txt.swp 222 4913 aming3
123:
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 ?.txt
1.txt 2.txt 3.txt 4.txt
[root@aminglinux-01 ~]# touch a.txt
[root@aminglinux-01 ~]# touch bb.txt
[root@aminglinux-01 ~]# ls ?.txt
1.txt 2.txt 3.txt 4.txt a.txt
[root@aminglinux-01 ~]#
```
- ls [0-9].txt []13.txt 或者的意思
```
[root@aminglinux-01 ~]# ls [0-3].txt
1.txt 2.txt 3.txt
[root@aminglinux-01 ~]# ls [123].txt
1.txt 2.txt 3.txt
[root@aminglinux-01 ~]# ls [23].txt
2.txt 3.txt
[root@aminglinux-01 ~]# ls [13].txt
1.txt 3.txt
[root@aminglinux-01 ~]# ls [0-9].txt
1.txt 2.txt 3.txt 4.txt
[root@aminglinux-01 ~]# ls [0-9a-zA-Z].txt
1.txt 2.txt 3.txt 4.txt a.txt
[root@aminglinux-01 ~]#
```
- ls {1,2}.txt
```
[root@aminglinux-01 ~]# ls {1,2}.txt
1.txt 2.txt
[root@aminglinux-01 ~]# ls {1,2,3,a}.txt
1.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.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
[root@aminglinux-01 ~]#
```
- &> 同样也支持追加
```
[root@aminglinux-01 ~]# ls [12].txt aaa.txt &>> a.txt
[root@aminglinux-01 ~]# cat a.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
[root@aminglinux-01 ~]#
```
- &> 既可以放正确也可以发个错误的输出信息 保存到指定的文件里
```
[root@aminglinux-01 ~]# ls [12].txt aaa.txt > 1.txt 2>a.txt
[root@aminglinux-01 ~]# cat 1.txt
1.txt
2.txt
[root@aminglinux-01 ~]# cat a.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
[root@aminglinux-01 ~]#
```
- 输入重定向 把右边的一个文件,文件的内容 给它左边 输入到一个命令里面去
```
[root@aminglinux-01 ~]# wc -l < 1.txt
2
[root@aminglinux-01 ~]# 2.txt < 1.txt
-bash: 2.txt: 未找到命令
[root@aminglinux-01 ~]#
```
- [ ] 左边必须是一个命令,不可以是文件 输入重定向用的比较少,做一个了解8.1 shell介绍 8.2 命令历史 8.3 命令补全和别名 8.4 通配符 8.5 输入输出重定向
原文:http://ch71smas.blog.51cto.com/13090095/1961192