2020/03/16
第七课
第十章:shell基础知识
10.1 什么是shell
shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上,在shell和计算机硬件之间还有一层东西——系统内核。用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
10.1.1 记录命令历史
我们执行过的命令Linux都会记录,预设可以记录1000条历史命令。这些命令保存在用户的家目录的.bash_history文件中。(只有当用户正常退出当前shell时,在当前shell中运行的命令才会保存之.bash_history文件中)
-
! !:连续两个!表示执行上一条指令;
[root@xxj-could ~]# pwd /root [root@xxj-could ~]# !! pwd /root [root@xxj-could ~]#
-
! n:这里的n是数字,表示执行命令历史中的第n条指令;
[root@xxj-could ~]# history | grep 17 17 pwd 24 history | grep 17 [root@xxj-could ~]# !17 pwd /root [root@xxj-could ~]#
-
! 字符串(字符串大于等于1):执行命令历史中最后一次以这个字符串开头的命令。
[root@xxj-could ~]# !pw pwd /root [root@xxj-could ~]#
10.1.2 命令和文件名补全
Tab键:可以补全一个指令、一个路径或者一个文件名。
连续按两次tab键,系统会把所有的命令或者文件都列出来。
10.1.3 别名
alias:把一个常用的并且很长的指令另取名为一个简单易记的指令。
-
执行alias命令,会看到目前系统预设的别名;
[root@xxj-could ~]# 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 which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde' [root@xxj-could ~]#
-
自定义命令的别名,格式:alias [命令别名]=[‘具体的命令’]。
[root@xxj-could ~]# alias aming='pwd' [root@xxj-could ~]# aming /root [root@xxj-could ~]# unalias aming [root@xxj-could ~]# aming bash: aming: command not found [root@xxj-could ~]#
10.1.4 通配符
在bash下,可以使用*来匹配零个或多个字符,用?匹配一个字符。
[root@xxj-could ~]# ls -d /tmp/4_6/test*
/tmp/4_6/test1
[root@xxj-could ~]# touch /tmp/4_6/test111
[root@xxj-could ~]# ls -d /tmp/4_6/test?
/tmp/4_6/test1
[root@xxj-could ~]#
10.1.5 输入/输出重定向
输入重定向用于改变命令的输入,输出重定向用于改变命令的输出。输入重定向命令是<,输出重定向命令是>,错误重定向命令2>以及追加重定向命令>>;
[root@xxj-could ~]# mkdir /tmp/10
[root@xxj-could ~]# cd /tmp/10/
[root@xxj-could 10]# echo "123" > 1.txt
[root@xxj-could 10]# echo "123" >> 1.txt
[root@xxj-could 10]# cat 1.txt
123
123
[root@xxj-could 10]#
10.1.6 管道符
| :用于将前一个命令的输出作为后一个指令的输入
[root@xxj-could 10]# cat /etc/passwd | wc -l
19
[root@xxj-could 10]#
10.1.7 作业控制
-
(Ctrl+Z)键:当运行进程时,可以使它暂停;
-
(Ctrl+C)键:当运行进程时,可以使它终止;
-
fg(foreground的简写)命令:恢复进程(如果有多个进程的话,在fg后jobs命令前面显示的对应数字即可)
-
bd(background的简写)命令:使进程到后台运行(如果有多个进程的话,在fg后jobs命令前面显示的对应数字即可)
-
jobs命令:可以看到被暂停或者在后台运行的任务(多个被暂停的任务前有对应的编号)
-
关掉后台运行的任务:
①在当前的shell下,使用命令fg 编号把任务调到前台,然后按Crtl+C结束任务;
②关闭当前的shell,再次打开另一个shell时,使用jobs命令并不会显示在后台运行或者被暂停的任
务。要像关闭这些任务,则需要先知道它们的pid,然后使用kill命令(如有结束不了的进程,加-9选项)[root@xxj-could ~]# ps aux | grep vmstat //第二个就是pid root 2683 0.0 0.0 148308 1372pts/0 S 10:16 0:00 vmstat 1 root 2685 0.0 0.0 112664 972pts/0 S+ 10:16 0:00 grep --color=auto vmstat
10.2 变量
通常,shell预设的变量都是大写的。变量就是使用一个比较简单的字符串来替代某些具有特殊意义的设定以及数据。就拿以前讲的PATH来讲,它就替代了所有常用命令的绝对路径的设定。
[root@xxj-could 10]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@xxj-could 10]# echo $HOME
/root
[root@xxj-could 10]# echo $PWD
/root
[root@xxj-could 10]#
10.2.1 命令env
env命令:可列出系统预设的全部系统变量(显示的只是环境变量,可以使用set命令把系统预设的全部变量都显示出来)
[root@xxj-could 10]# env
XDG_SESSION_ID=2
HOSTNAME=localhost.localdomain
SELINUX_ROLE_REQUESTED=
SHELL=/bin/bash
TERM=vt100
HISTSIZE=1000
SSH_CLIENT=192.168.20.1 52890 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;4
......
登录不同的用户,这些环境变量的值也不同。当前显示的是root账户的环境变量。简单介绍
一下常见的环境变量:
- HOSTNAME:表示主机的名称。
- SHELL:表示当前用户的shell类型。
- HISTSIZE:表示历史记录数。
- MAIL:表示当前用户的邮件存放目录。
- PATH:该变量决定了shell将到哪些目录中寻找命令或程序。
- PWD:表示当前目录。
- LANG:这是与语言相关的环境变量,多语言环境可以修改此环境变量。
- HOME:表示当前用户的家目录。
- LOGNAME:表示当前用户的登录名。
10.2.2 命令set
set命令与env命令类似,也可以输出环境变量(不仅可以显示系统预设的变量,也可以显示用户自定义的变量)
[root@xxj-could 10]# set
BASH=/usr/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=79
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
HOME=/root
HOSTNAME=localhost.localdomain
HOSTTYPE=x86_64
IFS=$' \t\n'
......
-
显示用户自定义的变量(但是该变量只能在当前shell中生效)
[root@xxj-could ~]# myname=Aming [root@xxj-could ~]# echo $myname Aming [root@xxj-could ~]# set | grep myname myname=Aming [root@xxj-could ~]# bash [root@xxj-could ~]# echo $myname [root@xxj-could ~]# exit exit [root@xxj-could ~]# echo $myname Aming [root@xxj-could ~]#
-
取消某个变量,只要输入unset [变量名]即可。
[root@xxj-could ~]# unset abc
[root@xxj-could ~]# echo $abc
[root@xxj-could ~]#
- Linux下设置自定义变量规则:
- 设定变量的格式为a=b,其中a为变量名,b为变量的内容,等号两边不能有空格。
- 变量名只能由字母、数字以及下划线组成,且不能以数字开头。
- 变量内容带有特殊字符(如空格)时,需要加上单引号。
如果变量内容中本身带有单引号,需要加双引号;
[root@xxj-could ~]# myname='Aming Li'
[root@xxj-could ~]# echo $myname
Aming Li
[root@xxj-could ~]#
如果变量内容中需要用到其他命令,运行结果则可以使用反引号。
[root@xxj-could ~]# myname=`pwd`
[root@xxj-could ~]# echo $myname
/root
[root@xxj-could ~]#
变量内容可以累加其他变量的内容,但需要加双引号。
[root@xxj-could ~]# myname="$LOGNAME"Aming
[root@xxj-could ~]# echo $myname
rootAming
[root@xxj-could ~]#
-
如果想让设置的环境变量一直生效:
①允许系统内所有用户登录后都能使用该变量。
在/etc/profile文件的最后一行加入export myname=Aming,然后运行source /etc/profile就可以生效了。此时再运行bash命令或者切换到其他账户就可以看到效果。[root@xxj-could ~]# echo “export myname=Aming” >> /etc/profile [root@xxj-could ~]# source !$ source /etc/profile [root@xxj-could ~]# bash [root@xxj-could ~]# echo $myname Aming [root@xxj-could ~]# exit exit [root@xxj-could ~]# su - test [root@xxj-could ~]$ echo $myname Aming [root@xxj-could ~]#
②仅允许当前用户使用该变量。
在用户主目录下的.bashrc文件的最后一行加入exprot myname=Aming,然后运行source .bashrc就可以生效了。这时再登陆test账户myname变量则不会生效了。
-
在当前shell中运行bash命令,则会进入一个新的shell,这个shell就是原来shell的子shell。可用pstree指令来查看。
[root@xxj-could ~]# yum install -y psmisc //没有该命令的话就运行安装 [root@xxj-could ~]# pstree | grep bash |-login---bash |-sshd---sshd---bash-+-grep [root@xxj-could ~]# bash [root@xxj-could ~]# pstree | grep bash |-login---bash |-sshd---sshd---bash---bash-+-grep [root@xxj-could ~]#
如果想让这个变量在子shell中生效,则要用到export指令:
[root@xxj-could ~]# abc=123 [root@xxj-could ~]# echo $abc 123 [root@xxj-could ~]# bash [root@xxj-could ~]# echo $abc [root@xxj-could ~]# exit exit [root@xxj-could ~]# export abc [root@xxj-could ~]# echo $abc 123 [root@xxj-could ~]# bash [root@xxj-could ~]# echo $abc 123 [root@xxj-could ~]#
10.3 系统环境变量与个人环境变量的配置文件
-
/etc/profile:这个文件预设了几个重要的变量,例如PATH、USER、LOGNAME、MAIL、INPUTRC、HOSTNAME 、HISTSIZE,、umask等。
-
/etc/bashrc:这个文件主要预设umask以及PS1。这个PS1就是我们在输入命令时前面的那串字符。
Linux系统的PS1就是[root@localhost ~],看一下PS1的值为:[root@xxj-could ~]# echo $PS1 [\u@\h \W]\$ [root@xxj-could ~]#
其中,\u指用户,\h指主机名,\W指当前目录,$指字符# (如果是普通用户.则显示为$)。
-
除了以上两个系统级别的配置文件外,每个用户的主目录下还有以下几个隐藏文件。
- .bash_profile:该文件定义了用户的个人化路径与环境变量的文件名称。每个用户都可使用该文件输入专属于自己的shell信息,当用户登录时,该文件仅仅执行一次。
- -bashrc:该文件包含专属于自己的shell的bash信息,当登录或每次打开新的shell时,该文件会被读取。例如,你可以将用户自定义的別名或者自定义变量写到这个文件中。
- .bash_history:该文件用于记录命令历史。
- .bash_logout:当退出shell时,会执行该文件。你可以将一些淸理的工作放到这个文件中。
10.4 Linux shell中的特殊符号
10.4.1 *代表零个或多个任意字符
[root@xxj-could ~]# ls /tmp/4_6/test*
/tmp/4_6/test1 /tmp/4_6/test111
[root@xxj-could ~]#
10.4.2 ?只代表一个任意的字符
[root@xxj-could ~]# touch /tmp/4_6/testa
[root@xxj-could ~]# ls -d /tmp/4_6/test?
/tmp/4_6/test1 /tmp/4_6/testa
[root@xxj-could ~]#
10.4.3 注释符号#
[root@xxj-could ~]# abc=123 #aaaaa
[root@xxj-could ~]# echo $abc
123
[root@xxj-could ~]#
10.4.4 脱义字符\
这个字符会将后面的特殊符号(如*)还原为普通字符:
[root@xxj-could ~]# ls -d test\*
ls: 无法访问test*: 没有那个文件或目录
[root@xxj-could ~]#
10.4.5 管道符|
将前面命令的输出作为后面命令的输入。这里提到的后面的命令,并不是所有命令都可以的,一般针对文档操作的命令比较常用。例如cat、less、head、tail、grep、cut、sort、wc、uniq、tee、tr、split、sed、awk等。
[root@xxj-could ~]# cat testb.txt | wc -l //wc -l用来计算一个文档有多少行
4
[root@xxj-could ~]#
10.4.6 命令cut
cut命令用来截取某一个字段,格式:cut -d ‘分隔字符’ [-cf]n,这里的n是指数字。
-
-d:后面跟分隔字符,分隔字符要用单引号括起来。
-
-c:后面接的是第几个字符。
-
-f:后面接的是第几个区块。
[root@xxj-could ~]# cat /etc/passwd | cut -d ':' -f 1 | head -5 root bin daemon adm lp [root@xxj-could ~]# head -n2 /etc/passwd | cut -c2 o i [root@xxj-could ~]# head -n2 /etc/passwd | cut -c1 r b [root@xxj-could ~]# head -n2 /etc/passwd | cut -c1-10 root:x:0:0 bin:x:1:1: [root@xxj-could ~]# head -n2 /etc/passwd | cut -c1,3,10 ro0 bn: [root@xxj-could ~]#
-d后面加冒号作为分隔符,-f1表示截取第一段;-f与1之间空格可有可无;
-c后面n可以是一个数字n,或是区间n1-n2,还可以是多个数字n1、n2、n3。
10.4.7 命令sort
sort命令用做排序,格式为sort [-t 分隔符] [-kn1,n2] [-nru]。这里n1,n2指的是数字。
-
-t:后面跟分隔字符,作用跟cut的-d选项一样。
-
-n:表示使用纯数字排序。
-
-r:表示反向排序。
-
-u:表示去重复。
-
-kn1,n2:表示由n1区间排序到n2区间,可以只写-kn1,即对n1字段排序。
[root@xxj-could ~]# head -n5 /etc/passwd | sort //不加任何选项,从首字符向后依次按ASCII码值进行比较,最后按升序输出 adm:x:3:4:adm:/var/adm:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin root:x:0:0:root:/root:/bin/bash [root@xxj-could ~]# head -n5 /etc/passwd | sort -t: -k3 -n // //k后面数字3表示对第3区域的字符串排序,-n表示用纯数字排序 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin [root@xxj-could ~]# head -n5 /etc/passwd | sort -t: -k3,5 -r //k后面数字3,5表示对第3区域至第5区域的字符串排序,-r表示反向排序 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin root:x:0:0:root:/root:/bin/bash [root@xxj-could ~]#
10.4.8 命令wc
wc命令用户统计文档的行数、字符数或词数。
-
-l:统计行数。
-
-m:统计字符数。
-
-w:统计词数。
[root@xxj-could ~]# wc /etc/passwd 19 27 846 /etc/passwd [root@xxj-could ~]# wc -l /etc/passwd 19 /etc/passwd [root@xxj-could ~]# wc -m /etc/passwd 846 /etc/passwd [root@xxj-could ~]# wc -w /etc/passwd 27 /etc/passwd [root@xxj-could ~]#
10.4.9 命令uniq
uniq命令用来删除重复的行。
-
-c:表示统计重复的行数,并把行数写在前面。
[root@xxj-could 4_6]# cat testb.txt 111 222 333 444 111 [root@xxj-could 4_6]# uniq testb.txt 111 222 333 444 111 [root@xxj-could 4_6]# sort testb.txt | uniq 111 222 333 444 [root@xxj-could 4_6]# sort testb.txt | uniq -c 2 111 1 222 1 333 1 444 [root@xxj-could 4_6]#
10.4.10 命令tee
tee命令后面跟文件名,其作用类似于重定向>,但它比重定向多一个功能,即把文件写入到后面所跟的文件时,还显示在屏幕上。该命令通常用于管道符|后。
[root@xxj-could 4_6]# echo "aaaaaaaaaaaaaaaaaaaaa" | tee testb.txt
aaaaaaaaaaaaaaaaaaaaa
[root@xxj-could 4_6]# cat testb.txt
aaaaaaaaaaaaaaaaaaaaa
[root@xxj-could 4_6]#
10.4.11 命令tr
tr命令用于替换字符,常用来处理文档中出现的特殊符号。
- -d:表示删除某个字符,后面跟要删除的字符;
- -s:表示删除重复的字符。
①tr命令常用于把小写字母变成大写字母:
[root@xxj-could ~]# head -n2 /etc/passwd |tr '[a-z]' '[A-Z]'
ROOT:X:0:0:ROOT:/ROOT:/BIN/BASH
BIN:X:1:1:BIN:/BIN:/SBIN/NOLOGIN
②tr命令还可以替换一个字符:
[root@xxj-could ~]# grep 'root' /etc/passwd | tr 'r' 'R'
Root:x:0:0:Root:/Root:/bin/bash
opeRatoR:x:11:0:opeRatoR:/Root:/sbin/nologin
[root@xxj-could ~]#
10.4.12 命令split
split命令用于切割文档。
-
-b:表示依据大小来分割文档,单位为byte。
[root@xxj-could ~]# mkdir split-dir [root@xxj-could ~]# cd !$ cd split-dir [root@xxj-could split-dir]# cp /etc/passwd ./ [root@xxj-could split-dir]# split -b 500 passwd [root@xxj-could split-dir]# ls passwd xaa xab [root@xxj-could split-dir]#
如果split不指定目标文件名,则会以xaa,xab…这样的文件名来存取切割后的文件,当然,我们也可以指定目标文件名:
[root@xxj-could split-dir]# rm -f xa*
[root@xxj-could split-dir]# split -b 500 passwd 123
[root@xxj-could split-dir]# ls
123aa 123ab passwd
[root@xxj-could split-dir]#
-
-l:表示依据行数来分割文档。
[root@xxj-could split-dir]# rm -f 123a* [root@xxj-could split-dir]# split -l 10 passwd [root@xxj-could split-dir]# wc -l * 19 passwd 10 xaa 9 xab 38 total [root@xxj-could split-dir]#
10.4.13 特殊符号$
符号$可以用做变量前的标识符。还可以和!结合起来使用。
[root@xxj-could 4_6]# ls testb.txt
testb.txt
[root@xxj-could 4_6]# ls !$
ls testb.txt
testb.txt
[root@xxj-could 4_6]#
10.4.14 特殊符号;
想在一行中运行两个或两个以上的命令。需要在命令之间加符号;。
[root@xxj-could ~]# mkdir testdir ; touch test1.txt ; touch test2.txt ; ls -d test*
test1.txt test2.txt testdir
[root@xxj-could ~]#
10.4.15 特殊符号~
符号~表示用户的家目录,root用户的家目录是/root,普通用户则是/home/username。
[root@xxj-could ~]# cd ~
[root@xxj-could ~]# pwd
/root
[root@xxj-could ~]# su xxj
[xxj@xxj-could root]$ cd ~
[xxj@xxj-could ~]$ pwd
/home/xxj
[xxj@xxj-could ~]$
10.4.16 特殊符号&
把一条命令放在后台执行,则需要加上符号&。
[root@xxj-could ~]# sleep 30 &
[1] 7668
[root@xxj-could ~]# jobs
[1]+ Running sleep 30 &
[root@xxj-could ~]#
10.4.17 重定向符号>、>>、2>和2>>
其中>表示取代,>>:表示追加,2>:错误重定向,2>>:错误追加重定向。
[root@xxj-could ~]# ls aaaa
ls: cannot access aaaa: No such file or directory
[root@xxj-could ~]# ls aaaa 2> /tmp/error
[root@xxj-could ~]# cat /tmp/error
ls: cannot access aaaa: No such file or directory
[root@xxj-could ~]# ls aaaa 2>> /tmp/error
[root@xxj-could ~]# cat /tmp/error
ls: cannot access aaaa: No such file or directory
ls: cannot access aaaa: No such file or directory
[root@xxj-could ~]#
10.4.18 中括号 [ ]
中括号内为字符组合,代表字符组合中的任意一个,可以是一个范围(1-3,a-z)
[root@xxj-could 1]# ls -d test*
test1.txt test2.txt testb.txt testdir
[root@xxj-could 1]# ls -d test[1-3].txt
test1.txt test2.txt
[root@xxj-could 1]# ls -d test[12b].txt
test1.txt test2.txt testb.txt
[root@xxj-could 1]# ls -d test[1-9].txt
test1.txt test2.txt
[root@xxj-could 1]# ls -d test[1-9a-z].txt
test1.txt test2.txt testb.txt
[root@xxj-could 1]#
10.4.19 特殊符号&&和||
用于多条命令之间的特殊符号。
-
command1 ; command2 使用;时,不管command1是否执行成功,都会执行command2。
-
command1 && command2 使用&&时,只有command1执行成功后,command2才会执行,否则command2不执行。
-
command1 | | command2 使用| |时,command1执行成功后则command2不执行,否则执行command2.即command1和command2中总有一条命令会执行。
[root@xxj-could ~]# rm -rf test* [root@xxj-could ~]# touch test1 test3 [root@xxj-could ~]# ls test2 && touch test2 ls: cannot access test2: No such file or directory [root@xxj-could ~]# ls test2 ls: cannot access test2: No such file or directory [root@xxj-could ~]# ls test2 || touch test2 ls: cannot access test2: No such file or directory [root@xxj-could ~]# ls test* test1 test2 test3 [root@xxj-could ~]#