a超打印怎么看Shell笔记(超级完整)

新闻资讯2026-04-20 22:47:25

@[toc]

Shell是一个命令行解释器,他接受应用程序/用户命令,然后调用操作系统内核
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第1张
Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强

[root@hadoop100 ~]# cat /etc/shells

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第2张
ubuntu使用的解析器是dash

  • [root@hadoop100 ~]# ls -l /bin/ | grep bash

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第3张

[root@hadoop100 ~]# echo $SHELL
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第4张

脚本以#!/bin/bash 开头(指定解析器)

一般情况下加上.sh后缀,也可以不加.sh后缀

创建一个 Shell 脚本,输出 helloworld

先创建一个目录scripts(可以不创建,我这里为了好管理,又重新创建了一个目录),然后进入该目录,在目录里创建一个hello.sh的文件,进行编辑
[root@hadoop100 ~]# mkdir scripts
[root@hadoop100 ~]# cd scripts/
[root@hadoop100 scripts]# touch hello.sh
[root@hadoop100 scripts]# vim hello.sh
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第5张
在hello.sh中写如下代码

echo "hello,world"
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第6张

2.3.1.1sh+脚本的相对路径

[root@hadoop100 scripts]# sh ./hello.sh
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第7张

2.3.1.2sh+脚本的绝对路径

[root@hadoop100 scripts]# sh /root/scripts/hello.sh

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第8张

2.3.1.3bash+脚本的相对路径

[root@hadoop100 scripts]# bash ./hello.sh
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第9张

2.3.1.4bash+脚本的绝对路径

[root@hadoop100 scripts]# bash /root/scripts/hello.sh

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第10张

2.3.2.1首先要赋予 helloworld.sh 脚本的+x 权限

[root@hadoop100 scripts]# chmod +x hello.sh

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第11张

2.3.2.2执行脚本

2.3.2.2.1相对路径

[root@hadoop100 scripts]# ./hello.sh

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第12张
[root@hadoop100 scripts]# hello.sh
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第13张
如果直接这样敲的话就会被认为是一条命令去执行

2.3.2.2.1绝对路径

[root@hadoop100 scripts]# /root/scripts/hello.sh

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第14张

第一种执行方法,本质是 bash 解析器帮你执行脚本,所以脚本本身不需要执行 权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。

2.3.4.1 source命令绝对路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第15张

2.3.4.2source命令相对路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第16张

2.3.4.3 “.”命令绝对路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第17张

2.3.4.4 “.”命令相对路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第18张

2.3.4.5注意a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第19张

这两个的区别在于第一个“.”是命令,而下面那个表示的是相对路径,因为“.”第三种情况是使脚本内容在当前 shell 里执行,所以不用加/来表示相对路径,而第一种和第二种是打开一个子 shell 来执行脚本内容,所以需要加./来表示相对路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第20张
相当于嵌套for循环,子shell的变量在父shell里面不能用,如果退出的话是先从最内层退出,然后再到最外层,相当于在在for循环里面写break,是一层一层的退出

2.3.6.1如果把要执行的脚本放到系统命令里(bin目录或者sbin目录)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第21张
但是这种情况不靠谱,因为这个目录里面是系统的命令,因此不要轻易更改

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第22张

2.3.6.2更改环境变量

可以通过更改环境变量来直接执行脚本,可以将hello.sh放到/root/bin里面,或者直接将scripts目录放到环境变量里也可以
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第23张

原因: 前两种方式都是在当前 shell 中打开一个子 shell 来执行脚本内容,当脚本内容结束,则 子 shell 关闭,回到父 shell 中。
第三种,也就是使用在脚本路径前加“.”或者 source 的方式,可以使脚本内容在当前 shell 里执行,而无需打开子 shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需 要 source 一下的原因。
开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子 shell 中设置的 当前变量,父 shell 是不可见的。

比如 更改linux中的.profile配置文件,发现没有及时生效,然后直接source 改过的文件,所有更改的环境配置文件都生效了

$HOME、$PWD、$SHELL、$USER 等

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第24张

