Shell基础 01

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000 次 1年
简介: Shell 是一种脚本语言,用于操作 Linux 服务器。本文介绍了 Shell 变量的定义和作用域,以及多命令运行的练习。变量定义时需注意字符串的引用方式,变量可分为局部和全局。多命令运行中,通过逻辑运算符 `&&` 和 `||` 实现条件判断和命令执行。

 shell 是一种脚本语言,该语言提供了对linux服务器进行操作的命令集合及逻辑处理方式。

1.shell变量定义

在定义变量时,若string中包含空格、制表符和换行符,则string必须用 'string' 或者 "string"的形式,即用单(双)引号将其括起来。双引号内允许变量替换,而单引号内则不可以。

下面给出一个定义和使用shell变量的例子。

//显示字符常量
[root@RHEL7-1 ~]# echo who are you
who are you
[root@RHEL7-1 ~]# echo 'who are you'  
who are you
[root@RHEL7-1 ~]# echo "who are you"
who are you
[root@RHEL7-1 ~]#
//由于要输出的字符串中没有特殊字符,所以' '和" "的效果是一样的,不用""但相当于使用了""
[root@RHEL7-1 ~]# echo Je t'aime
> 
//由于要使用特殊字符('),
//由于'不匹配,shell认为命令行没有结束,回车后会出现系统第二提示符,
//让用户继续输入命令行,按“Ctrl+C”组合键结束
[root@RHEL7-1 ~]#
//为了解决这个问题,可以使用下面的两种方法
[root@RHEL7-1 ~]# echo "Je t'aime"
Je t’aime
[root@RHEL7-1 ~]# echo Je t\'aime

image.gif

2.shell变量的作用域

与程序设计语言中的变量一样,shell变量也有规定的作用范围。shell变量分为局部变量和全局变量。

  • 局部变量的作用范围仅限命令行所在的shell或shell脚本文件中。
  • 全局变量的作用范围则包括本shell进程及其所有子程序。
  • 可以使用export内置命令将局部变量设置为全局变量。
//在当前shell中定义变量var1
[root@RHEL7-1 ~]# var1=Linux
//在当前shell中定义变量var2并将其输出
[root@RHEL7-1 ~]# var2=unix
[root@RHEL7-1 ~]# export var2
//引用变量的值
[root@RHEL7-1 ~]# echo $var1
Linux
[root@RHEL7-1 ~]# echo $var2
unix
//显示当前shell的PID
[root@RHEL7-1 ~]# echo $$
2670
[root@RHEL7-1 ~]#
//调用子shell
[root@RHEL7-1 ~]# bash
//显示当前shell的PID
[root@RHEL7-1 ~]# echo $$
2709                   
//由于var1没有被输出,所以在子shell中已无值
[root@RHEL7-1 ~]# echo $var1
//由于var2被输出,所以在子shell中仍有值
[root@RHEL7-1 ~]# echo $var2
unix
//返回主shell,并显示变量的值
[root@RHEL7-1 ~]# exit
[root@RHEL7-1 ~]# echo $$
2670
[root@RHEL7-1 ~]# echo $var1
Linux
[root@RHEL7-1 ~]# echo $var2
unix
[root@RHEL7-1 ~]#

image.gif

3.多命令运行练习

我们有如下情况。

  1. 先判断一个目录是否存在。
  2. 若存在,则在该目录下面创建一个文件。
    由于我们尚未介绍“条件判断式(test)”的使用,在这里我们使用ls以及回传值来判断目录是否存在。让我们进行下面的练习。

【例7-1】使用ls查阅目录/tmp/abc是否存在,若存在,则用touch创建/tmp/abc/hehe。

[root@RHEL7-1 ~]# ls /tmp/abc && touch /tmp/abc/hehe
ls: cannot access /tmp/abc: No such file or directory 
# 说明找不到该目录,但并没有touch的错误,表示touch并没有运行
[root@RHEL7-1 ~]# mkdir  /tmp/abc
[root@RHEL7-1 ~]# ls  /tmp/abc  &&  touch  /tmp/abc/hehe
[root@RHEL7-1 ~]# ll  /tmp/abc
total 0
-rw-r--r--. 1 root root 0 Jul 14 22:34 hehe

