Shell脚本构成与变量介绍

发布时间:2024年01月24日

目录

一、shell脚本基础

1. 概述与构成

2.?shell的作用

3.?脚本执行逻辑及执行方式

4.?脚本错误调试

二、shell脚本应用

1.?重定向与管道符

1.1 重定向

1.2?多行重定向

1.3?管道符

2. 自定义变量

2.1 常见Shell变量的类型

2.2 命名要求

2.3 符号使用?

2.4 变量追加值

2.5?read -p

3. 变量作用范围

4. 变量的运算

4.1 expr整数运算

4.2 其他运算方法

?4.3?随机数生成器变量

5.?环境变量

5.1 概述特点

5.2 配置文件?

6. 只读变量

7. 位置变量

8. 预定义(状态)变量?


一、shell脚本基础

1. 概述与构成

Shell脚本是一种用Shell语言编写的脚本程序,它可以在Unix/Linux系统上运行。Shell脚本通常以.sh为文件扩展名,是一种方便的自动化工具,可以用来完成各种系统管理和任务自动化的工作。

  • Shebang(可选):在脚本文件的第一行可以指定Shebang,用于指定脚本使用的Shell解释器。例如,#!/bin/bash表示使用bash解释器执行脚本。
  • 注释:可以在脚本中使用注释来提供说明和解释。注释以#开头,可以单行注释或多行注释。
  • 变量定义:可以在脚本中定义变量,用于存储数据。变量名通常使用大写字母,等号=用于赋值。例如,name="John"定义了一个名为name的变量,并将其赋值为"John"。
  • 命令和操作:在脚本中可以使用各种命令和操作,用于执行特定的任务。可以使用系统命令、自定义函数、管道、重定向等。
  • 流程控制语句:可以使用流程控制语句来控制程序的执行流程。常见的流程控制语句包括if语句、for循环、while循环、case语句等。
  • 函数定义(可选):可以在脚本中定义函数,用于封装一段可重复使用的代码。函数可以接受参数,并返回结果。
  • 输入和输出:脚本可以接受命令行参数作为输入,并可以使用echo命令输出结果。

2.?shell的作用

?Linux 系统中的Shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。 常见的Shell解释器程序有很多种,使用不同的Shell时,其内部指令、命令行提示符等方面会存在一些区别。通过/etc/shells文件可以了解当前系统所支持的Shell 脚本种类。

查看本机的shell信息:

[root@localhost ~]# cat /etc/shells 
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh

linux中常见的shell:

  • bash:基于gun的框架下发展的shell
  • csh:类似c语言的shell
  • tcsh:整合了csh提供了更多功能
  • sh:已经被bash替换
  • nologin:让用户无法登录 ?

3.?脚本执行逻辑及执行方式

脚本执行逻辑:

  • 顺序执行:程序按从上到下顺序执行
  • 选择执行:程序执行过程中,根据条件的不同,进行选择不同分支继续执行
  • 循环执行:程序执行过程中需要重复执行多次某段语句

执行方式:

① 使用绝对或者相对路径执行(需要加执行权限)

[root@localhost ~]# vim ping.sh
[root@localhost ~]# chmod +x ping.sh  #添加执行权限
#!/bin/bash
ping -c1 192.168.190.100
[root@localhost ~]# /root/ping.sh     #绝对路径执行
[root@localhost ~]# ./ping.sh         #相对路径执行

② 直接使用解释器(不需要加执行权限)

[root@localhost ~]# chmod -x ping.sh
[root@localhost ~]# bash ping.sh

③ source和 . (不需要加执行权限)

[root@localhost ~]# source ping.sh
[root@localhost ~]# . ping.sh 

三种执行方式对当前环境影响:

[root@localhost ~]# vim cd.sh
#!/bin/bash
cd /opt
ls
[root@localhost ~]# chmod +x cd.sh
[root@localhost ~]# /root/cd.sh 
rh
[root@localhost ~]# pwd
/root
[root@localhost ~]# ./cd.sh 
rh                                    #使用子shell执行,不切环境
[root@localhost ~]# pwd
/root
[root@localhost ~]# bash cd.sh 
rh                     
[root@localhost ~]# pwd
/root                                 #使用子shell执行,不切环境
[root@localhost ~]# source cd.sh 
rh
[root@localhost opt]# pwd
/opt                                  #使用本shell执行,切环境
[root@localhost ~]# . cd.sh 
rh                
[root@localhost opt]# pwd
/opt                                  #使用本shell执行,切环境

