【Linux】Shell

发布时间:2023年12月31日

Shell

1. 简介

Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。Shell还是一个功能相当强大的变成语言。

查看 Linux 提供的 Shell 解释器:cat /etc/shells ,其中 sh 是软链接,指向 bashCentOS 默认的解析器是 bash

2. Shell 脚本入门

脚本文件格式:#!/bin/bash 开头,表示指定解析器

脚本的执行方式:

  1. bash 脚本路径 sh 脚本路径 :这种方式不用赋予 x 权限
  2. 脚本路径 :当前目录下必须用 ./脚本名 的方式执行,要求必须有 x 权限
  3. .source :无需 x 权限,且不会在当前 shell 中打开一个子 shell 来执行脚本内容。
    • 方式1和2会打开子 shell 执行脚本内容,执行结束再回到父 shell。
    • 开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子 shell 中设置的当前变量,父 shell 是不可见的

3. 变量

  1. 常用系统变量:$HOME$PWD$SHELL$USER
  2. 自定义变量:变量名=变量值 ,撤销变量: unset 变量名 ,静态变量:readonly 变量 静态变量不能撤销。export 变量名 提升为全局变量,变量名规则:
    • 环境变量名建议大写
    • 变量默认都是字符串类型,无法直接进行数值运算
    • 变量有空格需用单引号或双引号括起来
  3. 特殊变量:
    • $n :n 为数字,$0 代表该脚本名称,$1 - $9 代表第一到第九个参数,十以上的参数需要用大括号包含,如 ${10}
    • $# :获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性
    • $* :这个变量代表命令行中所有的参数,$* 把所有的参数看成一个整体;当被双引号包含时,相当于把所有参数拼成了一个字符串
    • $@ :这个变量也代表命令行中所有的参数,不过 $@ 把每个参数区分对待;相当于把所有参数拼成一个集合,只有当被双引号包含时才与 $* 有区别
    • $? :最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确

4. 运算式

通过 $((运算式))$[运算式] 可以获取并接收一个运算式的值

[linux@CentOS01 ~]$ a=$[1+2+3]
[linux@CentOS01 ~]$ echo $a
6

5. 条件判断

基本语法:

  • test condition
  • [ condition ] ,condition 前后必须有空格

常用判断条件:

  1. 比较 :下面是整数间的比较,如果是字符串之间的比较 ,用等号 = 判断相等;用 != 判断不等
符号含义
-eq等于(equal)
-ne不等于(not equal)
-lt小于(less than)
-le小于等于(less equal)
-gt大于(greater than)
-ge大于等于(greater equal)
  1. 文件权限判断[ -r hello.txt ] 判断 hello.txt 有没有读权限
  2. 文件类型判断-e 文件存在;-f 文件存在并且是常规文件;-d 文件存在并且是一个目录

一般可以直接用 $? 来表示上一条条件判断结果,false 为 0,true 为 1;

还可以用 &&|| 来控制多条件判断及语句执行,&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令

6. 流程控制

6.1 if 判断

  1. 单分支
if [ 条件判断式 ];then
	程序
fi

或者

if [条件判断式]
then
	程序
fi
  1. 多分支
if [ 条件判断式 ]
then
	程序
elif [ 条件判断式 ]
then
	程序
else
	程序
fi

6.2 case 语句

case $变量名 in
"值1")
	变量值等于值1时执行的程序
;;
"值2")
	变量值等于值2时执行的程序
;;
"*")
	变量值都不是上述值执行的程序
;;
esac

6.3 for 循环

语法1:

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

语法2:

for 变量 in 值1 值2 值3...
do
	程序
done

6.4 while 循环

while [ 条件判断式 ]
do
	程序
done

7. read 读取控制台输入

基本语法:read (选项) (参数)

  1. 选项:
    • -p :指定读取值时的提示符
    • -t :指定读取值时等待的时间(秒)如果-t 不加表示一直等待
  2. 参数:指定读取值的变量名

8. 函数

8.1 系统函数

  1. basename [string / pathname] [suffix] :取路径里的文件名称,指定了 suffix 会将对应 suffix 去掉
  2. dirname 文件绝对路径 :取文件路径的绝对路径目录,不含文件名

8.2 自定义函数

基本语法:

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

function sum()
{
	s=0;
	s=$[$1+$2]
	echo "$s";
}

经验技巧

  1. 必须在调用函数地方之前,先声明函数
  2. 函数返回值,只能通过 $? 系统变量获得,如果不加 return 返回,将以最后一条命令运行结果;如用 return ,后跟数值 n(0-255)

9. 正则表达式入门

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

常规匹配:cat a.txt | grep abc 就会匹配所有包含 abc 的行

常用特殊字符

  • ^ :匹配一行的开头,cat a.txt | grep ^a 匹配所有 a 开头的行
  • $ :匹配一行的结束,cat a.txt | grep a$ 匹配所有 a 结尾的行
  • . :匹配一个任意字符,cat a.txt | grep a.b 匹配 aab 、abb 、acb … 的所有行
  • * :不单独使用,和上一个字符连用,表示匹配上一个字符0次或多次
  • \ :转义字符,如 cat a.txt | grep \$ 匹配包含 $ 的行

字符区间:[]

  • [6,8] :匹配6或者8
  • [6-8] :匹配一个 6-8 间的数字
  • [0-9]* :匹配任意长度的数字字符串3
  • [a-z] :匹配一个 a-z 间的字符
  • [a-c,e-f] :匹配一个 a-c 或者 e-f 间的字符

10. 文本处理工具

10.1 cut

cut [选项参数] filename :默认分割符是 \t

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

切割 ifconfig 后打印的 IP 地址:

[linux@CentOS01 ~]$ ifconfig ens33 | grep netmask | cut -d " " -f 10
192.168.115.128

10.2 awk

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

基本语法:awk [选项参数] ‘/pattern1/{action1} /pattern2/{action2}...’ filename

  • pattern :表示 awk 在数据中查找的内容,就是匹配模式
  • action :在找到匹配内容时所执行的一系列命令
选项参数功能
-F指定输入文件分隔符
-v赋值一个用户定义变量

内置变量:

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

切割 ifconfig 后打印的 IP 地址:

[linux@CentOS01 ~]$ ifconfig ens33 | awk '/netmask/ {print $2}'
192.168.115.128

11. 归档文件案例

实现一个当天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在 /root/archive 下。

这里用到了归档命令:tar ,后面可以加上 -c 选项表示归档,加上 -z 选项表示同时进行压缩,得到的文件后缀名为 .tar.gz 。如需每天执行可结合 crond 服务使用。

脚本实现如下:

#!/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)
# 获取当前日期
DATE=$(date +%y%m%d)

# 定义生成的归档文件名称
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
文章来源:https://blog.csdn.net/xxx1276063856/article/details/135319167
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。