image.gif

如果/tmp/abc不存在时,touch就不会被运行;若/tmp/abc存在,那么touch就会开始运行。在上面的例子中,我们还必须手动自行创建目录,很麻烦。能不能自动判断:如果没有该目录就创建呢?看下面的例子。

【例7-2】测试/tmp/abc是否存在,若不存在,则予以创建;若存在,就不做任何事情。

[root@RHEL7-1 ~]# rm  -r  /tmp/abc                 // <==先删除此目录以方便测试
[root@RHEL7-1 ~]# ls  /tmp/abc  ||  mkdir  /tmp/abc
ls: /tmp/abc: No such file or directory <==真的不存在
[root@RHEL7-1 ~]# ll  /tmp/abc
Total      0                               // <==结果出现了,说明运行了mkdir命令

image.gif

如果一再重复“ls /tmp/abc || mkdir /tmp/abc”,也不会出现重复mkdir的错误。这是因为/tmp/abc已经存在,所以后续的mkdir就不会进行。

再次讨论:如果想要创建/tmp/abc/hehe这个文件,但是并不知道 /tmp/abc是否存在,那该如何办呢?

【例7-3】如果不管/tmp/abc存在与否,都要创建/tmp/abc/hehe文件,怎么办呢?

[root@RHEL7-1 ~]#ls /tmp/abc  ||  mkdir  /tmp/abc  &&  touch  /tmp/abc/hehe

image.gif

上面的例7-3总是会创建/tmp/abc/hehe,不论/tmp/abc是否存在。那么例7-3应该如何解释呢?由于Linux下面的命令都是由左往右执行的,所以例7-3有下面两种结果。

  1. 若/tmp/abc不存在。回传$?≠0;因为||遇到非为0的$?,故开始执行mkdir /tmp/abc,由于mkdir /tmp/abc会成功执行,所以回传 $?=0;因为&&遇到 $?=0,故会执行touch /tmp/abc/hehe,最终hehe就被创建了。
  2. 若/tmp/abc存在。回传 $?=0;因为||遇到 $?=0不会执行,此时 $?=0继续向后传;因为&&遇到 $?=0就开始创建/tmp/abc/hehe,所以最终/tmp/abc/hehe被创建。

整个流程如下图所示。

image.gif 编辑

上面这张图显示的两股数据中,上方的线段为不存在 /tmp/abc时所进行的命令行为,下方的线段则是存在/tmp/abc时所进行的命令行为。如上所述,下方线段由于存在 /tmp/abc所以导致 $?=0,中间的mkdir就不运行了,并将 $?=0继续往后传给后续的touch去利用。

我们再来看看下面这个例题。

【例7-4】以ls测试/tmp/bobbying是否存在:若存在,则显示“exist”;若不存在,则显示“not exist”。

这又牵涉到逻辑判断的问题,如果存在就显示某个数据,若不存在就显示其他数据,那么我们可以这样做:

ls /tmp/bobbying && echo "exist" || echo "not exist"

意思是说,在ls /tmp/bobbying运行后,若正确,就运行echo "exist",若有问题,就运行echo "not exist"。那如果写成如下的方式又会如何呢?

ls /tmp/bobbying || echo "not exist" && echo "exist"

这其实是有问题的,为什么呢?由图7-2的流程介绍,我们知道命令是一个一个往后执行,因此在上面的例子中,如果/tmp/bobbying不存在时,会进行如下动作。

① 若ls /tmp/bobbying不存在,则回传一个非0的数值。

② 接下来经过||的判断,发现前一个命令回传非0的数值,因此,程序开始运行echo "not exist",而echo "not exist" 程序肯定可以运行成功,因此会回传一个0值给后面的命令。

③ 经过&&的判断,所以就开始运行echo "exist"。

这样,在这个例子里面竟然会同时出现not exist与exist,是不是很有意思啊!请读者仔细思考。

