这一篇文章,我们就要开始学习正式的Shell语言部分的内容。那在开始之前,我们回忆一下,javascript语言,大体都包含了哪些内容?比如数据类型(对象、字符串、数值),数据结构(对象、数组)、运算符(加减乘除与或非等)、流程控制(就是if-else,for循环等)等等,那么其实不单单是javascript语言,其他任何语言所涉及到的内容也无非如此,只不过可能在此基础上有些具体细节的不同。那么同样的,我们学习Shell也十分类似。

一、变量的定义

shell里变量的定义很简单,就像这样:

varname='abcd'  

要注意,Shell里变量的定义,也就是变量的声明,并没有像js那样需要使用变量声明的关键字。只是像上面那样,赋值既声明。

那么在Shell里,变量的定义要有几点需要注意:

  1. 变量名和等号之间不能有空格
  2. 命名只能使用英文字母、数字和下划线,首字母不能是数字
  3. 变量名中间不能有空格,可以使用下划线
  4. 不能使用标点符号
  5. 不能使用bash里的关键字

Ok,我们知道了怎么来定义一个变量,那Shell中的数据类型有哪些呢?shell中的数据类型比较特殊,从个人理解来说,Shell里只有字符串,其他的运算,比如数学运算,逻辑运算,都需要运算符或命令的参与。后面到运算符一篇的时候会详细的说明。这里先给大家打个预防针。当然,通过特定的方式可以声明类似数值、数组这样的数据,但是实际上,个人觉得它是通过命令定义的方式来实现了数据类型的特征,实际上他本质仍旧是个字符串。只是通过特定的命令,赋予了它计算的能力而已。这个我们后面再聊。

那,我们现在知道了怎么定义一个变量,接下来,我们在之前创建好的test.js文件中写点代码吧:

#!/bin/bash
a=1
b=2
c=3
echo $a $b $c

然后,我们上传到服务器后,执行该文件就可以了,如果不知道怎么使用的,请到上一篇文章查找,这里不再多说,结果可想而知:

从上面的代码可以看到,我们使用刚定义好的变量是通过美元符号+变量名的形式,或者可以通过给变量名加上花括号的形式,这两种方式是等价的:

#!/bin/bash
a=1
b=2
c=3
echo ${a} ${b} ${c}

推荐在使用变量的时候,给所有的变量都加上花括号,养成一个良好的习惯。

二、变量的分类

变量的分类,并不是指数据类型,而是指有哪些类型的变量。注意!是变量的类型,而不是数据的类型。

首先,在Shell中变量大体可以分为三种类型:

  • 局部变量(普通变量),在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问
  • 全局变量(环境变量),所有的程序都可以访问,必要时还可以自定义环境变量
  • shell变量,有一部分是全局变量,也有一部分是局部变量。

在做了简单地了解之后,我们深入的学习一下,加深我们对变量的分类的理解。

2.1、全局变量

全局变量其实主要就是环境变量,这种变量主要保存的是系统操作环境的相关变量。常用的环境变量有:

变量名 含义 示例
HOSTNAME 主机名 HOSTNAME=localhost
SHELL 当前的shell SHELL=/bin/bash
HISTSIZE 历史命令条数 HISTSIZE=1000
SSH_CLIENT 当前操作环境如果是用SSH连接的话,这里会记录客户端IP SSH_CLIENT=192.168.1.100 57596 22
USER 当前登录的用户 USER=root

这些,我们可以直接echo打印,看下这些环境变量的具体内容。

#!/bin/bash
echo $PATH
echo $USER
echo $SHELL
echo $HOSTNAME

打印结果如下:

刚才咱们查看的这些环境变量,属于BASH内置的环境变量,那么我们是否可以自定义环境变量呢?答案是可以的。

我们先来看两个命令:

  • export命令,export [-fnp][变量名称]=[变量设置值],用于设置或显示环境变量

    • -n,删除指定的变量,但是实际上变量并未删除,只是不会输出到后续指令的执行环境中。
  • env命令,查看环境变量。

