什么是shell?

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

shell和运维的关系?

实现自动化运维!

优势是什么?

shell脚本语言很适合处理纯文本类型数据,且Linux的哲学思想就是一切皆文件,如:日志、配置文件、文本、网页文件,大多数都是纯文本类型的,因此shell可以方便的进行文本处理,好比强大的Linux三剑客(grep、seq、awk)

  • 适合用于管理脚本开发、如软件启停脚本、监控报警脚本、日志分析脚本等等。

shell的作用是什么?

解释执行用户输入的命令和程序

用户输入一条命令,shell就解释一条

键盘输入命令,Linux给与相应的方式,称之为交互式

shell处在什么位置?

shell是对接用户且包裹着系统核心的一层壳

什么是shell脚本?

当命令或程序写在文件中,执行文件读取其中的代码,这个程序文件就称之为shell脚本。

shell脚本语言是属于一种弱类型语言,无需声明变量类型,直接定义使用;强类型语言,必须先定义变量类型,确定是数字、字符串等,之后再赋予同类型的值。

在shell脚本里定义多条Linux命令以及循环控制语句,然后将这些Linux命令一次性执行完毕,执行脚本文件的方式称之为,非交互式。

  • Windows中的*.bat批处理脚本

  • Linux中常用*.sh脚本文件

第一个shell脚本

hello.sh

1
2
3
#! /bin/bash
#这是第一个shell脚本
echo "我是第一个shell脚本"

Shebang

第一行出现的前两个字符#!称为Shebang。

在Unix系统中,程序会分析Shebang后面的内容,作为解析器的指令,如:

  • 以#! /bin/sh开头的文件,程序在执行时会调用/bin/sh,也就是bash解释器
  • 以#! /usr/bin/python开头的文件,代表指定python解释器去执行
  • 以#! /usr/bin/env解释器名称,是一种在不同平台上都能正确找到解释器的办法

注意事项

  • 若脚本未指定Shebang,脚本执行的时候会默认用当前的shell去解释脚本,即$SHELL;
  • 如果Shebang指定了可执行的解释器,如/bin/bash /usr/bin/python,脚本执行时,文件名会作为参数传递给解释器;
  • 如果#!指定的解释器没有可执行权限,则会报“bad interpreter :Permission denied”;
  • 如果#!指定的解释程序不存在,那么会报“bad interpreter:No such file or directory”;
  • #!之后的解释程序,需要写其他绝对路径(如:#! /bin/bash),它是不会自动到$PATH中寻找解释器的;
  • 如果使用“bash test.sh”这样的命令来执行脚本,那么#!这一行将会被忽略,解释器当然是用命令行中显式指定的bash。

执行脚本

情况一 直接输入文件名

1
hello.sh

提示

1
-bash: hello.sh: 未找到命令

原因:PATH中没有这个命令。因为在命令行中的命令都会去PATH中去查找

情况二 使用相对路径

1
./hello.sh

相当于

1
$SHELL ./hello.sh

若提示

1
-bash: ./hello.sh: 权限不够

解决方法,为文件添加执行权限

1
chmod +x hello.sh

情况三 为脚本指定解释器

1
/bin/bash ./hello.sh

情况四 使用source或.执行

1
2
source hello.sh
. hello.sh

情况五 重定向的理念(少见用法)

1
2
sh < hello.sh
bash < hello.sh

什么是bash?

  • bash是一个命令解释器,运行在文本窗口中,并能执行用户直接输入的命令

  • bash还能从文件中读取Linux命令,称之为脚本

  • bash支持通配符、管道、命令替换、条件判断等逻辑语句

历史命令

查看历史命令

1
history

查看设置存放的历史命令条数

1
echo $HISTSIZE

查看历史命令存放的文件位置

1
echo $HISTFILE

history命令

清除

1
history -c

恢复

1
history -r

调用历史记录命令

1
!<历史id>

执行上一次的命令

1
!!

bash基础特性汇总

TAB补全

快捷键

光标移动到最前

1
CTRL+A

光标移动到最后

1
CTRL+E

清除当前的命令

1
CTRL+U

清除光标后内容

1
CTRL+K

清除所有的内容

1
CTRL+L

打断当前命令

1
CTRL+C

暂停当前进程并放入后台

1
CTRL+Z

执行演示

1
2
3
4
5
6
[root@localhost ~]# ping baidu.com
PING baidu.com (110.242.68.66) 56(84) bytes of data.
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=128 time=49.3 ms
^Z[5] 已终止 nohup ping baidu.com > targetfile 2> targetfile

[6]+ 已停止 ping baidu.com

通配符

命令历史

命令别名

alias命令

语法

1
alias [-p] [name[=value] ...]

选项

1
-p:显示全部已定义的别名。
  • name(可选):指定要(定义、修改、显示)的别名。
  • value(可选):别名的值。