特别提示:经过这个例题的练习,你应该了解,由于命令是一个接着一个运行的,因此,如果真要使用判断,那么 && 与 || 的顺序就不能搞错。一般来说,假设判断式有3个,也就是,command1 && command2 || command3,而且顺序通常不会变。因为一般来说,command2与command3会放置肯定可以运行成功的命令,因此,依据上面例题的逻辑分析,必须按此顺序放置各命令,请读者一定注意。

相关文章
|
存储 网络协议 Ubuntu
【C++网络编程】Socket基础:网络通讯程序入门级教程
【C++网络编程】Socket基础:网络通讯程序入门级教程
370 7
|
存储 Shell Linux
【Shell 命令集合 系统设置 】⭐ Linux 取消或删除已设置的环境变量 unset命令 使用指南
【Shell 命令集合 系统设置 】⭐ Linux 取消或删除已设置的环境变量 unset命令 使用指南
695 0
|
11月前
|
监控 Linux
Linux常用命令-2
本文继续介绍Linux常用命令,涵盖目录操作、文件操作、系统信息和进程管理等类别。具体包括mkdir、rmdir、cp、mv、rm、touch、whereis、whatis、dmesg、free、date、cal、ps、kill、killall和top等命令的使用方法和常用参数。
119 7
|
11月前
|
PHP
23 七天免登录案例
路老师分享了PHP语言的知识,帮助大家入门并深入了解PHP。本文通过一个“七天免登录”的案例,详细介绍了从创建用户表、登录页面到登录检测和退出登录的完整过程。代码示例详尽,适合初学者学习。
179 2
|
11月前
|
Linux Shell
Linux常用命令-1
本课程要求学生熟悉Linux系统终端窗口和命令基础,掌握文件目录类、系统信息类、进程管理类及其他常用命令,学时为3-6小时。课程内容涵盖Linux命令的特点、常见命令的使用方法及其应用场景,如文件浏览、目录切换、内容显示等。建议学生逐个操作命令并及时反馈问题。
135 6
|
11月前
|
存储 druid 算法
磁盘管理工具
在Linux系统安装过程中,磁盘分区是一项重要步骤,可以通过Disk Druid、RAID、LVM等方式进行分区。此外,Linux还提供了fdisk、cfdisk、parted等分区工具。本文介绍了如何使用fdisk命令进行磁盘分区,包括创建、查看、删除分区以及格式化和挂载分区的具体操作步骤。通过这些步骤,可以有效地管理和优化磁盘资源,提高系统的安全性和性能。
352 2
|
缓存 网络协议 Linux
c++实战篇(三) ——对socket通讯服务端与客户端的封装
c++实战篇(三) ——对socket通讯服务端与客户端的封装
396 0
|
11月前
|
域名解析 网络协议 虚拟化
vmware 提供的三种网络工作模式
本文介绍了VMware虚拟机的三种网络工作模式:Bridged(桥接模式)、NAT(网络地址转换模式)和Host-Only(仅主机模式)。桥接模式将虚拟机与主机通过虚拟网桥连接,实现与物理网络的直接通信;NAT模式通过虚拟NAT设备和DHCP服务器使虚拟机联网;Host-Only模式则将虚拟机与外网隔离,仅与主机通信。此外,文章还简要介绍了网络相关的基础知识,包括主机名、IP地址、子网掩码、默认网关和DNS服务器。
549 4
|
11月前
|
SQL PHP 数据库
19 PHP如何利用PDO获取结果集
路老师在知乎上分享了关于PHP语言的知识,帮助大家入门并深入了解PHP。本文介绍了PDO中获取结果集的三种方法:`fetch()`、`fetchAll()` 和 `fetchColumn()`,并通过具体案例展示了如何使用这些方法从数据库中获取数据并展示在网页上。
375 5
|
11月前
|
JavaScript PHP
17 PHP 实现批量删除功能
路老师在本文中继续优化图书删除功能,实现批量删除图书。通过添加删除按钮、表格前的复选框以及实现PHP后端逻辑,展示了完整的删除流程和效果。
128 5