那我们来试一下:

#!/bin/bash
export zaking=1234
env | grep zaking

这样就可以了。

2.2、普通变量

普通变量比较好理解,就是我们自己创建的,可能需要在脚本中使用的变量。我们来试试一个比较简单的,完整的定义普通变量的例子:

#!/bin/bash
name=zaking
readonly age=18
job=web
echo $name $age $job
unset name
echo $name $age $job
unset age
echo $name $age $job

先解释下上面的几个新命令:

  • unset命令,删除已定义的变量,注意unset不能删除只读变量
  • readonly命令,使变量只读

上面的结果就很容易猜到:

三、参数的传递

是实话,这个东西我不知道该不该放在这,它到底属于什么,它属于变量分类里面的那个shell变量的类型么?还是说它不是变量?但是它为什么又有变量的特征,你说它是运算符呢?它又不参与运算。所以,它看起来像是一个用符号表示的变量。我们下面就看看它们都是什么吧:

3.1、位置参数变量
变量 作用
$n n为数字,$0代表命令本身,$1-$9代表第1到第9个参数,10以上的参数需要用大括号包含,如${10}
$* 这个变量代表命令中所有的参数,$*把所有的变看数看成一个整体
$@ 这个变量也代表命令行中所有的参数,不过$@把每个参数进行区分
$# 这个变量代表命令行中所有参数的个数

咱们来具体看下代码,就知道咋回事了:

#!/bin/bash
echo "我开始了"echo "第一个参数为:$1"echo "第二个参数为:$2"echo "参数个数为:$#"echo "传递的参数作为一个字符串显示:$*"echo "传递的参数作为$#个字符串显示:$@"

打印的结果就是:

所以这些从使用的角度来说其实还好,并不复杂,记下来就是了,但是从类别的角度来说,我真没找到具体的资料它属于哪一个类别。哎...我们继续吧。

3.2、预定义变量

简单说就是脚本中预先定义好的变量,变量名不能自定义,变量的作用也是固定的:

变量 作用
$? 最后一次执行的命令的返回状态。0表示正确执行,非0表示不正确执行
$$ 当前进程的进程号(PID)
$! 后台运行的最后一个进程的ID号
$- 显示Shell使用的当前选项,与set命令功能相同。

也没啥好说的。对吧?大家自己打印看一下吧。

3.3、read命令

该命令用于从标准输入设备读取参数。它有几个选项,很有用:

  • -p,后面跟提示信息,在输入前打印提示信息
  • -t,后面跟秒数,定义输入字符的等待时间
  • -n,后面跟数字,定义输入文本的长度
  • -s,安静模式,在输入字符时不在屏幕上显示,一般用于密码输入使用
  • -e,在输入的时候可以使用命令补全功能

我们还是来看个例子吧:

#!/bin/bash
read -p 'please input your name:' -t 5 name
echo -e "\n"
read -p 'please input you gender:' -n 1 gender
echo -e "\n"
read -p 'please input your password:' -s password
echo -e "\n"
echo $name,$gender,$password

大家可以去执行一下试一试。

四、declare命令

还记在开始的时候,变量的定义的那一部分,我说了,个人感觉shell里并没有真正意义上的数据类型,只有字符串。那么下面通过declare命令的学习,我们来尝试验证一下我的论点。

declare命令的主要作用就是:声明shell变量。注意,我没说明是声明什么变量,只是声明变量。

declare [+/-][rxi][变量名称=设置值]

它常用的选项有这些:

  • +/-  "-"可用来指定变量的属性,"+"则是取消变量所设的属性。
  • -a,将变量声明为数组类型。
  • -i,将变量声明为整数类型。
  • -r,将变量声明为只读。
  • -p,显示指定变量被声明的类型。
  • -x,将变量声明为环境变量。