命令行展开

shell变量

如何定义变量?

用法:

1
<变量名>="<值>"

bash默认把所有变量都认为是字符串类型,bash作为弱类型编程语言,无需实现声明变量类型,而是声明和赋值同时进行。

1
x="123"

注意变量和值之间不能有空格,错误实例:

1
x = "123"

如何输出变量?

简写用法:

1
echo $<变量名>

完整写法:

1
echo ${<变量名>}
1
2
echo $x
echo ${x}

变量名定义规则

  • 不能使用保留关键字help检查保留字

  • 只能包含数字、字母、下划线:abc%

  • 不能以数字开头:11school

  • 不能使用标点符号:abc?

  • 变量名严格区分大小写

变量的作用域

本地变量

针对当前的shell进程

首先安装pstree

1
yum install psmisc -y

pstree检查进程树

1
pstree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─auditd───{auditd}
├─chronyd
├─crond
├─dbus-daemon───{dbus-daemon}
├─firewalld───{firewalld}
├─irqbalance
├─login───bash
├─lvmetad
├─master─┬─pickup
│ └─qmgr
├─polkitd───6*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───bash
│ ├─sshd───bash───pstree #当前shell
│ └─sshd───sftp-server
├─systemd-journal
├─systemd-logind
├─systemd-udevd
└─tuned───4*[{tuned}]

当我们输入bash再输入pstree

1
2
bash 
pstree
1
2
3
├─sshd─┬─sshd───bash  
│ ├─sshd───bash───bash───pstree #当前shell
│ └─sshd───sftp-server

会发现生成了一个子shell

环境变量

也称全局变量,针对当前shell以及其任意子进程,环境变量也分为自定义、内置两种环境变量

局部变量

针对在shell函数或者是shell脚本中定义

特殊变量

shell内置的特殊功效变量

位置参数变量

用于shell脚本中传递的参数

自定义变量

1
<变量名>=`<>`或者"<>"或者'<>'或者<>
区别实例
1
2
3
单引号变量:不识别特殊语法
双引号变量:能识别特殊语法
反引号变量:在Linux反引号中的命令,执行结果会保留下来并传递给变量
反引号实例
1
2
3
4
5
[root@192 ~]# ls
anaconda-ks.cfg blog hello.sh node-v16.16.0-linux-x64 x.sh
[root@192 ~]# xx=`ls`
[root@192 ~]# echo $xx
anaconda-ks.cfg blog hello.sh node-v16.16.0-linux-x64 x.sh
单双引号实例
1
2
首先定义x值为1
x="1"或'1'或1
1
2
3
4
5
6
7
8
9
10
#定义y1,y2,y3
[root@192 ~]# y1=$x
[root@192 ~]# echo $y1
1
[root@192 ~]# y2="$x"
[root@192 ~]# echo $y2
1
[root@192 ~]# y3='$x'
[root@192 ~]# echo $y3
$x
1
2
3
4
5
#输出
[root@192 ~]# echo "$x"
1
[root@192 ~]# echo '$x'
$x

父子shell

1
2
当调用bash/sh解释器执行脚本时,会开启一个子shell,执行结果不会保留在当前shell
当调用source或者.执行脚本时,会在当前shell中加载脚本,结果保留在当前shell

实例

1
2
[root@192 ~]# cat x.sh
x="0"
1
2
[root@192 ~]# echo $x
1

调用bash/sh执行(此处使用bash)

1
2
3
[root@192 ~]# bash x.sh
[root@192 ~]# echo $x
1

结果显示值未发生改变

调用source/.执行(此处使用source)

1
2
3
[root@192 ~]# source x.sh
[root@192 ~]# echo $x
0

结果显示值发生改变

环境变量设置

PATH变量是什么

PATH变量 就是用于保存可以搜索的目录路径,如果待运行的程序不在当前目录,操作系统便可以去依次搜索 PATH变量 变量中记录的目录,如果在这些目录中找到待运行的程序,操作系统便可以运行。

环境变量

不能说PATH变量就代表了环境变量!

所谓环境变量一般是指,用export内置命令导出的变量。用于定义shell的运行环境、保证shell命令的正确执行。

shell通过环境变量确定登录的用户名、PATH路径、文件系统等各种应用。

环境变量可以在命令行中临时创建,但重新登录后环境变量失效。如果需要永久生效,需要修改环境变量配置文件。

  • 用户个人配置文件

    1
    ~/.bash_profile
  • 远程登录用户特有文件

    1
    ~/.bashrc
  • 全局配置文件

    1
    2
    3
    /etc/profile
    /etc/profile.d
    /etc/bashrc

系统建议创建/etc/profile.d/目录进行添加修改,而不是直接修改主文件

检查系统环境变量的命令

set命令可以找到shell环境中的所有变量,包括全局变量、局部变量