目录
- 一、Shell概念
- 1.定义
- 2.分类和使用场景
- 2.1.分类和切换
- 2.2.使用场景
- 3.特性
- 3.1.文件描述符与输出重定向
- 3.2.历史命令---history
- 3.3.别名 --alias
- 3.4.命令排序执行
- 3.5.部分快捷键
- 3.6.通配符置换
- 4.脚本规范
- 5.脚本运行方式
- 5.1.bash脚本执行
- 5.2.bash脚本测试
- 二、bash配置文件
- 1.全局配置文件
- 2.个人配置文件
一、Shell概念
1.定义
- 程序 语言 编程
- 语言:自然语言(汉语 英语)、计算机语言(c语言、c++、java、php、python、go、shell)
- 编译型语言:c、c++、java
- 解释型语言:php、python、bash(shell)
编译型语言:编译型语言的首先将源代码编译生成机器语言,再由机器运行机器码(二进制)。像C/C++等都是编译型语言。
解释型语言:源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。比如Python/JavaScript/Shell等都是解释型语言
c 编译型执行代码需要编译成cpu能认识的二进制码 x86指令集
java 编译型执行编译–>字节码,cpu不能直接运行,只能被Java虚拟机执行
shell 解释型语言执行 慢
编译型语言的执行方式
解释型语言的执行方式
Shell定义
Shell 也是一种程序设计语言,它有变量,关键字,各种控制语句,有自己的语法结构,利用shell程序设计语言可以编写功能很强、代码简短的程序。
shell是外壳的意思,就是系统的外壳,我们可以通过shell的命令来控制和操作操作系统,比如linux中的shell命令就包括ls、cd、pwd等等,总结来说shell就是一个命令解释器,他通过接收用户输入的shell命令来启动、停止程序的运行或者对计算机进行控制。
2.分类和使用场景
2.1.分类和切换
[root@localhost ~]# cat /etc/shells //查看所有shell
/bin/sh
/bin/bash //默认的shell
/usr/bin/sh //centos中脚本使用的默认shell
/usr/bin/bash
[root@localhost ~]# echo $SHELL //查看当前正在使用的shell
/bin/bash
[root@localhost ~]# vim /etc/passwd //编辑登录shell
2.2.使用场景
Shell 能做什么?
- 自动化批量系统初始化程序 (update,软件安装,时区设置,安全策略…)—初始化脚本
- 自动化批量软件部署程序 (LAMP,LNMP,Tomcat,LVS,Nginx)—一键安装la/nmp环境,通过脚本自动上线代码
- 应用管理程序 (KVM)—通过脚本批量创建虚拟机
- 日志分析处理程序(PV, UV, 200, !200,grep/awk/sed)
- 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
- 自动化信息采集及监控程序(收集系统/应用状态信息,CPU、Mem、Disk、Net、TCP Status、Apache、MySQL)
- 配合Zabbix信息采集(收集系统/应用状态信息,CPU、Mem、Disk、Net、Apache、MySQL)
- Shell可以做任何运维的事情(一切取决于业务需求)
3.特性
3.1.文件描述符与输出重定向
在 shell程序中,最常使用的FD (file descriptor) 大概有三个,分别是:
0: Standard Input (STDIN)
1: Standard Output (STDOUT)
2: Standard Error Output (STDERR)
在标准情况下, 这些FD分别跟如下设备关联:
stdin(0): keyboard 键盘输入,并返回在前端
stdout(1): monitor 正确返回值 输出到前端
stderr(2): monitor 错误返回值 输出到前端
将程序的标准输出(stdout)和标准错误(stderr)一起重定向到一个文件(该用法最常用):&> a.txt
将标准输出(stdout)重定向到标准错误(stderr),用的较少(了解即可):1 >&2
将标准错误(stderr)重定向到标准输出(stdout),用的较少(了解即可):2 >&1
一般来说, “1>” 通常可以省略成 “>”
1.例子,当前目录下只有a.txt,没有b.txt
[root@localhost ~]# touch a.txt
[root@localhost ~]# ls a.txt b.txt >file.out 2>&1
[root@localhost ~]# cat file.out
ls: cannot access b.txt: No such file or directory
a.txt
2.或者也可以:
[root@localhost ~]# ls a.txt b.txt &>cat.txt
[root@localhost ~]# cat cat.txt
ls: 无法访问b.tx: 没有那个文件或目录
a.txt
3.通过cat的方式将内容写入到文件中
[root@localhost ~]# cat >> b.txt <<eof
> ni hao a haha
> eof
[root@localhost ~]# cat b.txt
ni hao a haha
//注:这里也可以使用EOF需要成对使用即可!
3.2.历史命令—history
上下健
! 关键字
! 历史命令行号
!! 执行上一条命令
!$ 上一条命令的最后一个参数
esc . 上一条命令的最后一个参数
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
3.3.别名 --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 rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
设置别名
1.临时设置
[root@localhost ~]# aa=88
[root@localhost ~]# echo $aa
88
2.永久设置
[root@localhost ~]# vim /root/.bashrc
aa=88
[root@localhost ~]# source /root/.bashrc //让文件生效
3.4.命令排序执行
&& 逻辑与,前面执行成功,后面才执行。前面命令执行失败,后面命令也不执行
|| 逻辑或,前面执行失败,后面执行,前面命令执行成功,后面不执行。
; 从左往右按顺序执行,不管前面执行成功与否,后面都执行
3.5.部分快捷键
Ctrl+a 切换到命令行开始(跟home一样,但是home在某些unix环境下无法使用)
Ctrl+u 清除剪切光标之前的内容
Ctrl+k 清除剪切光标之后的内容
ctrl+y 粘贴刚才所删除的字符
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
Ctrl+l 清屏
Ctrl+c 终止
Ctrl+e 切换到命令行末尾
3.6.通配符置换
在 Shell命令中,通常会使用通配符表达式来匹配一些文件
* ? [] {}
字符 | 含义 | 实例 |
---|---|---|
* | 匹配 0 或多个字符 | a*b a与b之间可以有任意长度的任意字符,也可以一个也没有, 如aabcb, axyzb, a012b, ab |
? | 匹配任意一个字符 | a?b a与b之间必须也只能有一个字符,可以是任意字符, 如aab, abb, acb, a0b |
[list] | 匹配 list 中的任意单一字符 | a[xyz]b a与b之间必须也只能有一个字符,但只能是 x 或 y 或 z, 如: axb, ayb, azb |
[!list] | 匹配 除list 中的任意单一字符 | a[!0-9]b a与b之间必须也只能有一个字符,但不能是阿拉伯数字, 如axb, aab, a-b |
[c1-c2] | 匹配 c1-c2 中的任意单一字符 | [0-9] [a-z] a[0-9]b 0与9之间必须也只能有一个字符 如a0b, a1b… a9b |
{string1,string2,…} | 匹配 sring1 或 string2 (或更多)其一字符串 | a{abc,xyz,123}b a与b之间,只能是abc或xyz或123这三个字符串之一 |
[root@localhost tmp]# rm -rf *
[root@localhost tmp]# touch aabcb axyzb a012b ab acb
[root@localhost tmp]# ls
a012b aabcb ab acb axyzb
[root@localhost tmp]# ls a*b
a012b aabcb ab acb axyzb
[root@localhost tmp]# ls a?b
acb
[root@localhost tmp]# rm -rf *
[root@localhost tmp]# touch axb ayb azb axyb
[root@localhost tmp]# ls
axb axyb ayb azb
[root@localhost tmp]# ls a[xy]b
axb ayb
[root@localhost tmp]# ls a[!xy]b
azb
[root@localhost tmp]# ls a[!x]b
ayb azb
[root@localhost tmp]# rm -rf *
[root@localhost tmp]# touch a0b a1b a9b
[root@localhost tmp]# ls a[0-9]b
a0b a1b a9b
[root@localhost tmp]# rm -rf *
[root@localhost tmp]# touch aabcb axyzb a012b ab
[root@localhost tmp]# ls a{abc}b //a{abc}b被当作文件名
ls: cannot access a{abc}b: No such file or directory
[root@localhost tmp]# ls a{abc,}b
aabcb ab
[root@localhost tmp]# ls a{abc,xyz}b
aabcb axyzb
[root@localhost tmp]# ls a{abc,xyz,012}b
a012b aabcb axyzb
//拓展
[root@localhost tmp]# ls a[0-9a-z][0-9a-z][0-9a-z]b
a012b aabcb axyzb
4.脚本规范
[root@localhost ~]# vim helloworld.sh //.sh代表这个文件是个shell脚本,拓展名后缀,如果省略.sh则不易判断该文件是否为shell脚本
1. #!/usr/bin/env bash //shebang蛇棒, 解释器, 翻译
2. #
3. # Author: soso666
4. # Email: soso666@163.com //一些注释,可以解释一下脚本作用
5. # Github: https:github.com/soso666
6. # Date: 2019/12/24
7. printf "hello world"
//功能说明:打印hello world
[root@localhost ~]# sh helloworld.sh
hello world
5.脚本运行方式
5.1.bash脚本执行
[root@localhost ~]# vim /opt/test/script/test.sh
#!/bin/bash
# 获取主机基本信息
time=`date +%F-%T` #等同于 $(date +%F-%T)
#ifconfig命令需要安装net-tools工具包
ip=`ifconfig |grep broadcast|awk '{print $2}'`
echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip
[root@localhost ~]# cd /opt/test/script/
1.source 文件名
使用当前shell(父shell)执行 比如cd /tmp
会改变当前shell环境,但是其他的方式不会
[root@localhost script]# source test.sh
现在的时间是: 2023-09-07-19:52:54
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136
2.bash或者sh 文件名
[root@localhost script]# bash test.sh
现在的时间是: 2023-09-07-19:53:03
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136
[root@localhost script]# sh test.sh
现在的时间是: 2023-09-07-19:53:09
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136
3.相对路径或者绝对路径
需要提前授权
[root@localhost script]# ./test.sh
-bash: ./test.sh: 权限不够
[root@localhost script]# chmod +x ./test.sh
[root@localhost script]# ./test.sh
现在的时间是: 2023-09-07-19:56:25
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136
[root@localhost script]# /opt/test/script/test.sh
现在的时间是: 2023-09-07-19:56:36
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136
5.2.bash脚本测试
1.这将执行该脚本并显示所有变量的值
[root@localhost ~]# sh -x /root/helloworld.sh
+ printf 'hello world'
hello world
2.不执行脚本只是检查语法模式,将返回所有错误语法
[root@localhost ~]# sh -n /root/helloworld.sh
3.执行脚本前把脚本内容显示在屏幕上
[root@localhost ~]# sh -v /root/helloworld.sh
#!/usr/bin/env bash
#
# Author: soso666
# Email: soso666@163.com
# Github: https:github.com/soso666
# Date: 2019/12/24
printf "hello world"
hello world
二、bash配置文件
1.全局配置文件
/etc/bashrc、/etc/profile、/etc/profile.d/*.sh
如果修改/etc/profile文件修改出错,导致无法敲系统命令,例如:ls,怎么解决呢?
在命令行中输入
export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
然后将该命令【追加】到/etc/profile文件中,修改完后
source /etc/profile
2.个人配置文件
~/.bash_profile、~/.bashrc
profile类的文件:设定环境变量,运行命令或脚本,用户在登录的时候会自动生效
bashrc类的文件:定义命令别名
用户登录时加载bash配置文件的过程:
登录式shell加载配置文件过程:先个人,再公共;先局部,再全局
~/.bash_profile --> ~/.bashrc --> /etc/bashrc —> /etc/profile --> /etc/profile.d/*.sh
这里的优先级是影响范围最小的优先级最高
非登录式shell加载配置文件过程
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh
下面的文件为系统的每个用户设置环境信息Shell设置文件:
/etc/profile(系统级)启动时执行
这是系统最主要的shell设置文件,也是用户登陆时系统最先检查的文件,有关重要的【环境变量】都定义在此,其中包括 PATH,USER,MAIL,HOSTNAME,HISTSIZE,INPUTRC等。而在文件的最后,它会检查并执行/etc/profile.d/*.sh的脚本。
~/.bash_login(用户级)登录时执行,默认不存在
如果~/.bash_profile文件不存在,则系统会转而读取.bash_login这个文件内容。这是用户的登陆文件,在每次用户登陆系统时,bash都会读此内容,所以通常都会将登陆后必须执行的命令放在这个文件中。
~/.bash_logout 离开时执行如果想在注销shell前执行一些工作,都可以在此文件中设置。
例如:vi ~.bash_logout
clear #仅执行一个clear命令在你注销的时候
~/.bash_history(用户级) 这个文件会记录用户先前使用的历史命令。