20180622 Linux shell 基础知识 8.1 —— 8.6
8.1 shell 介绍
8.2 命令历史
8.3 命令补全和别名
8.4 通配符
8.5 输入输出重定向
8.6 管道符和作业控制
8.1 shell 介绍
- what is shell
shell是一个命令解释器,提供用户和机器之间的交互
支持特定语法,比如逻辑判断、循环
每个用户都可以有自己特定的shell
CentOS7默认shell为bash(Bourne Agin Shell)
还有zsh、ksh等
-
shell 脚本仅仅是他的一种表现, 在用户的配置文件
/etc/passwd
里边, 可以在第七段 (也是最后一段) 表示的也是 shell —— /sbin/nologin (一共两种, /bin/login [登录] 和 /sbin/nologin [不登录])发现 -
每个用户都可以用自己的 shell, C7 默认 shell 为 bash (起名叫 Bourne Agin Shell), 这是为了纪念创始人 — Steven Bourne
-
可以看看 ksh 和 zsh, 与 bash 还是有些细微的差别的
[root@localhost ~]# yum list |grep zsh
Failed to set locale, defaulting to C
autojump-zsh.noarch 22.3.0-3.el7 epel
zsh.x86_64 5.0.2-28.el7 base
zsh-html.x86_64 5.0.2-28.el7 base
zsh-lovers.noarch 0.9.0-1.el7 epel
[root@localhost ~]# yum list |grep ksh
Failed to set locale, defaulting to C
ksh.x86_64 20120801-137.el7 base
mksh.x86_64 46-8.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-wsgi.noarch 1.2.2-2.el7 epel
python2-moksha-hub.noarch 1.5.6-1.el7 epel
- shell 有自己的逻辑判断, if , for, while 等
8.2 命令历史
命令历史
history命令
.bash_history
最大1000条
变量HISTSIZE
/etc/profile中修改
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S "
永久保存 chattr +a ~/.bash_history
!!
!n
!word
- 敲过的命令是有保存的文件的, P.S: 按向上的方向键可以查看敲过的命令; 这个文件是 /root/.bash_history
[root@localhost ~]# ls /root/.bash_history
/root/.bash_history
## 查看敲过的命令
[root@localhost ~]# less /root/.bash_history
ip addr
dhclient
ifconfig
yum install -y net-tools
ifconfig
vi /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl restart network.service
ifconfig
ip addr
ping www.baidu.com
init 0
ifconfig
yum install -y epel-release
yum install -y vim-enhanced
mkdir /root/.ssh
chmod 700 /root/.ssh
......
## 命令 history 查看敲过的命令有多少
[root@localhost ~]# history
......
183 cat /root/.bash_history
184 less /root/.bash_history
185 history
## 最多存 1000 条命令, 由系统内置的环境变量 HISTSIZE 决定, 有时候敲出的命令超过了 1000 个, 是因为这些命令暂时存在于内存中
[root@localhost ~]# echo $HISTSIZE
1000
- 命令 history -c 清空内存的命令历史
[root@localhost ~]# history
......
185 history
186 echo $HISTSIZE
187 history
[root@localhost ~]# history -c
[root@localhost ~]# history
1 history
## 但是不会删除存命令的文件里边的命令
[root@localhost ~]# less /root/.bash_history
......
ls /usr/local/apache2/
yum provides "/*/libtoolT"
init 0
ls ./srclib
init 0
## 如上刚敲过的命令并不会存在于 .bash_history 文件中, 退出终端时这些命令才会保存在文件里
[root@localhost ~]# history
1 history
2 less /.bash_history
3 less /root/.bash_history
4 ls
5 pwd
6 history
[root@localhost ~]# less .bash_history
......
ls /usr/local/apache2/
yum provides "/*/libtoolT"
init 0
ls ./srclib
init 0
- 环境变量在
/etc/profile
里边去定义
[root@localhost ~]# vim /etc/profile
......
HISTSIZE=1000
......
## 更改为
......
HISTSIZE=5000
......
## 如果不执行 source /etc/profile, 那么 /etc/profile 就不会生效
[root@localhost ~]# echo $HISTSIZE
1000
[root@localhost ~]# source /etc/profile; echo $HISTSIZE
5000
[root@localhost ~]# history
1 history
2 less /.bash_history
3 less /root/.bash_history
4 ls
5 pwd
6 history
7 less .bash_history
8 vim .bash_history
9 vim /etc/profile
10 echo $HISTSIZE
11 source /etc/profile; echo $HISTSIZE
12 history
- HISTTIMEFORMAT 记录命令执行的时间
## 记录命令的执行时间
[root@localhost ~]# echo $HISTTIMEFORMAT
%Y%m%d %H:%M:%S
[root@localhost ~]# ls
anaconda-ks.cfg
[root@localhost ~]# history
1 20180622 22:04:01history
2 20180622 22:04:47less /.bash_history
3 20180622 22:05:10less /root/.bash_history
4 20180622 22:07:27ls
5 20180622 22:07:35pwd
6 20180622 22:07:49history
7 20180622 22:08:01less .bash_history
8 20180622 22:11:21vim .bash_history
9 20180622 22:11:36vim /etc/profile
10 20180622 22:15:25echo $HISTSIZE
11 20180622 22:16:10source /etc/profile; echo $HISTSIZE
12 20180622 22:16:24history
13 20180622 22:17:57vim /etc/profile
14 20180622 22:20:58HISTTIMEFORMAT="%Y%m%d %H:%M:%S"
15 20180622 22:21:09echo $HISTTIMEFORMAT
16 20180622 22:21:14ls
17 20180622 22:21:19history
## 但是在复制终端下没生效, 他的localhost 已变更为 localhostcp
[root@localhostcp ~]# echo $HISTTIMEFORMAT
## 如果让其生效, 可以在 /etc/profile 里边设置
[root@localhost ~]# vim /etc/profile
.....
HISTTIMEFORMAT="%Y%m%d %H:%M:%S"
.....
[root@localhost ~]# source /etc/profile
## 在复制终端下查看
[root@localhostcp ~]# echo $HISTTIMEFORMAT
%Y%m%d %H:%M:%S
[root@localhostcp ~]# history
......
178 20180622 22:29:07ls ./srclib
179 20180622 22:29:07init 0
180 20180622 22:29:35echo $HISTTIMEFORMAT
181 20180622 22:29:40history
- 命令历史永久保存, 而不去删除它: 可以增加隐藏权限 chattr +a ~/.bash_history
[root@localhost ~]# chattr +a ~/.bash_history
[root@localhost ~]# lsattr ~/.bash_history
-----a---------- /root/.bash_history
## 如果不正常退出, 在 ~/.bash_history 里边不能保存全
[root@localhostcp ~]# ls
anaconda-ks.cfg
[root@localhostcp ~]# ls
anaconda-ks.cfg
[root@localhostcp ~]# ls
anaconda-ks.cfg
[root@localhostcp ~]# cd
[root@localhostcp ~]# cd
[root@localhostcp ~]# cd
[root@localhostcp ~]# pwd
/root
[root@localhostcp ~]# pwd
/root
[root@localhostcp ~]# cd -
/root
[root@localhostcp ~]# cd -
/root
### 在 ~/.bash_history 里边查看
#1529679506
ls
#1529679508
cd
#1529679510
cd
#1529679511
cd
#1529679513
pwd
#1529679517
cd -
- 其他的一些参数
!!
!n
!word
!! 表示敲的最后一条命令 ? !n 其中 n 表示数字, 数字在 history 命令执行后可知; 整个表示执行排在第 n 的那条命令 !word word 表示命令的名称; 整个表示命令历史中离我们最近的那条命令
8.3 命令补全和别名
命令补全及别名
tab键,敲一下,敲两下
参数补全,安装bash-completion
alias别名给命令重新起个名字
各用户都有自己配置别名的文件 ~/.bashrc
ls /etc/profile.d/
自定义的alias放到~/.bashrc
- 当命令很多时, 输入一个命令的几个字符时, 按两下 tab 键列出命令, 按了几个字符后, 只有这一个命令时, 按一下 tab 键就可以补全; C7 支持命令和参数补全, C6 只支持命令补全
## 命令补全
### 按两下 tab 键补全命令
[root@localhost ~]# ls
ls lsblk lshw lsipc lslogins lsmod lspci
lsattr lscpu lsinitrd lslocks lsmem lsns lsscsi
[root@localhost ~]# mk
mkdict mkfifo mkfs.ext2 mkfs.xfs mknod
mkdir mkfs mkfs.ext3 mkhomedir_helper mkswap
mkdumprd mkfs.btrfs mkfs.ext4 mkinitrd mktemp
mke2fs mkfs.cramfs mkfs.minix mklost+found
### 按一下 tab 键补全命令
[root@localhost ~]# mkswap
## C7 支持补全参数, 默认不支持补全, 需要 yum install bash-completion , 且重启系统才生效
## 示例如下
[root@localhost ~]# systemctl restart network
- alias 别名 --> 适用于命令很长的情况, alias 可以列出系统所有的命令(包括自定义的), alias 一部分存在于 用户家目录下 ( /root , /home/username ) 的
.bashrc
, 另一部分存在于 /etc/profile.d/ 下
[root@localhost ~]# alias rn='systemctl restart network.service'; 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 rm='rm -i'
alias rn='systemctl restart network.service'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
## 查看一部分 alias
[root@localhost ~]# cat .bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
## 查看另一部分 alias , 在 /etc/profile.d/ 下的如下脚本中
[root@localhost ~]# cd /etc/profile.d/ ; ls
256term.csh colorgrep.csh colorls.sh lang.sh sh.local which2.csh
256term.sh colorgrep.sh csh.local less.csh vim.csh which2.sh
bash_completion.sh colorls.csh lang.csh less.sh vim.sh
## 示例如下
[root@localhost profile.d]# vim colorls.sh
....
alias ll='ls -l' 2>/dev/null
alias l.='ls -d .*' 2>/dev/null
....
- unalias 取消自定义别名
[root@localhost profile.d]# unalias rn; 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 rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
8.4 通配符
通配符、输入输出重定向
ls *.txt
ls ?.txt
ls [0-9].txt
ls {1,2}.txt
cat 1.txt >2.txt
cat 1.txt >> 2.txt
ls aaa.txt 2>err
ls aaa.txt 2>>err
wc -l < 1.txt
command >1.txt 2>&1
*
表示通配 , 无论个数还是字符都匹配
## 在字符的两边都可以用
[root@arron-02 ~]# ls *.txt
1.txt 2.txt
[root@arron-02 ~]# ls *txt
1.txt 2.txt
[root@arron-02 ~]# ls *txt*
1.txt 1.txt.bak 2.txt 2.txt.bak
[root@arron-02 ~]# ls 1*txt
1.txt
?
, 表示任意一个字符
[root@arron-02 ~]# touch abc.txt xyz.txt peter.txt ; ls *txt
1.txt 2.txt 3.txt 4.txt abc.txt peter.txt xyz.txt
[root@arron-02 ~]# ls ?.txt
1.txt 2.txt 3.txt 4.txt
- [0-9] 满足 0 到 9 的任意一个个数位数字, 且输出的是逐一匹配的; 如果里边是多个数字, [n1n3], 那就逐一匹配这些但数字;
[]
里边也可以是 [0-9a-zA-Z] ; 表示的也是或者的意思
[root@arron-02 ~]# ls [0-9].txt; ls [13].txt ; ls [23].txt ; ls [21].txt ; ls [11].txt
1.txt 2.txt 3.txt 4.txt
1.txt 3.txt
2.txt 3.txt
1.txt 2.txt
1.txt
## [0-9a-zA-Z]
[root@arron-02 ~]# touch X.txt Y.txt z.txt; ls . ;
1.txt 2.txt 3.txt abc.txt peter.txt xyz.txt z.txt
[root@arron-02 ~]# ls [0-9a-zA-Z].txt
1.txt 2.txt 3.txt 4.txt X.txt Y.txt z.txt
{}
跟[]
差不多, 但是字符间要加,
, 但是不支持模糊匹配(即不能加 -) ; 表示的也是或者的意思
[root@arron-02 ~]# ls {1,2,3,a-z}.txt
ls: 无法访问a-z.txt: 没有那个文件或目录
1.txt 2.txt 3.txt
[root@arron-02 ~]# ls {1,2,3,z}.txt
1.txt 2.txt 3.txt z.txt
## 不能输出后缀前有多个字符的文件
[root@arron-02 ~]# ls *txt
1.txt 2.txt 3.txt 4.txt abc.txt peter.txt X.txt xyz.txt Y.txt z.txt
[root@arron-02 ~]# ls [0-9a-zA-Z].txt
1.txt 2.txt 3.txt 4.txt X.txt Y.txt z.txt
[root@arron-02 ~]# ls {1,2,z,abc}.txt
1.txt 2.txt abc.txt z.txt
8.5 输入输出重定向
>
和>>
== 输出重定向和追加
>
, sourcefile > destinationfile , 会将 destinationfile 里边的内容删除, 将 sourcefile 的内容写进去;>>
, sourcefile >> destinationfile , 不会将 destinationfile 里边的内容删除, 而是将 sourcefile 里边的内容写入到 destinationfile 里边去
2>
, sourcefile 2> destinationfile , 将 sourcefile 输出的错误信息重定向到 destinationfile 里边去2>>
, sourcefile 2>> destinationfile , 将 sourcefile 输出的错误信息追加到 destinationfile&>
==>+2>
, 将 sourcefile 输出的错误信息和正确信息 追加到 destinationfile
[root@arron-02 ~]# lsaaa
-bash: lsaaa: 未找到命令
[root@arron-02 ~]# lsaaa 2> z.txt
[root@arron-02 ~]# cat z.txt
-bash: lsaaa: 未找到命令
## &> 正确与错误输出; &>> 正确与错误同时追加
[root@arron-02 ~]# ls {1,2,z,abc}.txt aaa.txt &> Y.txt
[root@arron-02 ~]# cat Y.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
abc.txt
z.txt
[root@arron-02 ~]# ls {1,2,z,abc}.txt aaa.txt &>> Y.txt
[root@arron-02 ~]# cat Y.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
abc.txt
z.txt
ls: 无法访问aaa.txt: 没有那个文件或目录
1.txt
2.txt
abc.txt
z.txt
<
, 输入重定向, 测试不通过
[root@arron-02 ~]# wc -l < 1.txt
3
[root@arron-02 ~]# cat 1.txt
123
123
123
8.6 管道符和作业控制
管道符、作业控制
cat 1.txt |wc -l ; cat 1.txt |grep 'aaa'
ctrl z 暂停一个任务
jobs查看后台的任务
bg[id]把任务调到后台
fg[id]把任务调到前台
命令后面加&直接丢到后台
|
, 管道符, 将前面命令得输出内容传递给后面的命令
## 统计当前命令的个数
[root@arron-02 ~]# ls
1.txt 2.txt 3.txt abc.txt peter.txt xyz.txt z.txt
1.txt.bak 2.txt.bak 4.txt anaconda-ks.cfg X.txt Y.txt
[root@arron-02 ~]# ls |wc -l
13
[root@arron-02 ~]# find ./ -type f
./.bash_logout
./.bash_profile
./.cshrc
./.tcshrc
./anaconda-ks.cfg
./.bash_history
./.ssh/authorized_keys
./1.txt.bak
./2.txt.bak
./2.txt
./.bashrc
./3.txt
./4.txt
./abc.txt
./xyz.txt
./peter.txt
./X.txt
./z.txt
./Y.txt
./1.txt
./.viminfo
[root@arron-02 ~]# find ./ -type f |wc -l
21
## ./ 和 / 表示的不一样
[root@arron-02 ~]# ls /
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@arron-02 ~]# ls ./
1.txt 2.txt 3.txt abc.txt peter.txt xyz.txt z.txt
1.txt.bak 2.txt.bak 4.txt anaconda-ks.cfg X.txt Y.txt
- 任务调整命令
CTRL+Z
暂停一个任务, 相当于将命令调到后台了,fg
表示将命令调到前台 , 后边可接 jobs 命令显示的进程 IDbg
表示将命令调到后台, 后边可接 jobs 命令显示的进程 IDjobs
将暂停的命令列出来/ 丢到后台
[root@arron-02 ~]# vim 1.txt
[1]+ 已停止 vim 1.txt
[root@arron-02 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda3 28G 2.4G 26G 9% /
devtmpfs 481M 0 481M 0% /dev
tmpfs 492M 0 492M 0% /dev/shm
tmpfs 492M 7.5M 485M 2% /run
tmpfs 492M 0 492M 0% /sys/fs/cgroup
/dev/sda1 197M 102M 96M 52% /boot
tmpfs 99M 0 99M 0% /run/user/0
[root@arron-02 ~]# cat 1.txt
123
123
123
[root@arron-02 ~]# fg
vim 1.txt
123
123
123
## jobs 示例 , 相当于将暂停的命令列出来
[root@arron-02 ~]# fg
vim 1.txt
[1]+ 已停止 vim 1.txt
[root@arron-02 ~]# vim abc.txt
[2]+ 已停止 vim abc.txt
[root@arron-02 ~]# vim abc.txt
[3]+ 已停止 vim abc.txt
[root@arron-02 ~]# jobs
[1] 已停止 vim 1.txt
[2]- 已停止 vim abc.txt
[3]+ 已停止 vim abc.txt
## bg 示例, 将命令调到后台去, 调到后台的命令依然在运行, 如果是调到后台的动态命令, 可以在屏幕上运行其他命令,
[root@arron-02 ~]# fg 3
vim abc.txt
fdasfkjdaskt
`f
[root@arron-02 ~]# bg 3
[3]+ vim abc.txt &
[root@arron-02 ~]# jobs
[1]- 已停止 vim 1.txt
[2]+ 已停止 vmstat 1
[root@arron-02 ~]# bg
[2]+ vmstat 1 &
[root@arron-02 ~]# df 0 0 0 670536 2076 184508 0 0 0 0 78 72 0 1 99 0 0
akjfda 0 0 0 670536 2076 184508 0 0 0 0 79 79 0 0 100 0 0
ls 0 0 0 670536 2076 184508 0 0 0 0 60 59 1 1 98 0 0
-bash: dfakjfdals: 未找到命令
[root@arron-02 ~]# ls
1.txt 2.txt 3.txt abc.txt peter.txt xyz.txt z.txt
1.txt.bak 2.txt.bak 4.txt anaconda-ks.cfg X.txt Y.txt
## 只有将后台运行的动态命令调到前台来, 才可以暂停和停止
fg 2 0 0 0 670524 2076 184508 0 0 0 0 112 109 0 1 99 0 0
## CTRL + Z
^Z
[2]+ 已停止 vmstat 1
sleep n
,n
表示秒, 整个命令表示休息多久
[root@arron-02 ~]# jobs
[2] 已停止 vmstat 1
[3]- 已停止 sleep 1000
[4]+ 已停止 sleep 500
## 如果 fg 后边什么都不加, 就会运行排在最下边命令(即离我们最近的暂停的命令)
[root@arron-02 ~]# fg
sleep 500
^Z
[4]+ 已停止 sleep 500
## 让命令在后台运行
[root@arron-02 ~]# bg 3
[3]- sleep 1000 &
[root@arron-02 ~]# jobs
[2]- 已停止 vmstat 1
[3] 运行中 sleep 1000 &
[4]+ 已停止 sleep 500
## 也可以一次性丢到后台去 command & , 它和 bg 一样的效果
[root@arron-02 ~]# sleep 500 &
[1] 3735
[root@arron-02 ~]# jobs
[1]+ 运行中 sleep 500 &
- 在复制终端下,
jobs
后没有原终端的命令显示, 但是可以通过ps aux
查看到进程的
## 但是可以通过 ps aux 查看到进程的
[root@arron-02 ~]# ps aux|grep sleep
root 3735 0.0 0.0 107948 348 pts/1 S 12:59 0:00 sleep 500
root 3889 0.0 0.0 112720 972 pts/2 S+ 13:02 0:00 grep --color=auto sleep