Shell变量阶段性总结与Linux环境变量讲解

1.运行方法


  1. 通过可执行程序进行执行

    chmod +x ./test.sh
    ./test.sh
    

    赋予test.sh脚本文件执行权限,然后在脚本所在目录,通过./test.sh执行脚本。不能直接test.sh是因为直接调用他会去系统PATH环境变量里去寻找执行文件。

  2. 通过sh解释器来执行脚本

    /bin/sh test.sh
    

    也可以直接输入sh test.sh。因为通常情况下/bin目录已经被配置到了PATH中。

2.shell变量


your_name="zhangsan"
  1. 变量名和等号之间不能有空格
  2. 定义变量时,不加$符号
  3. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  4. 中间不能有空格,可以使用下划线 _
  5. 不能使用标点符号
  6. 不能使用bash里的关键字
2.1 使用变量
your_name="zhangsan"
echo $your_name
echo ${your_name}

变量名外面的花括号{ }是可选的,加花括号{ }是为了帮助解释器识别变量的边界

已定义的变量,可以被重新定义.

2.2 只读变量

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

当我尝试vim readOnlyVar.sh更改只读变量时:

#!/bin/bash

myString="jkchou"
readonly myString
myString="hh"

系统会提示报错:

[root@localhost variable]# sh readOnlyVar.sh 
readOnlyVar.sh: line 5: myString: readonly variable
2.2 删除变量

使用unset命令可以删除变量。

unset variable_name

变量被删除后不能再次使用。unset 命令不能删除只读变量。

2.3 变量引用概述

Shell中使用$来引用变量

echo $variable_name

需要注意的是双引号""和单引号’'在其引用变量时要注意,效果和直接使用引号输出略有差异,如下述程序:

#!/bin/sh

var="Hello"

echo "hello"
echo 'hello'
echo "$var"
echo '$var'

输出结果为:

[root@localhost variable]# sh referVar.sh 
hello
hello
Hello
$var

直接使用双引号和单引号输出常量串,直接输出,但是使用变量引用时,双引号会引用其中的变量值,输出变量的值,而单引号不会引用变量,而是直接输出相应的字符。其次,单引号中的内容不能出现转义字符的单引号的,但是双引号就可以出现转义双引号。例如:

echo 'hello everyone, i am gg '
#正确,将输出hello everyone, i am gg 

echo 'hello everyone, i am \'gg\' '
#错误,将报错:unexpected EOF while looking for matching `''

echo 'hello everyone,''i am gg '
#正确,这属于字符串拼接,虽然是两对'',但是没有嵌套在一起,将输出这句话

echo "hello everyone, \"i am gg\" "
#正确,将输出hello everyone, "i am gg  "