这么说,还比较模糊。咱们还是得实践一下:

#!/bin/bash
a=1
b=2
c=$a+$b
echo $c
declare -i c
echo $c
declare -i c=$a+$b
echo $c

你猜,结果是什么:

所以,就像我之前说的,这种感觉并不像是javascript中那样,类型是一个纯粹的值,它更像是一种属性:

上面的结果,我在代码里加了两行:

#!/bin/bash
a=1
b=2
c=$a+$b
echo $c
declare -i c
echo $c
declare -i c=$a+$b
echo $c
echo '-------'
declare -p c

所以,你看,它本身还是个字符串罢了,只是赋予了一个属性。让系统对其进行分辨。

我们再来试一下其它的选项:

#!/bin/bash
declare -x m=1
declare -p m
env | grep m

大家自行试一下这个代码,看下结果是啥,下面我们再试一下数组:

#!/bin/bash
#声明为数组类型
declare -a arrs
arrs[0]=zaking
arrs[1]=wong
#默认只打印第一个元素
echo ${arrs}
#打印第2个元素
echo ${arrs[1]}
#打印全部
echo ${arrs[*]}

结果大家自己去试一下哦。

五、环境变量配置文件

最后,我们来看一下环境变量相关的配置文件。

  1. /etc/profile,保存系统变量,就是就是环境变量,对所有用户生效。

    • 该文件登录操作系统时,为每个用户设置环境信息,当用户第一次登录时,该文件被执行。也就是说这个文件对每个shell都有效,用于获取系统的环境信息。
  2. /etc/bashrc,为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取。也就是说,当用户通过bash执行了shell时,运行这个文件。
  3. ~/.bash_profile,它会调用~/.bashrc。可以再该文件修改PATH路径。仅对当前用户有效。
  4. ~/.bashrc,保存别名,可在该文件修改alias,它最终会调用/etc/bashrc。仅对当前用户有效。

在系统启动时,上面四个文件的执行顺序是:1->3->4->2。

这里要提一下,当修改以上文件时,需要将系统注销后重新登录,但是我们可以使用source [文件路径] 的方式,使其立即生效。

我们再来看看其他几个有用的文件:

  1. ~/.bash_logout,注销时生效的环境变量配置文件。
  2. ~/.bash_history,正确退出计算机的时候会历史记录会写入文件。
  3. /etc/issue,本地终端欢迎信息。
  4. /etc/issue.net,远程终端欢迎信息。
  5. /etc/motd,不管远程还是本地都可以生效 。

  

《前端运维》一、Linux基础--04Shell变量的更多相关文章

  1. 运维之linux基础知识(一)

    运维之linux基础知识(一) 1.GUI:Graphic User Interface 图形用户界面 2.CLI:Command line Interface 命令行界面 3 dll:Dynamic ...

  2. 运维之Linux基础(二)

    运维之Linux基础(二) 1. file 命令基期用法 2. 文件系统 Linux的文件系统结构是树状结构,所有的文件都在/root跟目录下 /boot:系统启动相关的文件, 如:内核.initrd ...

  3. 运维之Linux基础知识(三)

    运维之Linux基础知识(三) 1. 查看文本 cat tac more less head tail 1.1 cat 连接并显示文件 cat -n:在显示的时候,将每一行编号 -E:显示结束符$ - ...

  4. IT运维的五大基础知识

    IT运维的五大基础知识 | 浏览:331 | 更新:2014-09-25 11:36 IT运维对于很多企业都很重要,接下来运维的一些基础知识天天客服IT运维总监龙少文,就给大家介绍下IT运维的基础知识 ...

  5. 【Linux 运维】Linux 目录

    目录 [Linux 运维]Centos7初始化网络配置 [Linux 运维]linux系统修改主机名 [Linux 运维]linux系统关机.重启.注销命令 [Linux 运维]linux系统查看版本 ...

  6. 自动化运维工具-Ansible基础

    目录 自动化运维工具-Ansible基础 什么是Ansible 同类型软件对比 Ansible的功能及优点 Ansible的架构 Ansible的执行流程 安装Ansible ansible配置文件 ...

  7. 运维 07 Linux系统基础优化及常用命令

    Linux系统基础优化及常用命令   Linux基础系统优化 引言没有,只有一张图. Linux的网络功能相当强悍,一时之间我们无法了解所有的网络命令,在配置服务器基础环境时,先了解下网络参数设定命令 ...

  8. 论Linux运维的一些基础安全知识和简单办法

    不知不觉本人来北京也已经第三个年头了,从一个Linux小小鸟,开始,2012年我参加了第一份工作,其实现在想想其实我是幸运的,本来求学的时候,就没好好的学Linux,我认为有Cisco知识从上wind ...

  9. 更优雅的配置:docker/运维/业务中的环境变量

    目录 docker-compose 环境变量 .env 文件 env_file docker stack 不支持基于文件的环境变量 envsubst envsubst.py 1. 使用行内键值对 2. ...

