什么是shell
shell是一个命令解释器,提供用户和机器之间的交互。它支持特定语法,比如逻辑判断、循环等。我们默认创建一个用户,它的默认的shell是bin、bash,这就是它的shell。每个用户都有自己的shell。CentOS用的shell是bash。同时系统中还有zsh和ksh。
命令历史
我们输入的命令是有一个文件保存,/root/.bash_history。我们可以查看一下
[root@localhost ~]# ls /root/.bash_history
/root/.bash_history
我们也可以用history来查询我们输入过的命令,它最多可以存1000条,它是由一个环境变量决定的,这是系统内置的环境变量。
[root@localhost ~]# echo $HISTSIZE
1000
有时我们在查询的时候会出现超过1000条的情况,这时因为它还没有真正的写入到文件中去,因为我们现在运行的这些命令暂时都存在内存中。history -c可以将内存中的命令清空,但是它不会删除配置文件中的历史命令。只有我们退出终端的时候,历史命令才会存到配置文件中。
改变HISTSIZE
[root@localhost ~]# vi /etc/profile
然后找到HISTSIZE
将数值更改
HISTSIZE=1500
然后输入wq保存
虽然我们已将更改了它的设置,但是依然没有生效,如果我们想让它生效,一是退出终端,二是source /etc/profile。我们一般都会用第二种方法
[root@localhost ~]# echo $HISTSIZE
1000
[root@localhost ~]# source /etc/profile
[root@localhost ~]# echo $HISTSIZE
1500
这样,改变就生效了。
如果我们想知道对应的命令是什么时候执行的,只要给这个变量重新赋值就可以
[root@localhost ~]# HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S"
然后查看是否更改成功
[root@localhost ~]# echo $HISTTIMEFORMAT
%Y/%m/%d %H:%M:%S
因为这个环境变量只在当前当前终端生效的,所以我再打开一个终端里面是空的,所以系统默认这个变量是不存在的,入股我们想让他全局生效,那么就要重新的去编辑它
[root@localhost ~]# vim /etc/profile
然后将它放在我们刚才更改的HISTSIZE的下面
HISTSIZE=1500
HISTTIMEFORMAT="%Y/%m/%d %H:%M:%S"
然后执行 source /etc/profile
然后保存退出,这样就可以让他全局生效了
这就是怎样将你的历史命令格式改一下。
这里还有几个小技巧
!!执行上一条命令
[root@localhost ~]# !!
source /etc/profile
!n 这里n代表命令,只要我们前面输入!,后面接命令所在的行号,就可以执行那条命令
67 2018/02/17 19:10:15 ll
[root@localhost ~]# !67
ll
总用量 428
drwxrwxrwx. 2 root root 6 1月 21 14:12 aming
-rw-------. 1 root root 1402 12月 14 22:02 anaconda-ks.cfg
drwxr-xr-x. 20 aming aming 4096 2月 16 20:25 apr-util-1.6.1
-rw-r--r--. 1 root root 428595 10月 23 01:33 apr-util-1.6.1.tar.bz2
!+命令,他会从最后往上找第一个以这个命令开头的命令,比如我们要找echo这条命令
[root@localhost ~]# !echo
echo $HISTTIMEFORMAT
%Y/%m/%d %H:%M:%S
命令补全
tab键可以补全命令,命令参数补全,还可以补全路径。有时需要敲一下,有时则需要敲两下。
补全参数需要我们下载一个包
[root@localhost ~]# yum install -y bash-completion
但是安装完后不会生效,需要我们重启后才能生效
在什么情况下我们需要按两下呢?比如我们输入ls这个命令,然后敲击两下tab键
[root@localhost ~]# ls
ls lsattr lsblk lscpu lsinitrd lsipc lslocks lslogins lsmod lsns lspci lsscsi
他会出现这么多以ls开头的命令,我们只要找到需要的命令,然后继续往后输入。如果这个命令没有其他的选择时,只要按一下tab键就可以。
alias(别名)
如果一条命令过长,我们可以给他做一个别名,这样会节省时间
比如我们长期网络服务的命令很长,那我们就可以给他做一个别名,我们将网络重启的命令设置为restartnet
[root@localhost ~]# alias restartnet='systemctl restart network.service'
这样,如果我们要重启网络服务,就输入restartnet就可以了。
直接输入alias来查询我们当前系统下所有的alias
[root@localhost ~]# 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'
那么这些alias都存放在哪里呢?
在用户家目录下面的.bashrc下有三条alias,其他在 /etc/profile.d/
通过查询,我们可以看到目录下有很多的目录,这些目录中就有其他一些alias。
[root@localhost profile.d]# ls
256term.csh bash_completion.sh colorgrep.sh colorls.sh lang.sh less.sh vim.sh which2.sh
256term.sh colorgrep.csh colorls.csh lang.csh less.csh vim.csh which2.csh
取消自定义别名
输入unalias就可以取消别名
[root@localhost ~]# unalias restartnet
[root@localhost ~]# restartnet
-bash: restartnet: 未找到命令
通配符
- 代表通配,比如我们当前目录下有3个txt文件,那我们就可以这样操作
[root@localhost ~]# ls *.txt
111.txt 1.txt 2.txt
这样,当前目录下所有txt格式的文件就都被查找出来了,它部分什么字符,也不分几个字符,都会被找出来。
? 表示任意一个字符,比如我们创建了一些文件
111.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt aa.txt a.txt bb.txt b.txt c.txt d.txt e.txt f.txt g.txt vv.txt zz.txt
这里面文件名有一个字符,也有多个字符,那我们以?.txt来查找的话只能匹配出文件名是一个字符的文件
[root@localhost ~]# ls ?.txt
1.txt 2.txt 3.txt 4.txt 5.txt 6.txt a.txt b.txt c.txt d.txt e.txt f.txt g.txt
【】按照范围查找
我们可以在【】内写入文件名的范围
[root@localhost ~]# ls [1-3].txt
1.txt 2.txt 3.txt
[root@localhost ~]# ls [13].txt
1.txt 3.txt
[root@localhost ~]# ls [23].txt
2.txt 3.txt
同样中括号里也可以写字母
[root@localhost ~]# ls [a-z].txt
a.txt b.txt c.txt d.txt e.txt f.txt g.txt
{}这也是按范围查找,它的作用和【】类似,但是{}内要加上","去分割里面的要查找的内容
[root@localhost ~]# ls {1,2,3,a}.txt
1.txt 2.txt 3.txt a.txt
输入输出重定向
:重定向,他会将前面命令的输出,直接输入到后面的文件中去。>后面文件中的内容删除,>将前面的文件内容填充进去。
:追加重定向,他不会将后面的文件内容删除,他只会将前面文件的内容追加到后面文件内容的结尾处。
2>:错误重定向,他会把这么命令产生的错误信息指定输入到一个文件中去。比如我们运行一个错误信息
[root@localhost ~]# lsaaaaaa
-bash: lsaaaaaa: 未找到命令
他会提示这个名命令是错误的
这时候我们在命令后面加上2>
[root@localhost ~]# lsaaaaaa 2> a.txt
[root@localhost ~]# cat a.txt
-bash: lsaaaaaa: 未找到命令
这样,错误信息就会追加到指定的文件中去
2>>错误追加重定向,他会将错误信息追加到指定文件的结尾处
[root@localhost ~]# lbbbbba 2> a.txt
[root@localhost ~]# cat a.txt
-bash: lbbbbba: 未找到命令
[root@localhost ~]# lbcccvvv 2>> a.txt
[root@localhost ~]# cat a.txt
-bash: lbbbbba: 未找到命令
-bash: lbcccvvv: 未找到命令
&>他是结合了>和2>的重定向,他可以将正确和错误的输出信息全部定向到指定文件。同时他也可以追加&>>
[root@localhost ~]# ls [12].txt rrr.txt &> a.txt
[root@localhost ~]# cat a.txt
ls: 无法访问rrr.txt: 没有那个文件或目录
1.txt
2.txt
当我们能运行一条命令时,既有正确的输出,也有错误的输出,而我们想将正确和错误的分定向到不同的文件中去,那我们可以这样做。这在我们以后写shell会用到很多。
[root@localhost ~]# ls [12].txt rrr.txt > a.txt 2>1.txt
[root@localhost ~]# cat a.txt
1.txt
2.txt
[root@localhost ~]# cat 1.txt
ls: 无法访问rrr.txt: 没有那个文件或目录
这样,我们就将正确的定向到a.txt,错误的定向到1.txt。
<:输入重定向,我们可以将后面的文本文档输入重定到前面的命令中去
[root@localhost ~]# wc -l < 1.txt
1
而文件和文件是不能输入重定的,他必须是一个命令才可以
[root@localhost ~]# 2.txt < 1.txt
-bash: 2.txt: 未找到命令