4.?脚本错误调试

① 命令错误

默认后续的命令还会继续执行,用bash -n无法检查出来 ,可以使用bash -x进行观察

[root@localhost ~]# vim 1.sh
#!/bin/bash
mkdi 1                             #错误命令
echo 1                             #正确命令
[root@localhost ~]# bash 1.sh 
1.sh:行1: mkdi: 未找到命令
1                                  #错误命令不影响后续命令

② 语法错误

会导致后续的命令不继续执行,可以用bash -n检查错误,提示的出错行数不一定是准确的

[root@localhost ~]# vim 2.sh
#!/bin/bash
if [ 1 -eq 1 ];then
echo t
else
echo f
#fi
[root@localhost ~]# bash 2.sh 
2.sh:行7: 语法错误: 未预期的文件结尾

③ 逻辑错误

只能使用bash -x进行

注:

bash -n:脚本名称 (不在当前目录下加绝对路径),检查语法错误
bash -x:脚本名称 (不在当前目录下加绝对路径),逻辑错误

④?set -e,set -u

?在 脚本的前面输入set -e一旦出错立即停止

[root@localhost ~]# vim 3.sh
#!/bin/bash
set -e
cd /op
[root@localhost ~]# bash 3.sh 
3.sh: 第 3 行:cd: /op: 没有那个文件或目录

另外:set -u变量不存在不让执行

二、shell脚本应用

1.?重定向与管道符

1.1 重定向

重定向是一种功能,它允许用户更改命令的标准输入(stdin)和标准输出(stdout)的默认行为。这通常用于将命令的结果发送到不同的目的地,而不是仅仅显示在终端控制台上。

类型设备文件文件描述编号默认设备
标准输入/dev/stdin0键盘
标准输出/dev/stdout1显示器
标准错误输出/dev/stderr2显示器

交互式硬件设备:

  • 标准输入:从该设备接收用户输入的数据
  • 标准输出:通过该设备向用户输出数据
  • 标准错误:通过该设备报告执行出错信息
类型操作符用途
重定向输入<从指定的文件读取数据,而不是从键盘输入
重定向输出1>将输出结果保存到指定的文件(覆盖原有内容)
>>将输出结果追加到指定的文件尾部
标准错误输出2>将错误信息保存到指定的文件(覆盖原有内容)
2>>标准错误输出结果追加到指定的文件尾部
混合输出&>无论对错都可以重定向将标准输出、标准错误的内容保存到同一个文件中

案例:

不能将正确和错误一起显示出来?
[root@centos7 ~]#ls /data /xxx 1> /data/all.log 2>&1?????
先将正确的重定向文件中,再将错误的重定向文件中
[root@centos7 ~]#ls /data /xxx 2> /data/all.log 1>&2?????
先将错误的重定向文件中,再将正确的重定向文件中
[root@centos7 ~]#ls /data /xxx &> /data/all.log???????????? ? 不解释
[root@centos7 ~]#ls /data /xxx >& /data/all.log???????????? ? 同上
[root@centos7 ~]#ls /data /xxx ??2>&1 1> /data/all.log?? 开始没有定义1,所以不符合要求?

1.2?多行重定向

可以帮助脚本开发人员不必使用临时文件来构建输入信息,而是直接就地生产出一个文件并用作命令的标准输入。?

[root@localhost ~]# cat > test << EOF     #EOF不区分大小写
> 1
> 2
> EOF
[root@localhost ~]# cat test
1
2

案例:修改密码

[root@localhost ~]# passwd fql << EOF
> 123456
> 123456
> EOF
更改用户 fql 的密码 。
新的 密码:无效的密码: 密码少于 8 个字符
重新输入新的 密码:passwd:所有的身份验证令牌已经成功更新。

1.3?管道符

“|”,将前面命令的结果当作后面命令的参数执行,管道符左边的命令一定要有标准输出,右边的命令一定可以接收标准输入。当右边无法接收标准输入,可以使用xargs命令代为接收。