随机推荐

  1. Ajax向服务器发起请求

    Ajax向服务器发起请求的三个步骤: 1:创建Ajax 2:打开Ajax,打开Ajax请求 3:向服务器发起请求:需要知道地址和是get请求还是post方法 向服务器发起请求的两个方法:open 和 ...

  2. CentOS下搭建自动化测试基础框架:Jenkins+Maven+TestNG+ReportNG

    1. 安装JDK 1.1 卸载系统默认已安装的open-jdk rpm -qa|grep java 查出来openjdk相关的应用,把查出来的所有都要通过下面的命令给卸载掉 rpm -e --node ...

  3. MSTP多生成树协议

    MSTP多生成树协议 目录 MSTP多生成树协议 1.MSTP(Multiple Spanning Tree Protocol)概述 2.STP.RSTP.PVST的应用缺陷 3.MSTP的主要特点 ...

  4. JabRef

    # JabRef 下载 https://www.fosshub.com/JabRef.html # JabRef 安装 自己更改下目录直接安装接可以了 # 新建自己的库, 然后点击保存就可以了. # ...

  5. linux_20

    总结tomcat优化方法 java程序出现oom如何解决?什么场景下会出现oom? 简述redis特点及其应用场景 对比redis的RDB.AOF模式的优缺点 实现redis哨兵,模拟master故障 ...

  6. Solution -「HAOI 2018」「洛谷 P4491」染色

    \(\mathcal{Description}\)   Link.   用 \(m\) 种颜色为长为 \(n\) 的序列染色,每个位置一种颜色.对于一种染色方案,其价值为 \(w(\text{出现恰 ...

  7. 『无为则无心』Python面向对象 — 45、面向对象编程

    目录 1.面向对象编程的概念 2.面向对象编程和面向过程编程的区别 (1)面向过程编程 (2)面向对象编程 3.举例理解面向对象 4.Python的面向对象编程 5.面向对象的几大核心特性 1.面向对 ...

  8. 使用SpringBoot整合MybatisPlus出现 : java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

    解决方案一: 将测试类的包路径改为和主启动类的一致 解决方法二: 不想改测试类的路径 就在测试类上添加要测试的类的classes

  9. [LeetCode]1295. 统计位数为偶数的数字

    给你一个整数数组 nums,请你返回其中位数为 偶数 的数字的个数. 示例 1: 输入:nums = [12,345,2,6,7896] 输出:2 解释: 12 是 2 位数字(位数为偶数)  345 ...

  10. CobaltStrike逆向学习系列(14):CS功能分析-DotNet

    这是[信安成长计划]的第 14 篇文章 0x00 目录 0x01 DotNet功能分析 0x02 DotNet功能执行 0x03 写在最后 在上两篇文章中,讲述了 CS 中的一种功能执行方式 RDI, ...