[root@hadoop100 scripts]# env
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第25张
如果想看的方便可以加 | less

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第26张
[root@hadoop100 scripts]# printenv
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第27张
[root@hadoop100 scripts]# printenv USER
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第28张
这样输入的时候不用加$符号,他可打印全部或部分shell 环境

[root@hadoop100 scripts]# set

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第29张

看所有变量包括全局变量和自定义变量局部变量

1)定义变量:变量名=变量值,注意,=号前后不能有空格
2)撤销变量:unset 变量名
3)声明静态变量:readonly 变量,注意:不能 unset

1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
2)等号两侧不能有空格
3)在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算
4)变量的值如果有空格,需要使用双引号或单引号括起来。

3.2.3.1定义变量a

[root@hadoop100 scripts]# a=2

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第30张

3.2.3.2查看没有定义的sssshell

[root@hadoop100 scripts]# echo $sssshell
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第31张

3.2.3.3“=”号前后有空格的情况

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第32张

3.2.3.4更改变量的值

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第33张

3.2.3.5当要赋值的内容有空格的时候需要加上单引号或者双引号

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第34张

3.2.3.6局部变量和全局变量

env只能查系统所设置的全局变量,而set可以查看所有定义的变量,到这步还不能完全知道ssshell是局部变量还是全局变量继续往下走
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第35张
打开一个子shell
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第36张
说明ssshell是局部变量

3.2.3.7将ssshell定义成全局变量

当我们需要在子shell里使用ssshell变量时,我们需要将ssshell定义成全局变量,定义ssshell变成全局变量的时候需要在创建ssshell的父shell变,不能在其他子shell变
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第37张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第38张

3.2.3.8在子shell中更改父shell全局变量只在子shell有效,回到父shell里不会改变

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第39张

3.2.3.9用vim输出全局变量和局部变量的区别

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第40张
在hello.sh中加上局部变量sssshell然后执行hello.sh的结果为
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第41张

如果用绝对路径的话是没有hello,linux这条的,因为sssshell是局部变量

把sssshell变量变为全局变量结果为
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第42张
这两个都显示

3.2.3.10在set中看自定义变量

定义了a变量,在set里面可以找到

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第43张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第44张

3.2.3.11声明静态变量

[root@hadoop100 ~]# readonly b=2
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第45张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第46张
静态变量和局部变量都在set里面

3.2.3.12撤销变量a

[root@hadoop100 ~]# unset a

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第47张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第48张
set里面没有a变量了

3.2.3.13不能撤销静态变量

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第49张

3.2.3.14在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第50张

3.2.3.15如果进行数值运算需要使用,需要使用shell中的运算符的表达

[root@hadoop100 ~]# a=$((1+4))

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第51张
[root@hadoop100 ~]# a=$[5+2]

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第52张

3.3.1.1基本语法

$n (功能描述:n 为数字,$0 代表该脚本名称,$1-$9 代表第一到第九个参数,
十以上的参数,十以上的参数需要用大括号包含,如${10})

3.3.1.2案例实操

3.3.1.2.1在vim里面""和''的区别
用双引号扩住$n和用单引号扩住$n
双引号扩住$n代码变量
不管单引号扩住什么都原封不动的输出
3.3.1.2.2$n的使用

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第53张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第54张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第55张
用绝对路径的话需要给parameter.sh加上执行权限
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第56张

3.3.2.1基本语法

$# (功能描述:获取所有输入参数个数,
常用于循环,判断参数的个数是否正确以及 加强脚本的健壮性)。

3.3.2.2$

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第57张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第58张

3.3.3.1基本语法

$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体) 
$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)

3.3.3.2$*$@的使用

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第59张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第60张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第61张

3.3.3.1基本语法

$? (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一 个命令正确执行;
如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明 上一个命令执行不正确了。)

3.3.3.2判断 parameter.sh 脚本是否正确执行

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第62张

“$((运算式))” 或 “$[运算式]”
用expr输出+、-、*、%
符号(+、-、*、%)两边需要空格隔开
用*的时候需要用这个,因为*的用处很多,所以需要区分

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第63张

需要使用命令替换

a=$(运算式)或者用a=`运算式`

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第64张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第65张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第66张