[root@localhost ~]# cat /etc/passwd | wc -l
41
[root@localhost ~]# echo --help | xargs cat
用法:cat [选项]... [文件]...
将[文件]或标准输入组合输出到标准输出。
……

2. 自定义变量

2.1 常见Shell变量的类型

  • 自定义变量:由用户自己定义,修改和使用
  • 预定义变量:Bash中内置的一类变量shell,不能修改规定好的变量
  • 环境变量:由系统维护,用于设置工作环境,当前目录 、当前主机名、$PATH ? ??
  • 只读变量:只可以读取不可以更改,常量 ??
  • 位置变量:通过命令行给脚本传递参数

2.2 命名要求

  • 区分大小写
  • 不能使程序中的保留字和内置变量:如:if, for,hostname 命令 a=
  • 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
  • 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH
  • 大驼峰 StudentFirstName
  • 小驼峰 studentFirstName
  • 下划线 student_name
定义变量:name=fql            
引用变量:$name  或  ${name}
调用变量:echo $name   或   echo ${name}
取消变量:unset name

2.3 符号使用?

双引号"  "            #弱引用,可以识别变量,可以避免空格错误
[root@localhost ~]# a=1
[root@localhost ~]# echo "$a"
1
[root@localhost ~]# a=1 2
bash: 2: 未找到命令...
[root@localhost ~]# a="1 2";echo $a
1 2

单引号'  '            #强引用,不能识别变量
[root@localhost ~]# a=1
[root@localhost ~]# echo '$a'
$a

反撇号`  `            #调用命令的执行结果,等于$()
[root@localhost ~]# time=`date`;echo $time
2024年 01月 24日 星期三 16:16:19 CST

大括号{  }             #定义变量名的范围
[root@localhost ~]# a=1;b=2
[root@localhost ~]# echo ${a}b
1b

2.4 变量追加值

格式:变量名+=变量值

[root@localhost ~]# a=1
[root@localhost ~]# a+=2;echo $a
12

2.5?read -p

从键盘输入的内容变成变量,交互式命令

[root@localhost ~]# read -p "现在的时间是:" time
现在的时间是:16点
[root@localhost ~]# echo $time
16点

[root@localhost ~]# vim 1.sh
#!/bin/bash
read -p "你的名字:" name
echo "你的名字是:$name"
[root@localhost ~]# bash 1.sh 
你的名字:lisi
你的名字是:lisi

3. 变量作用范围

默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用。

方法:
格式1:定义好变量情况下 export 变量名
格式2:为定义变量情况下 export 变量名=变量值

[root@localhost ~]# a=1
[root@localhost ~]# echo $a
1
[root@localhost ~]# bash          #切换到子shell
[root@localhost ~]# echo $a       #子shell无法识别变量

[root@localhost ~]# 
[root@localhost ~]# pstree -p | grep -v grep | grep bash
           |-sshd(1097)-+-sshd(1520)---bash(1583)---bash(37606)  #37606为新打开的子shell

[root@localhost ~]# export a     #定义全局变量
[root@localhost ~]# bash
[root@localhost ~]# echo $a      #子shell可以识别变量
1
[root@localhost ~]# pstree -p | grep -v grep | grep bash
           |-sshd(1097)-+-sshd(1520)---bash(1583)---bash(37654)  #37654为新打开的子shell

4. 变量的运算

4.1 expr整数运算

expr只能进行整数的运算,格式:expr 变量1 运算符 变量2 [运算符 变量3]

运算符:

  • 加法 +
  • 减法 -
  • 乘法 \ *
  • 除法 /
  • 取余 (取模)%
[root@localhost ~]# expr a+b
a+b
[root@localhost ~]# expr $a + $b
3
[root@localhost ~]# expr $a - $b
-1
[root@localhost ~]# expr $a \* $b
2

4.2 其他运算方法

let 变量名=算术表达式
[root@localhost ~]# a=1;b=2
[root@localhost ~]# let c=a+b;echo $c
3

((变量名=算术表达式))
[root@localhost ~]# a=1;b=2
[root@localhost ~]# ((c = a+b));echo $c
3

