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会放置肯定可以运行成功的命令,因此,依据上面例题的逻辑分析,必须按此顺序放置各命令,请读者一定注意。

相关文章
|
6月前
|
Shell 网络安全 数据安全/隐私保护
Shell基础命令(一)
Shell基础命令(一)
|
3月前
|
Shell
Shell基础知识(一)
Shell基础知识(一)
58 2
|
6月前
|
Unix Shell Linux
第一章 Shell基础知识
第一章 Shell基础知识
|
机器学习/深度学习 Shell Linux
shell基础学习
shell基础学习
74 0
|
缓存 Unix Shell
【shell基础学习】
【shell基础学习】
81 0
|
运维 Shell Linux
Linux运维之shell基础
Linux运维之shell基础
168 1
|
Shell Linux
Shell基础入门
Shell基础入门
|
Shell Linux
热饭面试复习:【linux shell 相关】-5
热饭面试复习:【linux shell 相关】-5
|
Linux Shell 数据安全/隐私保护
热饭面试复习:【linux shell 相关】-2
热饭面试复习:【linux shell 相关】-2
|
Linux Shell
热饭面试复习:【linux shell 相关】-8
热饭面试复习:【linux shell 相关】-8