01 Shell编程规范与变量

1、Shell脚本概述

在一些复杂的Linux维护工作中,大量的重复性的输入和交互操作不仅费力费时,而且容易出错,而编写一个恰到好处的Shell脚本程序,可以批量处理、自动化地完成一系列维护任务,大大减轻管理员的负担。

Shell脚本是什么?

简单的说,只要将平时使用的各种Linux命令按顺序保存到一个文本文件中,然后添加可执行权限,这个文件就成为一个Shell脚本了。

1.1 Shell的作用

Shell是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了命令解释器的角色。

Shell——负责接收用户输入的操作指令(命令)并解释,将需要执行的操作传递给内核执行,并输出执行结果。

注:常见的Shell解释器程序有很多种,使用不同的Shell时,其内部指令、命令行提示符等方面会存在一些区别。

可通过查看/etc/shell文件来了解当前系统所支持的Shell脚本种类。如下图:

1.2  编写第一个Shell脚本

Bash——是目前大多数Linux版本采用的默认Shell,是最受欢迎的开源软件项目之一。

例如,执行下图操作可以创建第一个脚本文件:first.sh

在上图的first.sh脚本文件中,包括三条命令,执行此脚本文件后,输出结果与依次单独执行这三条命令是相同的。如下图,是查看执行first.sh脚本文件后的结果:

补充:执行脚本的方式有两种,以执行上面所述的first.sh脚本文件为例。

一种是直接通过./first.sh的方式来执行脚本,但这要求文件本身具有x权限(在某些安全系统中可能无法满足此条件)

另一种是指定某个Shell来解释脚本语句,或者通过内部命令source(或点号.)来加载文件中的源代码执行。例如,使用sh first.sh或.first.sh也可以执行first.sh脚本中的语句。

注意:Linux系统中包括大量的Shell脚本文件,但应避免直接修改系统内的Shell脚本文件,以免导致服务或系统故障。

2、重定向与管道操作

由于Shell脚本批量处理的特性,其大部分操作过程会以静默的方式运行(不需要用户干预)

因此,学会提取、过滤执行信息就变得十分重要。

2.1 重定向操作

用户通过操作系统处理信息的过程中,包括下面这几类的交互设备文件:

  • 标准输入(STDIN):默认的设备是键盘,文件编号为0。命令将从标准输入文件中读取在执行过程中需要的输入数据。
  • 标准输出(STDOUT):默认的设备是显示器,文件编号为1.命令将执行后的输出结构=果发送到标准输出文件。
  • 标准错误(STDERR):默认的设备是显示器,文件编号为2。命令将执行期间的各种错误信息发送到标准错误文件。

注:在实际的Linux系统维护中,可以改变输入、输出内容的方向,而不使用默认的标准输入、输出设备(键盘和显示器),这种操作称为重定向。

(1)、重定向输出

将命令的正常输出结果保存到指定的文件中,而不是直接显示在显示器的屏幕上。

注:重定向输出使用>(用于覆盖文件)或>>(用于追加文件)操作符号。

若重定向输出的目标文件不存在,则会新建该文件,然后将前面命令的输出结果保存到该文件中;

若目标文件已经存在,则将输出结果覆盖或追加到文件中。

例如,要将当前主机的CPU类型信息(uname -p)保存到kernel.txt文件中,而不是直接显示在屏幕上,可执行下图中的操作:

当需要保留目标文件原有的内容时,应使用>>操作符号,以便追加内容而不是全部覆盖。

例如,执行下图中的命令可以将内核版本信息追加到kernel.txt文件中:

(2)、重定向输入

指的是将命令中接收输入的途径由默认的键盘改为指定的文件,而不是等待从键盘输入。重定向输入使用<操作符

注:重定向输入可以使一些交互式操作过程能够通过读取文件来完成。

例如,使用passwd命令为用户设置密码时,每次都必须根据提示输入两次密码字串,非常繁琐。如下图:

但是若改成改用重定向输入将可以省略交互式的过程,而自动完成密码设置(结合passwd命令的--stdin选项来识别标准输入):