变量名=$[算术表达式]
[root@localhost ~]# a=1;b=2
[root@localhost ~]# c=$[c=a+b];echo $c
3

变量=$(expr arg1 + arg2 ...)
[root@localhost ~]# c=$(expr $a + $b);echo $c
3

变量=`expr arg1 + arg2 ...`
[root@localhost ~]# c=`expr $a + $b`;echo $c
3

echo 算术表达式 | bc
[root@localhost ~]# echo $a+$b | bc
3

?4.3?随机数生成器变量

$RANDOM是一个特殊的环境变量,用于生成一个随机整数。每次访问$RANDOM时,它会返回一个0到32767(2^15-1)之间的随机整数,这个值是通过使用伪随机数生成器来生成的。

[root@localhost ~]# echo $[RANDOM]        #随机生成0-32767
17922
[root@localhost ~]# echo $[RANDOM%35]     #随机生成0-34
1
[root@localhost ~]# echo $[RANDOM%35+1]   #随机生成1-35
7

?随机生成颜色:

[root@localhost ~]# echo -e "\E[1;30mhello\E[0m"  
hello
#指定颜色,30-36共7种颜色
[root@localhost ~]# echo -e "\E[1;$[RANDOM%7+31]mhello\E[0m"
hello
#随机颜色

5.?环境变量

5.1 概述特点

环境变量大体可以分为两类:全局环境变量、局部环境变量。前者变量名通常使用大写字母,后者变量名通常使用小写字母。可通过下述env、printenv命令查看当前所有的全局环境变量。

常用的环境变量:

  • $USER 表示用户名称
  • $HOME 表示用户的宿主目录
  • $LANG 表示语言和字符集
  • $PWD 表示当前所在工作目录
  • $PATH 表示可执行用户程序的默认路径

?特点:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
  • 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
  • 一般只在系统配置文件中使用,在脚本中较少使用

5.2 配置文件?

/etc/profile如果修改此文件会作用于所有用户

~/.bash_profile 用户独立的配置文件,修改这个文件只作用于当前用户

6. 只读变量

只读变量是一种特殊类型的变量,其值不能被修改或重写。一旦将变量声明为只读,就无法再对其进行赋值操作。?变量值不允许修改(重新赋值)的情况,无法使用unsets删除,最快方法重启。

[root@localhost ~]# a=1
[root@localhost ~]# readonly a
[root@localhost ~]# echo $a
1
[root@localhost ~]# a=2
bash: a: 只读变量
[root@localhost ~]# unset a
bash: unset: a: 无法反设定: 只读 variable

7. 位置变量

位置变量也称为位置参数,使用$1、$2、$3、…、$9 表示

[root@localhost ~]# vim 1.sh
#!/bin/bash
echo "$1"            位置1
echo "$2"            位置2
echo "${10}"         位置10,不使用括号,只能识别第一个参数
[root@localhost ~]# bash 1.sh {1..20}
1
2
10

8. 预定义(状态)变量?

存在一些预定义变量(也称为状态变量),它们提供了有关系统和正在发生的操作的信息。这些变量不需要事先声明,而是由操作系统自动提供。

  • $*:表示所有位置参数的内容看成一个整体返回 返回所有
  • $@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回 返回所有
  • $?:表示前一条命令执行后的返回状态,返回值为0表示执行正确,返回任何非0值均表示执行出现异常
  • $#:表示命令行中位置参数的总个数
  • $0:表示当前执行的脚本或程序的名称 当前脚本的名字
  • $$:当前bash的进程id
  • $!: 后台任务最后一个id
[root@localhost ~]# vim 1.sh
#!/bin/bash
echo "$*"
echo "$@"
echo "$?"
echo "$#"
echo "$0"
echo "$$"
echo "$!"

[root@localhost ~]# bash 1.sh {1..10}
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
0
10
1.sh
38866

注:?

?当使用“$0”预定义变量时,如果执行的是软链接文件,则输出的是当前执行的软链接文件名

[root@localhost ~]# ln -s 1.sh a
[root@localhost ~]# ll a
lrwxrwxrwx. 1 root root 4 1月  24 18:47 a -> 1.sh
[root@localhost ~]# bash a
a
文章来源:https://blog.csdn.net/qq_64612585/article/details/135816199
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。