8.1 shell介绍
shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。
用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作。
8.2 命令历史
- history命令,-r和-w
- .bash_history
- 最大1000条
- 变量HISTSIZE
- /etc/profile中修改
- HISTTIMEEFORMAT="%Y%m%d %H:%M:%S"
- 永久保存chattr +a ~/.bash_history
- !!
- !n
- !word
[root@localhost ~]#grep -rn "HISTFILESIZE" #命令或变量找不见时可以搜索
[root@localhost ~]#history -r #将文件中的命令记忆读出到当前内存,一般登录时候会自定进行
[root@localhost ~]#history -w #将目前内存中的命令写入到history文件,一般登出时候会自定进行
[root@localhost ~]# ls /root/.bash_history
[root@localhost ~]# cat !$ #关机再保存,‘!’, 表示执行上一条指令
[root@localhost ~]# echo $HISTSIZE #history 命令如果未改动过环境变量,默认可以把最近1000条命令历史打印出来。
1000
[root@localhost ~]# history -c #清空内存命令,不能清空配置文件
[root@localhost ~]# vim /etc/profile #然后使用/HISTSIZE搜索HISTSIZE,修改HISTSIZE大小为5000
[root@localhost ~]# source /etc/profile #使命令生效,或者重启终端
[root@localhost ~]# echo $HISTSIZE
5000
[root@localhost ~]# HISTTIMEFORMAT="%Y%m%d %H:%M:%S"
[root@localhost ~]# echo $HISTTIMEFORMAT #同样可以在/etc/profile 里面设置
%Y%m%d %H:%M:%S
[root@localhost ~]# hstory
-bash: hstory: 未找到命令
[root@localhost ~]# history
1 20180813 19:49:09cd
2 20180813 19:49:09ls /root
3 20180813 19:49:09mkdir /root/.ssh
......
[root@localhost ~]# chattr +a ~/.bash_history #a权限,只能追加,不能删除,就不用设置HISTSIZE
1) !! 执行和显示上一次命令的结果
[root@localhost ~]# pwd
/root
[root@localhost ~]# !!
pwd
/root
2) !n 这里的n是数字,表示执行命令历史中第n条指令,例如 !1002 表示执行命令历史中第1002个命令;
[root@localhost ~]# history |grep 1002
1002 pwd
1015 history |grep 1002
[root@localhost ~]# !1002
pwd
/root
3) !字符串 (字符串大于等于1),例如 !pw 表示执行命令历史中最近一次以 ‘pw’ 为开头的指令。
[root@localhost ~]# !pw
pwd
/root
补充:
- souce命令
当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录;这时就想到用source命令,如:source /etc/profile
对source进行了学习,并且用它与sh 执行脚本进行了对比,现在总结一下。
source命令:
source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令。
功能:使Shell读入指定的Shell程序文件并依次执行文件中的所有语句
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
用法:
source filename 或 . filename
source命令(从 C Shell 而来)是bash shell的内置命令;点命令(.),就是个点符号(从Bourne Shell而来)是source的另一名称。
source filename 与 sh filename 及./filename执行脚本的区别在那里呢?
1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。
2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
举例说明:
1.新建一个test.sh脚本,内容为:A=1
2.然后使其可执行chmod +x test.sh
3.运行sh test.sh后,echo $A,显示为空,因为A=1并未传回给当前shell
4.运行./test.sh后,也是一样的效果
5.运行source test.sh 或者 . test.sh,然后echo $A,则会显示1,说明A=1的变量在当前shell中
- w命令-->用来查看登录者的信息及他们的行为
[root@localhost ~]# w #https://blog.csdn.net/jerry_1126/article/details/52088987
20:44:12 up 56 min, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root tty1 19:48 56:12 0.05s 0.05s -bash
root pts/0 192.168.224.1 19:49 4.00s 0.38s 0.01s w
8.3 命令补全和别名
- tab键,敲一下自动补全,敲两下显示所有以这个开头的命令
- centos7 支持参数补全,需安装包 yum install -y bash-completion,然后重启reboot才生效
rpm -qa bash-completiom
- alias别名给命令重新起个别名 :alias [命令别名]=['具体的命令']
alias restarnet='systemctl restart network.service' #用户家目录里面的.bashrc和/etc/profile.d
- 取消自定义别名unalias + 别名
8.4 通配符
在bash下,可以使用:
* 来匹配零个或多个字符
? 匹配一个字符
[]满足一个范围[0-9a-zA-Z]中的一个
{}或的意思,{a,b,c,1,2,3}逗号隔开,满足一个
[^]有且仅有一个,且不是所枚举的字符,如[^a-zA-Z]
#注释符号
\转义符,将特殊字符或通配符还原成一般字符
|管道符
; 命令连接符,连续执行多个命令
~当前用户家目录
&工作控制,放在命令后面,将指令变成后台工作
!逻辑非
> >> << < 数据流重定向
' ' 单引号,无法引用变量
" "双引号,可以引用变量
` ` 反引号,指令引用,类似$(command)
[root@localhost tmp]# ls
222.txt 333.txt shadow-text.txt systemd-private taroo1 test01 vimtest01.txt vmware-root zip-test
[root@localhost tmp]# ls *.txt
222.txt 333.txt shadow-text.txt vimtest01.txt
[root@localhost tmp]# ll *.tx*
-rw-rw-r--. 1 panyu001 panyu001 8927 8月 4 16:12 222.txt
-rwx--x--x. 1 panyu001 root 80 8月 6 21:51 333.txt
-rw-r--r--. 1 root root 2018 8月 6 21:45 shadow-text.txt
-rw-r--r--. 1 root root 670293 8月 12 22:22 vimtest01.txt
[root@localhost tmp]# ls ???.txt
222.txt 333.txt
[root@localhost tmp]# ls [0-300].txt
ls: 无法访问[0-300].txt: 没有那个文件或目录
[root@localhost tmp]# ls [2-3][2-3][2-3].txt
222.txt 333.txt
[root@localhost tmp]# ls [2][23][23]*
222.txt
[root@localhost tmp]# ls [0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]
taroo1
test01:
111.txt 222
[root@localhost tmp]# ls {222,333}.txt
222.txt 333.txt
8.5 输入输出重定向
- cat 1.txt > 2.txt #覆盖
- cat 1.txt >> 2.txt #追加
- ls aaa.txt 2>err #错误输出信息输入到指定文件覆盖,err为指定文件如a.txt
- ls aaa.txt 2>>err #错误输出信息输入追加到指定文件,err为指定文件如a.txt
?? eof?
黑洞 > /dev/null
while ((1==1));do echo nihao >/dev/null;done
>+2> == &> 正确和错误重定向 ;也可写成: ls [12].txt 3.txt >a.txt 2>b.txt
[root@localhost tmp]# ls [12].txt 3.txt &>a.txt
[root@localhost tmp]# cat a*
ls: 无法访问b.txt: 没有那个文件或目录
1.txt
2.txt
- wc -l < 1.txt #输入重定向(几乎不用) ,wc - c 统计字节数、 - l 统计行数、 - w 统计字数。
8.6 管道符 | 和作业控制
- 管道符的作用是将前面一个命令的输出作为后面一个命令的输入
[root@localhost ~]# cat /etc/passwd |wc -l
27
[root@localhost ~]# cat /etc/passwd |grep "root"
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
作业控制:
1.当一个进程运行时,ctrl+z 可以暂停这个任务
[root@localhost ~]# vim 1.txt
^Z
[1]+ 已停止 vim 1.txt
2.暂停时,jobs显示暂停任务
[root@localhost ~]# vim 2.txt
[2]+ 已停止 vim 2.txt
[root@localhost ~]# jobs
[1]- 已停止 vim 1.txt
[2]+ 已停止 vim 2.txt
2.当暂停后,可以输入fg(foreground简写)命令来恢复这个进程,让它在前端继续运行。多个任务输入fg n
3.我们也可以使用命令bg(background简写)将暂停的进程直接丢到后台运行。输出信息会显示,多个任务输入bg n,不加是最后一个
[root@localhost ~]# vmstat 1
[root@localhost ~]# bg #后台运行,但是输出信息会不停显示,也可命令后加 &,命令直接后台运行
[root@localhost ~]# fg #弄到前台再暂停,ctrl + Z
pkill pname
kill -9 ???
补充:
- vmstat 查看系统消耗如CPU,之后频繁用到https://blog.csdn.net/ty_hf/article/details/63394960
- sleep n: 休息n s
- ps 显示进程 Process Status :ps aux
8.7/8.8 shell变量
PATH、HOME、PWD、LOGNAME、HOSTNAME #变量就是使用一个比较简单的字符串来代替某些具有特殊意义的设定以及数据。
环境变量PATH,它是shell预设的一个变量,通常shell预设的变量都是大写的。
[root@localhost ~]# env #系统环境变量,列出系统预设的全部系统变量
[root@localhost ~]# set #系统变量和自定义变量
[root@localhost ~]# a=111
[root@localhost ~]# set |grep 111
a=111
[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# echo $HOME
/root
[root@localhost ~]# echo $HISTSIZE
5000
命名规则,略
- HOSTNAME:表示主机的名称;
- SHELL:表示当前用户的shell类型;
- HISTSIZE:表示历史记录数;
- MAIL:表示当前用户的邮件存放目录;
- PATH:改变量决定了shell将到那些目录中寻找命令或者程序;
- PWD:表示当前目录;
- LANG:这是与语言相关的环境变量,多语言环境可以修改此环境变量;
- HOME:表示当前用户的家目录;
- LOGNAME:表示当前用户的登录名;
命令set
- 命令set不仅可以显示系统预设的环境变量,还可以显示用户自定义的变量。
自定义变量规则:
- 设定变量的格式为a=b,其中a为变量名,b为变量的内容,等号两边不能有空格;
- 变量名只能由字母,数字以及下划线组成,而且不能以数字开头。
- 当变量值带有特殊字符(如空格)时,需要加上单引号。
[root@localhost ~]# name=l em
-bash: em: 未找到命令
[root@localhost ~]# name='l $em'
[root@localhost ~]# echo $name #特殊符号显示用单引号
l $em
[root@localhost ~]# name="l'em" #变量内容本身就带有单引号,这个时候需要加上双引号
[root@localhost ~]# echo $name
l'em
[root@localhost ~]# name=`pwd` #变量内容中需要用到其他命令,运行结果则可以使用反引号;
[root@localhost ~]# echo $name
/root
[root@localhost ~]# a=1
[root@localhost ~]# b=2
[root@localhost ~]# c=3
[root@localhost ~]# d="$a$b$c" #变量内容可以累加其他变量的内容,但需要加上双引号
[root@localhost ~]# echo $d
123
[root@localhost ~]# echo $SSH_TTY #查看当前在哪个终端下:
/dev/pts/0
[root@localhost ~]# bash #如果再当前shell中运行bash命令,则会进入一个新的shell中,这个shell是原来shell的子shell
[root@localhost ~]# yum install -y psmisc #我们可以用pstree来查看: 需要先安装这个包
[root@localhost ~]# pstree
[root@localhost ~]# export a=11 #设置向下全局变量(不会向上全局),但是不会让它的父shell和其他终端的shell生效。非全局变量只能在本地local的bash使用。
[root@localhost ~]# exit 退出当前BASH
[root@localhost ~]#unset a #取消变量
8.9 系统环境变量和个人环境变量
- /etc/profile #用户环境变量,交互,登录才执行 系统层次
- /etc/bashrc #用户不用登录,执行shell就生效 用户层次
- ~/.bashrc #执行新的shell脚本时每次都调用,可以将用户之定义的alias或者自定义变量写到这个文件中
- ~/.bash_profile #用户登录时加载,调用.bashrc,该文件仅仅执行一次
- ~/.bash_history #显示命令执行历史
- ~/.bash_logout #退出shell时的操作,可以把一些清理的工作放到这个文件中
- PS1='[\033[01;32m]\u@\h[\033[00m]:[\033[01;36m]\w[\033[00m]$ ' #带颜色显示,PS2为命令行脚本操作
- \u 用户名 \h主机名 \t 时间 \W 当前目录 \w 目录的完整路径 $ 就是#,如果普通用户就是$
- /etc/profile 设置系统环境变量,不管针对哪个用户这些环境变量都会生效,但是设置这个配置文件不太好,编辑的时候会有一段提示: 这不是一个好主意来改变这个文件,除非你知道你 正在做的事情。如果你想更改某些环境变量,最好在/etc/profile.d /下去自定义,创建格式为XXX.sh, 在未来的更新将防止合并的必要性。
[root@localhost ~]# ls /etc/profile.d #此目录下的脚本文件用户登录时加载
colorls.csh glib2.csh lang.csh less.csh path.sh vim.sh
colorls.sh glib2.sh lang.sh less.sh vim.csh which2.sh
[root@localhost ~]# vim /etc/profile.d/path.sh
#!/bin/path
export PATH=$PATH:/tmp/:/data/bin/
[root@localhost ~]# source /etc/profile #编辑完后要source /etc/profile,加载的时候会调用profile.d下面的所有文件。
- /etc/bashrc 设置PS1和umask; 它和/etc/profile一样,在/etc/bashrc设置不好,要在/etc/profile.d目录下去定义,创建格式为.sh的文件
[root@localhost ~]# vim /etc/profile.d/umask.sh
#bsah/bin
PS1="[\u@\h-\t \W]\$ "
[root@lem ~]# source /etc/profile
[root@lem-23:35:13 ~]$ ls
补充:
/etc/profile 文件
当一个用户登录Linux系统或使用su -命令切换到另一个用户时,也就是Login shell 启动时,首先要确保执行的启动脚本就是 /etc/profile 。
敲黑板:只有Login shell 启动时才会运行 /etc/profile 这个脚本,而Non-login shell 不会调用这个脚本。
一些重要的变量就是在这个脚本文件中设置的,含义如下:
- PATH: 预设可执行文件或命令的搜索路径。
- USER: 用户登录时使用的用户名。
- LOGNAME: 其值为$USER。
- HOSTNAME: 所使用的主机名。
- MAIL: 存放用户电子邮件的邮箱(实际上是一个ASCII码文件)。
- HISTSIZE: 历史记录的行数。
- INPUTRC: 存放的是针对键盘热键的信息(也是一个ASCII码文件)
要注意的是在/etc/profile 文件中设置的变量是全局变量。
/etc/profile.d 目录中的脚本文件
在/etc/profile.d 目录中存放的是一些应用程序所需的启动脚本,其中包括了颜色、语言、less、vim及which等命令的一些附加设置。
这些脚本文件之所以能够 被自动执行,是因为在/etc/profile 中使用一个for循环语句来调用这些脚本。而这些脚本文件是用来设置一些变量和运行一些初始化过程的。
大致介绍一下/etc/profile.d 目录下一些脚本文件中的具体内容。首先,切换到/etc/profile.d 目录,之后使用ls命令列出/etc/profile.d 目录中的所有脚本文件(在这个目录中只有脚本文件)。
goddog@ubuntu:~$ cd /etc/profile.d
goddog@ubuntu:/etc/profile.d$ ls
apps-bin-path.sh cedilla-portuguese.sh vte-2.91.sh
bash_completion.sh qtubuntu-print.sh
使用file命令确定apps-bin-path.sh文件的类型,确定是一个ASCII码文件之后,使用cat命令列出 apps-bin-path.sh 文件中的全部内容:
goddog@ubuntu:/etc/profile.d$ file apps-bin-path.sh
apps-bin-path.sh: ASCII text
goddog@ubuntu:/etc/profile.d$ cat apps-bin-path.sh
# Expand the $PATH to include /snap/bin which is what snappy applications
# use
PATH=$PATH:/snap/bin
如果对其他的脚本文件的内容感兴趣,可以使用以上的方法确认文件的类型之后再显示脚本文件中的内容。
- 下面以jdk的安装为例
vi /etc/profile.d/java.sh
在新的java.sh中输入以下内容:
#set java environment
JAVA_HOME=/var/mysoft/jdk1.7.0_80
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME PATH
保存退出,然后给java.sh分配权限:chmod 755 /etc/profile.d/java.sh
echo $JAVA_HOME