Bash Shell变量既不同于通常意义上的普通变量也不同于一般的脚本语言的变量,在默认情况下它使用字符串来保存变量的形式;在本文的末尾作为补充加上了“Shell编程的块注释的四种写法”
说明:Bash环境
对比一下,
Java:int a = 12;
Python:a = 12(a是int类型)
Bash:a=12(a是字符串,12实际上是‘12’)
1. 在默认情况下,每个变量的值都是字符串(不论在赋值时有没有打引号)
2. 使用declare命令声明变量的存储类型(参数-a,-i等)
还是通过例子讲解:
var1=value
var2=99
1. 变量的赋值等号和变量名之间不能有空格,否则将不再是“赋值”操作而是“判断相等”
var=12 #赋值
var = 12 #判断相等
2. 如果右值不包含任何空白符,就不需要使用引号进行引用,否则需要使用单引号或者双引号进行引用
var=100 #不需要引号
var='Hello world' #需要引号进行引用
3. 在变量名前加上$前缀就可以输出变量的内容
var="value" #给变量var赋值
echo $var #输出value
echo ${var} #和上面一个命令等价,也是输出value
0. Linux的环境变量是存储于RAM中的,每个Process启动时,OS会往Process的RAM中写入环境变量,所以每个Process的环境变量间是相互独立的。 Linux每个Process启动时的初始环境变量是从其父进程继承过来的,但是一旦子进程启动后,那么不会再和父进程的环境变量存在任何依赖关系,子进程的环境变量的更改不会影响父进程,反之亦然。 所以,要控制程序运行时能获取的环境变量,只能在父进程中写入
1. 环境变量是指“未在当前进程中定义而在父进程中继承而来的变量”
例如:HTTP_PROXY,它定义了互联网连接应该使用那个代理服务器
2. 使用export
命令来设置环境变量
HTTP_PROXY=192.168.1.23:3128
export HTTP_PROXY
export HTTP_PROXY=192.168.1.23:3128
这两种写法是等价的
此后,从当前shell脚本执行的任何应用都会继承这个变量
3. 在默认情况下,有很多标准换将变量可供使用
echo $PATH #输出/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Mono.framework/Versions/Current/Commands
环境变量通常用来存储路径列表,这些路径用于可执行文件、库文件等;例如$PATH、$LD_LIBRARY_PATH,它看起来像这样:
PATH=/usr/bin:/bin
LD_LIBRARY_PATH=/usr/lib:/lib
其中冒号(:)是分隔符,用于分隔多个路径,这意味着只要shell运行二进制可执行文件时,它会先查找/usr/bin,然后是/bin
当你必须使用源码编译生成程序并将其安装到某个特定路径中时,有项极其常见的任务就是将该程序的bin目录加入到PATH环境变量;假设我们要将myapp安装到/opt/myapp,它的二进制文件在bin目录中,库文件在lib目录中
实战方法:
export PATH=/opt/myapp/bin:$PATH
export LD_LIBRARY_PATH=/opt/myapp/lib;$LD_LIBRARY_PATH
PATH和LD_LIBRARY现在看起来应该像这样:
PATH=/opt/myapp/bin:usr/bin/:bin
LD_LIBRARY_PATH=/opt/myapp/lib:/usr/lib:lib
不过我们可以把下面的函数加入到.bashrc-,让一切更简单:
prepend() {[-d "$2"] && eval $1=\"$2':'\$$1\" && export $1;}
像这样使用函数:
prepend PATH /opt/myapp/bin
prepend LD_LIBRARY_PATH /opt/myapp/lib
export命令的作用就是设置环境变量;注意的是,export设置的环境变量只对当前进程和由该进程产生的子进程有效
export a='test'
这样的脚本执行完后,是不会有所谓的变量a的
export a='test';bash
在该进程结束前开启一个新的子进程,在该子进程中可以使用变量a
4. 谈谈source命令执行、set命令、export命令的不同
1.)set:设置本地变量
2.)export:设置环境变量,在当前进程和子进程中生效,重启后失效;export命令可以用于传递一个或多个变量的值到任何后继脚本
3.)source:在当前进程执行Shell脚本,source 命令可以影响执行脚本的父shell的环境,而 export 则只能影响其子shell的环境,source 命令会强制执行脚本中的全部命令,而忽略文件的权限;另外source(由C语言而来)可以使用点命令(.)代替,用法和source一样(由Bourne Shell而来)
5. ~/.bashrc
该文件包含专用于单个人的bash shell 的bash 信息,当登录时以及每次打开一个新的shell 时, 该该文件被读取
单个用户此文件的修改会影响到他以后的每一次登陆系统和每一次新开一个bash 。因此,可以在这里设置单个用户的特殊的环境变量或者特殊的操作,那么每次它新登陆系统或者新开一个bash ,都会去获取相应的特殊的环境变量和特殊操作
1. 在环境变量中,分为“临时变量”和“永久变量”
“临时变量”通过export命令声明,在重启或关闭shell时失效
“永久变量”需要修改配置文件,并执行该脚本
2. /etc/profile文件、/etc/bashrc文件区别
(如果系统是 ubuntu 或者 debian 的话, 就不会有 /etc/bashrc 而会有 /etc/bash.bashrc 文件)
“login shell” 代表用户登入, 比如使用 su -命令, 或者用 ssh 连接到某一个服务器上, 都会使用该用户默认 shell 启动 login shell 模式,该模式下的 shell 会去自动执行 /etc/profile 和 ~/.profile 文件, 但不会执行任何的 bashrc 文件, 所以一般再 /etc/profile 或者 ~/.profile 里我们会手动去 source bashrc 文件
而 no-login shell 的情况是我们在终端下直接输入 bash 或者 bash -c “CMD” 来启动的 shell,该模式下是不会自动去运行任何的 profile 文件
interactive shell 是交互式shell, 顾名思义就是用来和用户交互的, 提供了命令提示符可以输入命令,该模式下会存在一个叫 PS1 的环境变量, 如果还不是 login shell 的则会去 source /etc/bash.bashrc 和 ~/.bashrc 文件
non-interactive shell 则一般是通过 bash -c “CMD” 来执行的bash,该模式下不会执行任何的 rc 文件, 不过还存在一种特殊情况这个我之后详细讲述
profile文件:
其实看名字就能了解大概了, profile 是某个用户唯一的用来设置环境变量的地方, 因为用户可以有多个 shell 比如 bash, sh, zsh 之类的, 但像环境变量这种其实只需要在统一的一个地方初始化就可以了, 而这就是 profile
bashrc文件
bashrc 也是看名字就知道, 是专门用来给 bash 做初始化的比如用来初始化 bash 的设置, bash 的代码补全, bash 的别名, bash 的颜色. 以此类推也就还会有 shrc, zshrc 这样的文件存在了, 只是 bash 太常用了而已
=> 代表 在文件内部 source, 换行的 => 代表自身执行结束以后在 source, 同一行表示先 source 在执行自身
3. 设置永久变量的三种方法
1. 在/etc/profile文件中添加变量(对所有用户生效)
vi /etc/profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
2. 在用户目录下的.bash_profile文件中增加变量(对当前用户生效)
vi ~/.bash_profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注意:脚本文件在重启后生效,如果要立即生效还得source xx.sh
命令
3. 使用unset命令删除环境变量
unset TEMP_KEVIN
表示删除环境变量TEMP_KEVIN
注意,unset命令
只能对当前Shell环境有效,如果要永久删除还得去配置文件里面去删除该变量
: '
注释
'
: <<eof
注释
eof
: <<!
注释
!
if false; then
注释
fi
注意:冒号后面有一个空格!
推荐使用第一种……