在add.sh中写如下代码
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第67张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第68张

1)test condition
2)[ condition ](注意 condition 前后要有空格)
注意:条件非空即为 true,[ atguigu ]返回 true,[ ] 返回 false。

-eq 等于(equal) -ne 不等于(not equal)
-lt 小于(less than) -le 小于等于(less equal)
-gt 大于(greater than) -ge 大于等于(greater equal)
注:如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等。

-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)

-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)

5.2.4.1test condition

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第69张

测试他输出的是正确还是错误使用$?来判断,输出0则表达式为真,输出1表达式为假

5.2.4.2[ condition ](注意 condition 前后要有空格)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第70张
用[]的时候,里面的等于号两边一定要用空格空开,否则他会识别为一个整体条件非空即为 true

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第71张
当[]里面有东西事,则为真,只有空格时为假,如果前后不空格的话就未找到命令

5.2.4.3在[]里面使用=和!=

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第72张

5.2.4.4-eq 等于(equal) -ne 不等于(not equal)

如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第73张

5.2.4.5-lt 小于(less than) -le 小于等于(less equal)

不能用< 和<=,因为在linux里表示输入重定向
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第74张
在双小括号里可以使用(> < >= <=号)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第75张

5.2.4.6-gt 大于(greater than) -ge 大于等于(greater equal)

不能用>和>=,因为在linux里>表示输出重定向
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第76张

在双小括号里可以使用(> < >= <=号)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第77张

5.2.4.7判断文件权限、 -r 有读的权限(read)、 -w 有写的权限(write) 、 -x 有执行的权限(execute)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第78张

5.2.4.8判断文件类型、-e 文件存在(existence)、-f 文件存在并且是一个常规的文件(file)、-d 文件存在并且是一个目录(directory)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第79张

5.2.4.9多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一 条命令执行失败后,才执行下一条命令)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第80张

注意事项:
①[ 条件判断式 ],中括号和条件判断式之间必须有空格
②if 后要有空格

6.1.1.1单分支

if [ 条件判断式 ];then
 程序 
fi
或者 
if [ 条件判断式 ] 
then
 程序 
fi

6.1.1.2多分支

if [ 条件判断式 ] 
then
    程序 
elif [ 条件判断式 ] 
then
    程序 
else
    程序 
fi

6.1.2.1单分支

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第81张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第82张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第83张
当这样写的时候,没有传入参数时,会报错的,所以要按照下面的做法做

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第84张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第85张
这样的话就不会报错了,因为要是不输入参数的时候两边也都不会为空

6.1.2.2用逻辑与&&逻辑或||连接(单分支)

6.1.2.2.1逻辑与&&

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第86张

在中括号里面的话就不用&&而是用-a(-and)

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第87张

6.1.2.2.2逻辑或||

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第88张

在中括号里面的话就不用||而是用-o(-or)
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第89张

6.1.2.3多分支

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第90张
..a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第91张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第92张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第93张

case $变量名 in 
"值 1")
    如果变量的值等于值 1,则执行程序 1 
;;
"值 2")
    如果变量的值等于值 2,则执行程序 2 
;; 
    …省略其他分支… 
*) 
    如果变量的值都不是以上的值,则执行此程序 
;;
esac

(1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。 (2)双分号“;;”表示命令序列结束,相当于 java 中的 break。
(3)最后的“*)”表示默认模式,相当于 java 中的 default。

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第94张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第95张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第96张

for (( 初始值;循环控制条件;变量变化 )) 
do 
    程序 
done
for 变量 in 值 1 值 2 值 3… 
do 
    程序 
done

6.3.3.1for (( 初始值;循环控制条件;变量变化 ))

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第97张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第98张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第99张

6.3.3.2“{}”在linux shell里面表示生成序列

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第100张

{1..100}表示从1到100,中间是两个点,别看错了

6.3.3.3for 变量 in 值 1 值 2 值 3…

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第101张

6.3.3.2在for循环中$*和$@的区别

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第102张
$*和$@没有加双引号的时候输出结果为下:

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第103张
他们两个的输出结果一致

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第104张