注:非交互式的命令语句,可以更方便的在Shell脚本中使用,从而大大减少程序被打断的过程,提高脚本执行的效率。

(3)、错误重定向

指的是将执行命令过程中出现的错误信息(如选项或参数错误)保存到指定的文件,而不是直接显示在屏幕上。

注:错误重定向使用2>操作符,其中的2是指错误文件的编号

(在使用标准输出、标准输入定向时,实际上省略了1、0编号)

例如,执行下图中的命令可以将使用tar命令进行备份时出现地错误信息保存到error.log文件中:

2.2 管道操作

位于管道符号|左侧的命令输出的结果,将作为右侧命令的输入(处理对象)。

注:同一行命令中,可以使用多个管道。管道操作通常用来过滤所需要的关键信息。

例如,使用grep命令查询使用/bin/bash作为Shell的系统用户名时,会输出符合条件的整行内容,在此基础上,可以结合管道操作与awk命令作进一步过滤,只输出用户名和登录Shell列:

3、Shell变量的作用、类型

Shell变量是用来存放系统和用户需要使用的特点参数(值),这些参数可以根据用户的设定或系统环境的变化而相应地变化。

常见Shell变量的类型有:

  • 自定义变量
  • 环境变量
  • 只读变量
  • 位置变量
  • 预定义变量

3.1 自定义变量

自定义变量是由系统用户自己定义的变量,只在用户自己的Shell环境中有效,因此又称为本地变量。

注:在Bash中定义一个新的变量时,一般不需要提前进行声明,而是直接指定变量名称并赋给初始值内容即可。

定义变量的基本格式是“变量名=变量值”,等号两边没有空格。