Shell中还有好多常见的引用,比如有$var、${var}、${#var}、${var:start_char:length}等等,大都是对字符串进行操作的,这里不做列出,想要了解的找Shell字符串相关内容,需要注意的是,如${#var}这种,花括号{}是不能省略的,否则无法输出想要的返回值。

2.4 变量输入

Shell脚本中通过echo输出变量,通过read关键字读取变量。当然,是从命令行读取。

#!/bin/sh

read var
echo "your input is :"$var

如果我输入的是jkchou,那么将在控制台有如下结果:

[root@localhost variable]# sh readVar.sh 
jkchou
your input is :jkchou
2.5 变量分类

上述脚本中的变量通常被称为局部变量或者本地变量,Shell中还存在一些独特的变量,包括环境变量、位置变量、标准变量和特殊变量。下面,我只挑经常用得到的环境变量来具体说一说,其他几个特殊的变量只做个概述。

2.5.1 位置变量

位置变量即执行脚本时,传入脚本中对应脚本位置的变量。类似于调用函数的时候,函数的参数,引用方法为$+参数位置,比如$0、$1、$2等。$0比较特殊,代表的是脚本的名称,其余$1代表的是脚本的第一个参数,以此类推。比如:

#!/bin/sh

echo "name of the script:"$0
echo "first variable:"$1
echo "second variable:"$2
echo "third variable:"$3
echo "fourth variable:"$4

执行这个脚本:

[root@localhost variable]# sh varSorted.sh A B C
name of the script:varSorted.sh
first variable:A
second variable:B
third variable:C
fourth variable:

可以看到,不输入第四个参数的时候是不会打印出$4的,同理,多输入第五个,也不会打印出第五个参数。可以配合shift,使参数左移一位,上述脚本,如果加入个shift,则只会打印出B和C,A就被左移出去了,两个shift就是左移两次。

2.5.2 标准标量

标准变量,就是环境变量。细看的话,属于系统环境变量,在bash环境建立时生成,在/etc/profile 文件中可以查看系统中的标准环境变量。

2.5.3 特殊变量

变量名和含义如下:

  • # 传递到脚本或函数的参数数量
  • ? 前一个命令执行情况,0表示成功,其他值表示失败
  • $ 运行当前脚本的当前进程id号
  • ! 运行脚本最后一个命令
  • * 传递给脚本或函数的全部数量

例子如下:

#!/bin/bash

echo "number of variables:"$#
echo "pre commands' situation:"$?
echo "cur script's processes identity number:"$$
echo "run last commands:"$!
echo "all the paramaters:"$*

运行结果:

[root@localhost variable]# vim specialVar.sh
[root@localhost variable]# sh specialVar.sh A B C
number of variables:3
pre commands' situation:0
cur script's processes identity number:66446
run last commands:
all the paramaters:A B C
2.5.4 环境变量

讲在前面:以下引用内容来自man bash,后续内容完全为个人理解与查阅得到。

FILES
/bin/bash
The bash executable
/etc/profile
The systemwide initialization file, executed for login shells
/etc/bash.bash_logout
The systemwide login shell cleanup file, executed when a login
shell exits
~/.bash_profile
The personal initialization file, executed for login shells
~/.bashrc
The individual per-interactive-shell startup file
~/.bash_logout
The individual login shell cleanup file, executed when a login
shell exits
~/.inputrc
Individual readline initialization file

环境变量分为系统环境变量用户环境变量

bash命令与应用程序命令的执行是需要运行环境的,这些环境的构成正是环境变量。举个例子,当我们在编写java程序时,需要jdk,jdk中的bin下有一个叫javac的二进制文件,通过javac javafile_name 可以实现对这个.java文件的编译。如果没有配置环境变量,我们只能指定这个bin目录下的javac文件来编译java文件,比如:

在hello.java的目录下输入:
/usr/java/jdk1.8.0_151/bin/javac hello.java
或者
cd /usr/java/jdk1.8.0_151/bin/
javac ~/Desktop/hello.java

以及使用/usr/local/bin、/usr/bin、/bin下等等的指令时,这些都是默认配置到环境变量中的,否则我们将无法使用与系统交互/应用交互的各种指令;除此之外,许多应用的运行环境也需要一些执行程序的支持,当在其安装目录找不到时,就会去环境变量里寻找,找不到就无法实现某些功能。

Linux系统环境变量的配置在:/etc/profile、/etc/profile.d、/etc/bashrc。他们的区别在于启动时机和作用对象的不同。经过我的查阅,概述性的总结如下:

  • /etc/profile : 对所有用户生效;当用户第一次登录操作系统,该文件被执行;不建议在此配置环境变量。

  • /etc/profile.d : 对所有用户生效;每次执行/etc/profile时,该文件都会被执行,其内部有许多脚本文件,被执行时,也是执行该目录下的所有脚本文件;建议在此配置环境变量,易于修改和移植,添加删除修改方便,耦合度低。
    可以在profile中看到执行profile.d的代码:

    for i in /etc/profile.d/*.sh ; do
        if [ -r "$i" ]; then
            if [ "${-#*i}" != "$-" ]; then
                . "$i"
            else
                . "$i" >/dev/null 2>&1
            fi
        fi
    done
    
  • /etc/bashrc : 对所有用户生效;每当用户运行bash shell (可以理解为终端,大多Linux版本默认以bash作为默认shell),这个文件就会被执行,也就是说,每当用户shell执行了bash脚本和终端,这个文件被执行,并对所有用户生效;不建议在此配置环境变量。

登录shell和非登录shell的区别:

通过bash、sh等指令直接进入的命令行模式均属于非登录shell,说人话我理解的就是没有输入账户密码的,就属于非登录。

Linux用户环境变量的配置在: ~/.bash_profile、~/.bash_logout、~/.bashrc

[jkchou@localhost /]$ ls -l ~/.bash*
-rw-------. 1 jkchou jkchou 10748 Oct 23 04:32 /home/jkchou/.bash_history
-rw-r--r--. 1 jkchou jkchou    18 May 10  2016 /home/jkchou/.bash_logout
-rw-r--r--. 1 jkchou jkchou   176 May 10  2016 /home/jkchou/.bash_profile
-rw-r--r--. 1 jkchou jkchou   124 May 10  2016 /home/jkchou/.bashrc
  • ~/.bash_profile : 和/etc/profile类似,不过是用户级别的,只对当前~用户生效;当用户登录时,该文件被执行一次;紧接着它还会调用一次~/.bashrc;建议在此配置环境变量。默认下的Cent OS6.7的bash_profile文件内容如下:

    [jkchou@localhost /]$ cat ~/.bash_profile 
    # .bash_profile
    
    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
    	. ~/.bashrc
    fi
    
    # User specific environment and startup programs
    
    PATH=$PATH:$HOME/bin
    
    export PATH
    
  • ~/.bashrc : 和/etc/bashrc类似,是用户级别的;当登录时或者打开新的shell 时,该文件会被加载一次,登录shell和非登录shell都可以使用.bashrc中的内容;不建议在此配置环境变量。

  • ~/.bash_logout : 用户级别;当退出bash shell时,执行它(看这个调用时机也知道,不能在它里面放正常内容了吧?233)。

综上所述,通常情况下,登录用户,可以得出如下结论的执行时机:

/etc/profile -> /etc/profile.d -> /etc/bashrc -> ~/.bash_profile -> ~/.bashrc

除此之外,使用export可以设置和现实环境变量,但他设置的环境变量是会话级的,关闭当前终端后,就会失效了。

2.5.5 备注

由于我用的是Mac操作系统,虽然都是基于Unix内核,但是我还是想说说我个人的理解,Mac在2019年以zsh作为默认的shell,zsh就是在bash的基础上进行了大量的改进,同时加入了bash、ksh和tcsh的某些功能。所以,当我在Mac的bash_profile中配置环境变量后,无论怎么样,它并不会生效,这是因为Mac并没有自动的在某个地方调用bash相关的指令,而是调用的~/.zshrc 和~/.zprofile ,所以,有三种方法,可以调用bash写的环境变量:

  1. 配置环境变量到~/.zshrc 或~/.zprofile
  2. 使用source ~/.bash_profile或source ~/.bashrc
  3. 在到~/.zshrc 或~/.zprofile最后一行加上source ~/.bash_profile或source ~/.bashrc

但是Mac和Linux还是有很大的区别的,以下内容截自官方文档:

STARTUP/SHUTDOWN FILES

​ Commands are first read from /etc/zshenv; this cannot be overridden.

​ Subsequent behaviour is modified by the RCS and GLOBAL_RCS options; the

​ former affects all startup files, while the second only affects global

​ startup files (those shown here with an path starting with a /). If one

​ of the options is unset at any point, any subsequent startup file(s) of

​ the corresponding type will not be read. It is also possible for a file

​ in $ZDOTDIR to re-enable GLOBAL_RCS. Both RCS and GLOBAL_RCS are set by

​ default.

​ Commands are then read from $ZDOTDIR/.zshenv. If the shell is a login

​ shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zprofile.

​ Then, if the shell is interactive, commands are read from /etc/zshrc and

​ then $ZDOTDIR/.zshrc. Finally, if the shell is a login shell,

/etc/zlogin and $ZDOTDIR/.zlogin are read.

………………

可以看出,首先执行的是/etc/zshenv,想了解更多直接man zsh

2.6 变量运算

Shell中实现算术运算一般通过两个命令:let和expr

let

直接上例子:

#!/bin/bash

i=1
echo "i="$i
let i=i+2
echo "i="$i
let "i=i+4"
echo "i="$i
i=i+3
echo "i="$i

结果:

[jkchou@localhost shell Test]$ sh letTest.sh 
i=1
i=3
i=7
i=i+3

let也可以用((算数表达式))来代替,比如:

((i+=3))
expr

直接上代码:

#!/bin/bash

a=10
b=10
c=`expr $a + $b`
echo "c="$c

需要注意的是,``是tab上,!左边的那个符号,不是单引号!!,除此之外, a 、 a、 ab和算数运算符+之间需要有空格,否则会原样输出:c=10+10

结果:

[jkchou@localhost shell Test]$ sh exprTest.sh 
c=20

3.小结


该文章最终目的是自我学习与提升,不做任何商业用途,转载还请标明出处,写作不易。如有错误欢迎指出,毕竟我只是个本科菜鸟。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值