当加上双引号后。结果如下:
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第105张

当它们被双引号“”包含时,
$*会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输 出所有参数;
$@会将各个参数分开,以“$1” “$2”…“$n”的形式输出所有参数。
while [ 条件判断式 ] 
do 
    程序 
done

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第106张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第107张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第108张

在新版shell中支持用let的,他的语言是和高级语言差不多的
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第109张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第110张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第111张

read 是 Shell 内置命令,用来从标准输入中读取数据并赋值给变量。如果没有进行重定向,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据。

read (options) (variables)

options表示选项,如下表所示;
variables表示用来存储数据的变量,可以有一个,也可以有多个。
options和variables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。
①options:

  • -p:指定读取值时的提示符;
  • -t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待

②variables

  • 变量:指定读取值的变量名

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第112张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第113张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第114张

如果超过设置的时间,则直接跳过
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第115张

8.1.1.1基本语法

basename [string / pathname] [suffix] (功能描述:basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。
basename 可以理解为取路径里的文件名称
选项:
suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中的 suffix 去掉。

dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
dirname 可以理解为取文件路径的绝对路径名称

8.1.3.1date+%s时间戳练习

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第116张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第117张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第118张

8.1.3.2basename的练习

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第119张

将文件名剪切下来
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第120张
parameter文件的代码
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第121张

显示的文件名包括路径,我们不需要输出路径,因此加上basename来解决

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第122张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第123张

8.1.3.3dirname的练习

dirname截取最后一个斜杠之前的路径,不包括文件名
而basename截取最后一个斜杠之后的文件名,不包括路径

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第124张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第125张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第126张

如果只有pwd的话,在其他文件夹里执行代码则不会打印脚本的目录,需要加上dirname,如下
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第127张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第128张

加上dirname后输出的脚本路径是保持不变的

[ function ] funname[()] 
{ 
    Action; 
    [return int;] 
}

(1)必须在调用函数地方之前,先声明函数,shell 脚本是逐行运行。不会像其它语言一样先编译。
(2)函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值 n(0-255)

8.2.3.1没有使用return的版本

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第129张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第130张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第131张
可以输出和

8.2.3.2用return返回的话

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第132张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第133张
可以看出,return后面必须是跟数字,修改如下:
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第134张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第135张

这样就可以正常输出结果了,但是return的时候只能返回0-255,超过的数就不能显示正确的答案,如下
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第136张
156+245!=145的,所以可以说明return只能返回0-255的数,那我们应该如何解决呢,看下面的代码
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第137张
这样写就可以将函数add里面echo的值赋给ans,然后再输出
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第138张

结果也是对的,说明这样写是正确的

正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中,grep,sed,awk 等文本处理工具都支持通过正则表达式进行模式匹配。

一串不包含特殊字符的正则表达式匹配它自己,例如:
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第139张
[root@hadoop100 ~]# cat /etc/passwd | grep 00:
就会匹配所有包含 00:的行。

^ 匹配一行的开头,例如:
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第140张
会匹配出所有以 a 开头的行

$ 匹配一行的结束,例如
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第141张

会匹配出所有以 h结尾的行

  • 思考:^$ 匹配什么?

匹配空行

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第142张

匹配一个任意的字符,例如
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第143张

“*”不单独使用,他和上一个字符连用,表示匹配上一个字符 0 次或多次,例如

[root@hadoop100 ~]# cat /etc/passwd | grep ro*t
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第144张

会匹配 rt, rot, root, rooot, roooot 等所有行

思考:.* 匹配什么?
匹配任意字符,可以和^$连用,放在他们中间用,就可以将下面的代码实现,以a开头,login结尾的行
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第145张

[root@hadoop100 ~]# cat /etc/passwd | grep ^a.*login$

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第146张
[root@hadoop100 ~]# cat /etc/passwd | grep ^a.var.login$

[ ] 表示匹配某个范围内的一个字符,例如
[6,8]------匹配 6 或者 8
[0-9]------匹配一个 0-9 的数字
[0-9]*------匹配任意长度的数字字符串
[a-z]------匹配一个 a-z 之间的字符
[a-z]* ------匹配任意长度的字母字符串
[a-c, e-f]-匹配 a-c 或者 e-f 之间的任意字符

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第147张
[root@hadoop100 ~]# cat /etc/passwd | grep r[a-z]*t

表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配某一特殊字符本身时(例如,我想找出所有包含 '$' 的行),就会碰到困难。此时我们就要将转义字符和特殊字符连用,来表示特殊字符本身,例如

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第148张

就会匹配所有包含 $ 的行。注意需要使用单引号将表达式引起来。

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第149张

[root@hadoop100 scripts]# echo "13812345678" | grep ^1345780-90-90-90-9$

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第150张

[root@hadoop100 scripts]# echo "13812345678" | grep -E ^134578{9}$

记得加大写的-E,因为目前grep不支持{9}的扩展的正则的,所以需要加上-E,表示支持扩展的正则表达式

cut 的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

cut [选项参数] filename
说明:默认分隔符是制表符

选项参数 功能 -f 列号,提取第几列 -d 分隔符,按照指定分隔符分割列,默认是制表符“ ” -c 按字符进行切割 后加加 n 表示取第几列 比如 -c 1

10.1.3.1数据准备

[root@hadoop100 scripts]# vim cut_test.txt
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第151张

10.1.3.2切割 cut_test.txt 第一列

[root@hadoop100 scripts]# cut -d " " -f 1 cut_test.txt
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第152张

10.1.3.3切割 cut_test.txt 第二、三列

[root@hadoop100 scripts]# cut -d " " -f 2,3 cut_test.txt
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第153张

10.1.3.4在 cut_test.txt 文件中切割出 nan

[root@hadoop100 scripts]# cat cut_test.txt | grep nan | cut -d " " -f 1

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第154张

10.1.3.5要passwd中以bash结尾的第一,六,七列

[root@hadoop100 scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 1,6,7

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第155张

如果列多的话总不能1,2,3,4,5,6,7,8,9,10...等吧,可以用“-”来,下面介绍

10.1.3.6要passwd中以bash结尾的第1-4列

[root@hadoop100 scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 1-4

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第156张

10.1.3.7要passwd中以bash结尾的第4列往后的全部列

[root@hadoop100 scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f 4-

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第157张

10.1.3.8要passwd中以bash结尾的第4列之前的全部列

[root@hadoop100 scripts]# cat /etc/passwd | grep bash$ | cut -d ":" -f -4

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第158张

10.1.3.9选取系统 PATH 变量值,第 2 个“:”开始后的所有路径:

[root@hadoop100 scripts]# echo $PATH | cut -d ":" -f 3-

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第159张

10.1.3.10切割 ifconfig 后打印的 IP 地址

[root@hadoop100 scripts]# ifconfig ens33 | grep netmask | cut -d " " -f 10

为什么是10呢,因为inet前面有8个空格
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第160张

awk和gawk是一样的,awk是gawk的一个软连接
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}...’ filename
pattern:表示 awk 在数据中查找的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令

选项参数 功能 -F 指定输入文件分隔符 -v 赋值一个用户定义变量

10.2.3.1搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 7 列

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第161张

10.2.3.2搜索 passwd 文件以 root 关键字开头的所有行,并输出该行的第 1 列和第 7 列, 中间以“,”号分割

用cut是不能改变输出中间用什么隔开的,而awk可以,记住,需要用“”包裹
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第162张

10.2.3.3只显示/etc/passwd 的第一列和第七列,以逗号分割,且在所有行前面添加列名 user,shell 在最后一行添加"end of file"

[root@hadoop100 scripts]# cat /etc/passwd | awk -F ":" 'BEGIN{print "user,shell"}{print $1","$7} END{print "end of file"}'

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第163张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第164张

10.2.3.4将 passwd 文件中的用户 id 增加数值 1 并输出

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第165张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第166张

因为{}里面是代码块,可以直接在里面更改

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第167张

如果{}代码块里的代码多了,需要更改会很麻烦,因此使用-v,这样的话在外面一改数字代码块里面的代码就都改了

变量 说明 FILENAME 文件名 NR 已读的记录数(行号) NF 浏览记录的域的个数(切割后,列的个数)

10.2.4.1统计 passwd 文件名,每行的行号,每行的列数

[root@hadoop100 scripts]# awk -v i=1 -F ":" '{print "文件名:" FILENAME "行号:" NR "列数:" NF}' /etc/passwd

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第168张

10.2.4.2查询 ifconfig 命令输出结果中的空行所在的行号

[root@hadoop100 scripts]# ifconfig | grep -n ^$

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第169张
用之前的方法输出会有":",但是结果不想要,用awk解决

[root@hadoop100 scripts]# ifconfig | awk '/^$/ {print NR}'

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第170张

也可以随意加东西

[root@hadoop100 scripts]# ifconfig | awk '/^$/ {print "空行:"NR}'

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第171张

10.2.4.3切割 IP

使用cut时-f后需要数前面那一堆空格

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第172张

使用awk后,前面那一堆空格是不需要数的
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第173张

实际生产应用中,往往需要对重要数据进行归档备份。
需求:实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/root/archive下。
这里用到了归档命令: tar
后面可以加上-c选项表示归档,加上-z选项表示同时进行压缩,得到的文件后缀名为.tar.gz

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第174张

#!/bin/bash

#首先判断输入参数个数是否为1
if [ $# -ne 1 ]
then
        echo "参数个数错误!应该输入一个参数,作为归档目录名"
        exit
fi

# 从参数中获取目录名称
if [ -d $1 ]
then
        echo
else
        echo
        echo "目录不存在!"
        echo
        exit
fi

DIR_NAME=$(basename $1)
DIR_PATH=$(cd $(dirname $1); pwd)

# 获取当前日期
FILE=archive_${DIR_NAME}_$DATE.tar.gz
DEST=/root/archive/$FILE

# 开始归档目录文件

echo "开始归档..."
echo

tar -czf $DEST $DIR_PATH/$DIR_NAME

if [ $? -eq 0 ]
then
        echo
        echo "归档成功!"
        echo "归档文件为:$DEST"
        echo
else
        echo "归档出现问题!"
        echo
fi

exit

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第175张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第176张
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第177张
则创建一个文件
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第178张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第179张

归档成功

使用crontab
crontab中的代码

0 2 * * * /root/scripts/daily_archive.sh /root/scripts

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第180张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第181张

这个可以查看用户在线情况, +号代表的是可以发送信息,mesg是打开的
a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第182张
mesg n可以将mesg关闭
mesg y可以将mesg打开

  • write 用户名 控制台

[root@hadoop100 scripts]# write cat pts/1

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第183张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第184张

我们可以利用 Linux 自带的 mesg 和 write 工具,向其它用户发送消息。
需求:实现一个向某个用户快速发送消息的脚本,输入用户名作为第一个参数,后面直接跟要发送的消息。脚本需要检测用户是否登录在系统中、是否打开消息功能,以及当前发送消息是否为空。
脚本实现如下:

#!/bin/bash

# 查看用户是否登录
login_user=$(who | grep -i -m 1 $1 | awk '{print $1}')

if [ -z $login_user ]
then
        echo "$1 不在线!"
        echo "脚本退出..."
        exit
fi

# 查看用户是否开启消息功能
is_allwoed=$(who -T | grep -i -m 1 $1 | awk '{print $2}')


if [ "$is_allowed"x != "+"x ]
then
        echo "$1 没有开启消息功能"
        echo "脚本退出..."
        exit
fi

# 确认是否有消息发送
if [ -z $2 ]
then
        echo "$1 没有消息发送"
        echo "脚本退出..."
        exit
fi

# 从参数中获取要发送的消息
whole_msg=$(echo $* | cut -d " " -f 2-)

# 获取用户登录的终端
user_terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')

# 写入要发送的消息
echo $whole_msg | write $login_user $user_terminal

if [ $? != 0 ]
then
        echo "发送失败!"
else
        echo "发送成功!"
fi
exit

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第185张

a超打印怎么看Shell笔记(超级完整)_https://www.jmylbn.com_新闻资讯_第186张

完结!!!