变量名称要以字母、下划线开头,数字不能开头。另外,变量名称中不要包含特殊字符(如+ - * / ?& #等)。

例如,要定义一个Product的变量(值为Python)和一个名为Version的变量,可执行如下图的操作:

3.2 查看和引用变量的值

通过在变量名称前添加前导符号$,就可以引用一个变量的值。

注:使用echo命令可以查看变量(可以在一条echo中同时查看多个变量值)。如下图:

当变量名称容易和紧跟其后的其他字符相混淆时,需要用大括号{}将其括起来。如下图:

3.3 给变量赋值的特殊操作

在等号=后边直接指定变量内容是为变量赋值的最基本方法,除此之外还有一些特殊的赋值操作。

(1)双引号" "

双引号主要起到界定字符的作用,特别是当要赋值的内容中包含空格时,必须以双引号括起来。其他情况下可以省略。例如:

注:在双引号范围内,使用$符号可以引用其他变量的值(变量引用),从而能够直接调用现有变量的值来赋给新的变量。

例如,执行下图中的操作可以调用变量Version的值,将其赋给一个新的变量PyVersion:

(2)单引号' '

当要赋值的内容中包含$   "   \等具有特殊含义的字符时,应该使用单引号括起来。

注:在单引号的范围内,将无法引用其他变量的值,任何字符均作为普通字符看待。

例如下图,

补充:当赋值内容中包含单引号时,需要使用\'符号进行转义,以免冲突,如下图:

(3)反撇号`

反撇号主要用于命令替换,允许将执行某个命令的屏幕输出结果赋值给变量。

注:反撇号括起来的范围内必须是能够执行的命令行,否则将会出错。

如下图,

在上图中的操作,相当于连续执行了两条命令——先通过which useradd命令查找出useradd命令的程序位置,然后根据查找结果列出其文件属性。

也就是说,执行过程中,会用which useradd命令的输出结果替换整个反撇号范围。

(4)read命令

除了上述的赋值操作以外,还可以使用Bash的内置命令read来给变量赋值。

read命令——用来提示用户输入信息,从而实现简单的交互过程。

注:read命令在执行时,将从标准输入设备(键盘)读入一行内容,并以空格为分隔符,将读入的各字段依次赋值给指定的变量(多余的内容赋值给最后一个变量)。

若指定的变量只有一个,则将整行内容赋值给此变量。

例如,执行下图中的命令将会等待用户输入文字,并将输入的内容赋值给变量ToDir1:

补充:为了使交互式操作界面更加友好,read命令可以结合-p选项来设置提示信息(以便告知用户应该输入什么内容等相关事项)。

例如,若希望提示用户输入备份文件的存放目录,并将输入的路径信息赋值给变量ToDir2,可以执行下图中的操作:

3.4 设置变量的作用范围

默认环境下,新定义的变量只在当前的Shell环境中有效,因此称为局部变量。

注:当进入到子程序或新的子Shell环境时,局部变量将无法再使用。

例如,直接执行Bash进入一个新的子Shell脚本后,将无法引用父级Shell环境中定义的Product、Version等变量。如下图:

为了使用户定义的变量在所有的子Shell环境中能够继续使用,减少重复设置工作,可以通过内部命令export将指定的变量导出为全局变量。

注:用户可以同时指定多个变量名称作为参数(无须使用$符号),变量名之间以空格分隔。

补充:在使用export导出全局变量的同时,也可以为变量进行赋值,这样一来,在新定义全局变量时就不需要提前进行赋值了。

例如,执行下图中的操作可以直接新建一个名为FQDN的全局变量:

4、数值变量的运算

Shell变量的数值运算多用于脚本程序的过程控制(如循环次数、使用量比较等)。

注:在Bash Shell环境中,只能进行简单的整数运算,不支持小数运算。

整数值的运算主要通过内部命令expr进行,基本格式如下所示:

但要注意,运算符与变量之间必须有至少一个空格。

常用的运算符有:

+                         加法运算

-                          减法运算

\*                         乘法运算 (注意不能仅使用*符号,否则将被当成文件通配符)

/                          除法运算

%                        取余运算——用来计算数值相除后的余数

若要将运算结果赋值给其他变量,可以结合命令替换操作(使用反撇号)。

例如,下图中为计算变量Y的三次方,并将结果赋值给变量Ycube:

5、特殊的Shell变量

除了用户自定义的Shell变量以外,在Linux系统和Bash Shell环境中还有一系列的特殊变量,它们分别是:

环境变量、只读变量、位置变量、预定义变量

5.1 环境变量——主要用于设置用户的工作环境(包括宿主目录、命令查找路径、用户当前目录、登录终端等)

环境变量是出于运行需要而由Linux系统提前创建的一类变量,

注:环境变量的值由Linux系统自动维护,会随着用户状态的改变而改变。

使用env命令——可以查看到当前工作环境下的环境变量。

接上图:

PATH变量——用于设置可执行程序的默认搜索路径,当仅指定文件名称来执行命令程序时,Linux系统将在PATH变量指定的目录范围查找对应的可执行文件,如果找不到则会提示command not found。

例如,first.sh脚本位于/root目录下,若希望能直接通过文件名称来运行脚本,可以修改PATH变量以添加搜索路径,或者直接将first.sh脚本复制到现有搜索路径中的某个文件夹下:

在Linux系统中,环境变量的全局配置文件为/etc/profile,在此文件中定义的变量作用于所有用户。

除此之外,每个用户还有自己的独立配置文件(~/.bash_profile)。

注:若要长期变更或设置某个环境变量,应该在/etc/profile文件中进行设置。

例如,执行以下操作可以将记录的历史命令条数改为200条(默认为1000条),只针对root用户:

在上图中的修改,只有当用户root用户下次登录时才会生效。若希望立即生效,应手动修改环境变量,或者加载配置文件执行:

5.2 只读变量

只读变量一经设定,其值是不可改变的。

注:在创建变量的时候,可将其设置为只读属性,也可以将已存在的变量设置为只读属性(只读变量——主要用于变量值不允许被修改的情况)

例如,脚本中定义了一个变量log_path用来定义日志文件的路径,在脚本的执行过程中如果不想被修改,就可以将该变量设置为只读变量。如下图:

补充:

readonly命令——可将变量定义为只读变量(定义之后不能通过再次赋值的方式进行修改)

unset命令——用于删除变量

5.3 位置变量

当执行命令行操作时,第一个字段表示命令名或脚本程序名,其余的字符串参数按照从左到右的顺序依次赋值给位置变量。

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

例如,当执行命令行ls -lh /boot时,其中第一个位置变量为-lh,以$1表示;

第二个位置变量为/boot,以$2表示;

命令或脚本本身的名称使用$0表示($0属于预定义变量而不是位置变量)

为了说明位置变量的作用,下面编写一个加法运算的小脚本adder2num.sh,用来计算两个整数的和。需要计算的两个整数在执行脚本时以位置变量的形式提供:

脚本的内容是:

5.4 预定义变量

预定义变量是由Bash程序预先定义好的一类特殊变量,预定义变量使用$符号和另一个符号组合表示。

注:用户只能使用预定义变量,而不能创建新的预定义变量,也不能直接为预定义变量赋值。

几个常用的预定义变量如下:

$#——表示命令行中位置参数的个数

$*——表示所有位置参数的内容

$?——表示前一条命令执行后的返回状态,

返回值为0表示执行正确,返回值为让任何非0值均表示执行出现异常

$0——表示当前执行的脚本或程序的名称

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/729567.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CT】LeetCode手撕—54. 螺旋矩阵

目录 题目1- 思路2- 实现⭐54. 螺旋矩阵——题解思路 3- ACM实现 题目 原题连接&#xff1a;92. 反转链表 II 1- 思路 模式识别&#xff1a;螺旋矩阵 ——> 用四个指针来顺时针遍历 2- 实现 ⭐54. 螺旋矩阵——题解思路 class Solution {public List<Integer> spir…

RuoYi Swagger请求401

问题描述&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 使用ruoyi-vue分离版&#xff0c;访问swagger&#xff0c;发现接口都调用失败&#xff1a;401 解决方案&#xff1a; 最终解决问题如下步骤&#xff1a; 1、 调用swagger中的接口&#xff0c;报错&a…

QT MQTT (二)编译与集成

一、QT MQTT 提供 MQTT 客户端服务的 Qt 专用库基于标准化发布 / 订阅协议&#xff0c;用于在设备和组件之间可靠地共享数据。MQTT 是为保证状态正确性、满足高安全标准和交换最小数据而设计的协议&#xff0c;因此被广泛应用于各种分布式系统和物联网解决方案中。 Qt开发MQT…

修改源码,打patch包,线上环境不生效

1.首先看修改的源码文件是否正确 在node_modules中&#xff0c;找对应的包&#xff0c;然后查看包中package.json 的main和module。如果用require引入&#xff0c;则修改lib下面的组件&#xff0c;如果是import引入则修改es下面的文件 main 对应commonjs引入方式的程序入口文件…

WPF 数据分组显示

WPF 数据分组显示 效果展示&#xff1a; Student类&#xff1a; public class Student {public string Name { get; set; }public string Class { get; set; }public int Age { get; set; } }MainWindow.xaml.cs public partial class MainWindow : Window {private Observ…

数据结构-图的基本概念

图的定义 图时由非空的顶点集合和一个描述顶点之间关系的集合组成。可以定义为&#xff1a; ​​​​​​​ ​​​​​​​ ​​​​​​​ G表示一个图&#xff0c;V表示点集&#xff0c;E表示边集。集合E的每一个二元组都包含两个值和&#xff0c;表示…

超薄续航,加量不加厚,这款手机甩某果几条街!

据微博知名数码博主爆料&#xff0c;一加即将推出的Ace3 Pro将搭载革命性的“冰川电池”&#xff0c;这是一款6100mAh容量的先进电池&#xff0c;比传统5000mAh电池薄0.49毫米&#xff0c;仅5.51毫米厚&#xff0c;且支持100W快充&#xff0c;可在30分钟内充满。 &#xff08;比…

设计软件有哪些?粒子插件篇,渲染100邀请码1a12

设计师常常需要设计特效&#xff0c;而粒子系统是必不可少的&#xff0c;这次我们简单介绍一些粒子插件。 1、ComplexFresnel ComplexFresnel插件是一款用于计算机图形渲染中的增强型菲涅尔效应模拟工具。它扩展了传统的菲涅尔效应模型&#xff0c;考虑了更多的光学参数&…

R语言——绘图与数据可视化

1、练习将25个点的符号绘制出来&#xff0c;然后用rainbow()返回25个颜色&#xff0c;后5个符号形状的背景颜色用蓝色填充&#xff0c;图的标题为"符号图"&#xff0c;x轴标题为符号索引&#xff0c;y轴标题为符号形状。 2、根据员工的销售业绩画饼状图&#xff0c;添…

【AI】AI在创造还是毁掉音乐?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

嵌入式学习真的这么烧钱吗?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「嵌入式的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;在我的学习过程中身边有不…

Java宝藏实验资源库(4)对象数组

一、实验目的 学习面向对象程序设计的方法。学习建立对象数组的方法。 学习在数组中存储和处理对象。 二、实验内容、过程及结果 **10.7 (Game: ATM machine) Use the Account class created in Programming Exer cise 9.7 to simulate an ATM machine. Create ten accou…

MAC地址解析工具:ARP命令

网络中每台设备都有一个唯一的网络标识&#xff0c;这个地址叫MAC地址或网卡地址&#xff0c;由网络设备制造商生产时写在硬件内部。形象地说&#xff0c;MAC地址就如同身份证上的身份证号码&#xff0c;具有唯一性。 无论是局域网&#xff0c;还是广域网中的计算机之间进行通信…

Windows系统下安装RabbitMQ详细步骤

声明&#xff1a;原文参考链接出自&#xff1a; 如何在Windows系统下安装RabbitMQ_rabbitmq windows安装-CSDN博客 https://zhuanlan.zhihu.com/p/693160757 一、RabbitMQ安装软件资源准备 因为RabbitMQ是Erlang语言开发的&#xff0c;因此安装Erlang环境在进行安装RbbitMQ的…

小程序大作为|小程序开发详细流程,新手也能轻松掌握

随着移动互联网的快速发展&#xff0c;小程序作为一种轻量级应用&#xff0c;因其无需下载安装、即点即用、用完即走的特点&#xff0c;受到了广大用户的青睐。那么开发小程序都有哪些开发流程呢&#xff1f;可以用哪种方式开发&#xff1f;选择合适的开发方式&#xff0c;一起…

java连接mysql报错

1.背景&#xff0c;直接升级操作系统从centos-》国产化操作系统&#xff0c;mysql也升级到5.7.44 2&#xff0c;报错 Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconn…

如何使用 ArcGIS Pro 和 Landsat 8 影像计算叶绿素指数和全球环境监测指数

GIS 工具和技术的出现极大地帮助了识别、量化和解决问题。GIS 还通过研究可能的情况并实施预防方案提供了一种主动的解决方案。多年来&#xff0c;GIS 通过电信和网络服务、事故/事件分析、城市规划、交通规划、环境影响评估、洪水损失估计、自然资源管理、环境健康和安全、植被…

【STM32-DAP 仿真器】

STM32-DAP 仿真器 ■ STM32-DAP仿真器介绍■ STM32-DAP仿真特点■ STM32-DAP仿真器实物图■ STM32-DAP高速 DAP 仿真器实物图■ STM32-DAP高速无线调试器 实物图■ STM32-DAP高速无线调试器示意图■ STM32-DAP高速无线调试器接线图■ STM32-DAP高速无线调试器接收端示意图 ■ S…

oracle开放某些视图给特定用户,查询报视图不存在问题

以sysdba身份登录到Oracle数据库。 创建新用户。例如&#xff0c;创建一个名为new_user的用户&#xff0c;密码为password&#xff1a; CREATE USER new_user IDENTIFIED BY password;为新用户分配表空间和临时表空间。例如&#xff0c;将表空间users和临时表空间temp分配给新…

循环的三种写法

一、for(i): for (int i0;i< arrayList.size();i){System.out.println(arrayList.get(i));} 最基本的循环方法。 二、for-each: 又称加强for &#xff0c;更简单的遍历集合。 三、迭代器: 迭代器是调用Java中的Iterator接口&#xff0c;该接口定义了三个方法分别是hasNex…