shell编程之shell脚本基础(未完待续)
目录
前言:
一、Shell脚本语言的基本结构
1、Shell脚本的用途:
2、 Shell脚本基本结构:
3、 创建Shell脚本过程
4、 脚本注释规范
5、 执行脚本
6、脚本错误
二、Shell脚本语言的变量用法详解
1、变量
2、 变量类型
3、 Shell中变量命名法则
4、 变量定义和引用
5、 环境变量
6、位置与预定义变量
7、 展开命令行
7.1、展开命令执行顺序
7.2 、防止扩展
7.3、 加引号来防止扩展
7.4 、变量扩展
前言:
- shell是操作系统的最外层,shell可以合并编程语言以控制进程和文件,以及启动和控制其他程序。
- shell通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出,简单来说shell就是一个用户跟操作系统之间的一个命令解释器。
- shell是用户与Linux操作系统之间沟通的桥梁,用户可以输入命令执行,又可以利用shell脚本
编程去运行,如图所示。
shell、utilites(工具程序)及kernel位置关系
一、Shell脚本语言的基本结构
1、Shell脚本的用途:
-
自动化常用命令
-
执行系统管理和故障排除
-
创建简单的应用程序
-
处理文本或文件
2、 Shell脚本基本结构:
Shell脚本编程:是基于过程式,解释执行的语言
编程语言的基本结构:
-
各种系统命令的组合
-
数据存储:变量,数组
-
表达式:a+b
-
控制语句:条件语句:if、case
循环语句:for、while
shell脚本:包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行执行声明机制
#声明后续语句是通过那种语言写的
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
3、 创建Shell脚本过程
- 使用vim创建文本文件,第一行必须包括shell声明序列:
[root@localhost ~]# vim first_shell.sh
#!/bin/bash
2.加执行权限,给予执行权限,在命令行上指定脚本的绝对或相对路径:
[root@localhost ~]# chmod +x first_shell.sh
3.运行脚本,直接运行解释器,将脚本作为解释器程序的参数运行:
[root@localhost ~]# ./first_shell.sh
第一个脚本:
[root@localhost ~]# vim first_shell.sh#!/bin/bash
#This is my First shell
#By author zhou 2025
echo "Time is `date +'%F %T'`"
echo "Hello World!"[root@localhost ~]# chmod +x first_shell.sh
[root@localhost ~]# ./first_shell.sh
Time is 2025-08-29 16:27:38
Hello World!
4、 脚本注释规范
-
第一行一般为调用使用的语言
-
程序名,避免更改文件名为无法找到正确的文件
-
版本号
-
更改后的时间
-
作者相关信息
-
该程序的作用,及注意事项
-
最后是各版本的更新简要说明(change log)
注意事项:
- shell脚本名称命名一般为英文的大写、小写;
- 不能使用特殊符号、空格来命名;
- shell脚本后缀以。sh结尾;
- 不建议shell命名为纯数字,一般以脚本功能命名;
- shell脚本内容首行需以#!/bin/bash开头;
5、 执行脚本
1、增加执行权限,执行脚本时会创建一个子shell,不影响现有的shell环境
2、使用 . 或者source,执行脚本时不会创建一个子shell,会影响现有的shell环境(注意:尽量不要使用该方式执行脚本!!! )
6、脚本错误
-
语法错误,会导致后续的命令不继续执行,可以用bash -n shellname检查错误
-
命令错误,后续的命令还会继续,可以使用bash -x shellname检查
-
逻辑错误,只能使用bash -x进行观察
二、Shell脚本语言的变量用法详解
1、变量
变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据
2、 变量类型
变量类型:
-
内置变量:如PS1,PATH,UID,HOSTNAME,HISTSIZE
-
用户自定义变量
-
预定义变量
-
位置变量 ($1~$9)
不同的变量存放的数据不同,决定了以下:
-
数据存储方式
-
参与的计算
-
表示的数据范围
变量数据类型:
-
字符串
-
数值:整型,浮点型(小数)、bash不支持浮点数
3、 Shell中变量命名法则
-
不能使用程序中的保留字,如:if,for
-
只能使用数字,字母及下划线,且不能以数字开头
-
见名思意,用英文名字,并体现真正含义
-
统一命名规则:驼峰命名法(oneNumber=1:单驼峰;TwoNumber=1:双驼峰)
-
全局变量名大写
-
局部变量小写
-
函数名小写
4、 变量定义和引用
变量的生效范围(变量作用域)
-
普通变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效
-
环境变量(全局变量):生效范围为当前shell进程及其子shell进程
-
本地变量:生效范围为当前shell进程中某代码片段,通常指函数
变量赋值:
name="value"
value可以是以下多种类型
直接字符串:name='root'
变量引用:name="$USER"
命令应用:name=`command` || name=$(command)
通配符:FILE=/etc/* /*表示etc目录下所有的文件名*/
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存。
变量引用:{ }
$name
${name}
[root@localhost ~]# a=1
[root@localhost ~]# echo $a
1
[root@localhost ~]# echo $ab[root@localhost ~]# echo ${a}b
1b
弱引用和强引用:
-
"$name":弱引用,其中的变量引用会被替换成为变量值
-
'$name':强引用,其中的变量引用不会被替换成变量值,而保持原字符串
[root@localhost ~]# name='Jackson'
[root@localhost ~]# NAME="$USER"
[root@localhost ~]# NUM=`seq 5`[root@localhost ~]# echo "my name is $name"
my name is Jackson[root@localhost ~]# echo "my name is $NAME"
my name is root[root@localhost ~]# echo '$NUM'
$NUM
[root@localhost ~]# echo $NUM
1 2 3 4 5
[root@localhost ~]# echo "$NUM"
1
2
3
4
5
查看已定义的所有变量:set
删除变量:unset
[root@localhost ~]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:globasciiranges:globskipdots:histappend:interactive_comments:login_shell:patsub_replacement:progcomp:promptvars:sourcepath
BASHRCSOURCED=Y
BASH_ALIASES=()
BASH_ARGC=([0]="0")
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_VERSINFO=([0]="2" [1]="12" [2]="0")
BASH_LINENO=()
BASH_LOADABLES_PATH=/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:.
BASH_REMATCH=()
BASH_SOURCE=()
利用变量实现动态命令:
[root@localhost ~]# CMD="ls -l"
[root@localhost ~]# $CMD
总计 1268
-rw-------. 1 root root 866 8月26日 23:08 anaconda-ks.cfg
-rwxr-xr-x. 1 root root 109 8月29日 16:26 first_shell.sh
drwxr-xr-x. 9 502 games 4096 8月27日 20:14 nginx-1.29.1
-rw-rw-rw-. 1 root root 1285529 8月27日 19:36 nginx-1.29.1.tar.gz
5、 环境变量
环境变量:
-
可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
-
一旦子进程修改了从父进程继承的变量,将会传递新的值给孙子进程
-
一般只在配置文件中使用,在脚本中较少使用
6、位置与预定义变量
位置变量:在Bash Shell中内置的变量,在脚本代码中调用命令行传递给脚本的参数
$1,$2,... 对应第一个,第二个等参数,shift[n]换位置,最多9个
预定义变量:
$0 | 脚本本身,包括路径 |
$# | 传递给脚本的参数的个数 |
$* | 传递给脚本的所有参数,全部参数合成一个字符串 |
$@ | 传递给脚本的所有参数,每个参数为独立字符串 |
$? | 上个命令的退出状态,或函数的返回值 |
$$ | 当前shell进程ID。对于Shell脚本,就是这些脚本所在的进程ID |
注意:$@,$*只有被双引号括起来的时候才会有差异
7、 展开命令行
7.1、展开命令执行顺序
- 把命令行分成单个命令词
- 展开别名
- 展开大括号的声明{}
- 展开波浪符声明(~)
- 命令替换$()和``
- 再次把命令行分成命令词
- 展开文件通配(*,?,[abc]等)
- 准备I/O重导向(<,>)
- 运行命令
7.2 、防止扩展
反斜线(\)会使随后的字符按原意解释
[root@localhost ~]# name=zhou
[root@localhost ~]# echo $name
zhou
[root@localhost ~]# echo \$name
$name
7.3、 加引号来防止扩展
单引号 ' ' 防止所有扩展
双引号 " " 可防止扩展
[root@localhost ~]# name=zhou[root@localhost ~]# echo "\$name"
$name
[root@localhost ~]# echo '\$name'
\$name
7.4 、变量扩展
``:反引号,命令替换 等效于$( )
例:`ls`等效于$(ls)
\:反斜线,禁止单个字符扩展
!:叹号,历史命令替换
[root@localhost ~]# root=`ls /root`
[root@localhost ~]# echo $root
anaconda-ks.cfg first_shell.sh nginx-1.29.1 nginx-1.29.1.tar.gz one.sh[root@localhost ~]# name=$(hostname)
[root@localhost ~]# echo $name
localhost.localdomain