学习linux杂七杂八——关于shell中的变量

var=value 变量定义并赋值,注意等号前后不能与空格相邻,如果需要有空格(其他特> 殊字符,如$,回车,",',\等)可用转义字符\进行转义。
变量命名规则同C语言。

变量值两端可以用"或者',"号中的$保持变量特性不变,但'号中的特殊字符即为其字> 面值。

echo $var 获取变量的值。

neeo@neeo-labtop:~$ hi=hello  #定义变量hi
neeo@neeo-labtop:~$ echo $hi #获取变量hi的值
hello
neeo@neeo-labtop:~$ hi=$hiworld #像这样不能实现将hi变量值变为helloworld的目的,因为$hiworld被认为是一个变量,而这个变量并不存在,hi变成了空值。
neeo@neeo-labtop:~$ echo $hi

neeo@neeo-labtop:~$ hi=hello 
neeo@neeo-labtop:~$ hi=$hi,world #但是这样是可以工作的,原因是逗号不是合法变量名的一部分,只有$hi被识别为一个变量。
neeo@neeo-labtop:~$ echo $hi
hello,world
neeo@neeo-labtop:~$ hi=hello
neeo@neeo-labtop:~$ hi="$hi"world #可以这样扩充变量值,注意双引号中的$符号依然具有其特殊性。
neeo@neeo-labtop:~$ echo $hi
helloworld
neeo@neeo-labtop:~$ hi=${hi}world #也可以这样,注意{}的位置和双引号的位置是不同的。
neeo@neeo-labtop:~$ echo $hi
helloworldworld
neeo@neeo-labtop:~$ hi='$hi'world #如果你写成了这样(双引号被单引号替代),$符号失去了其特殊性,变成了一个字面值,结果就是下面这样。
neeo@neeo-labtop:~$ echo $hi
$hiworld

有关数组的定义 arr[index]=value

neeo@neeo-labtop:~$ arr[1]=one #这4行定义了一个数组
neeo@neeo-labtop:~$ arr[0]=zero
neeo@neeo-labtop:~$ arr[2]=two
neeo@neeo-labtop:~$ arr[10]=ten
neeo@neeo-labtop:~$ echo $arr # $arr的结果等同于 arr[0],
zero
neeo@neeo-labtop:~$ echo ${arr} #结果同上
zero
neeo@neeo-labtop:~$ echo "${arr},${arr[1]}" #看来像${arr[1]}这样可以取得arr[1]的值
zero,one
neeo@neeo-labtop:~$ echo $arr[3] #那么这样能取得arr[3]的值么?看结果,不解释
zero[3]
neeo@neeo-labtop:~$ echo ${arr[3]} #这样应该可以取到了吧!因为arr[3]没有值,当然为空。

neeo@neeo-labtop:~$ unset arr #(这里是剧透,unset下面才讲到)有意思的在这里,unset arr并不等同于unset arr[0],事实上,unset把整个arr都干掉了。注意区分上面的 echo $arr。
neeo@neeo-labtop:~$ echo ${arr[1]} #被unset扫荡过的arr,1号成员消失了。

neeo@neeo-labtop:~$ 
#不要走开哦,下面介绍declare时有数组定义的新方法。
neeo@neeo-labtop:~$ arr=(0 1 2) #还可以这样声明数组,注意值之间用空格分隔。
neeo@neeo-labtop:~$ echo ${arr}
0
neeo@neeo-labtop:~$ echo ${arr[2]}
2
neeo@neeo-labtop:~$

declare 和typeset

declare的执行方式:declare [-aAfFilrtux] [-p] [name[=value] ...] 

其中:

-f    #列出函数列表,包括函数体
-F    #列出函数列表,尽显示名称
#------------分隔线,下面是设定变量属性用的----------
-a    #变量为一个数组(就是类似C语言中的数组,用整数做下标)
-A    #变量为一个关联数组(用一个字符串做下标,key-value,类似于C#中的字典,健唯一)
-i    #变量为一个整数
-l    #变量的值为小写(这是小写的L不适大写的i)
-u    #变量的值为大写
-r    #变量为一个只读变量(很彪悍,不能改不能删,见下面讲到的readony)
-x    #声明为环境变量(类似于export,看下面)
-t    #变量具有'trace'属性
neeo@neeo-labtop:~$ declare -f | less #显示函数列表,包括函数体

#--------------下面是结果---------------------
_ImageMagick () 
{ 
    local prev;
    prev=${COMP_WORDS[COMP_CWORD-1]};
    case "$prev" in 
        -channel)
            COMPREPLY=($( compgen -W 'Red Green Blue Opacity \
                Matte Cyan Magenta Yellow Black' -- "$cur" ));
            return 0
        ;;
        -colormap)
            COMPREPLY=($( compgen -W 'shared private' -- "$cur" ));
            return 0
        ;;
#---------------此处省略无数字-----------------

neeo@neeo-labtop:~$ declare -F | less #显示函数列表,仅名称
#--------------下面是结果---------------------
declare -f _ImageMagick
declare -f __get_cword3
declare -f __get_cword4
declare -f __git_aliased_command
declare -f __git_aliases
declare -f __git_complete_file
declare -f __git_complete_remote_or_refspec
declare -f __git_complete_revlist
declare -f __git_complete_strategy
declare -f __git_compute_all_commands
declare -f __git_compute_merge_strategies
declare -f __git_compute_porcelain_commands
declare -f __git_config_get_set_variables
declare -f __git_find_on_cmdline
declare -f __git_has_doubledash

#---------------此处省略无数字-----------------

neeo@neeo-labtop:~$ declare -a arr=(0 1 2 3) #定义数组
neeo@neeo-labtop:~$ echo ${arr[*]} #显示数组值,用*表示将数组所有内容取出组成一个字符串。
0 1 2 3
neeo@neeo-labtop:~$ echo ${arr[@]} #显示数组值,用 @表示将数组所有内容用空格分隔显示
0 1 2 3
neeo@neeo-labtop:~$ declare -A dict #定义一个关联数组
neeo@neeo-labtop:~$ dict[key]=value #设定一个键值
neeo@neeo-labtop:~$ echo ${dict[*]} #显示
value
neeo@neeo-labtop:~$ echo ${dict[@]} #显示
value
neeo@neeo-labtop:~$ echo ${dict[key]} #还是显示
value neeo@neeo
-labtop:~$ declare -r var='readonly' #定义一个只读变量 neeo@neeo-labtop:~$ var='change' #这货不能更改了 bash: var: 只读变量 neeo@neeo-labtop:~$ unset var #你也别想unset他 bash: unset: var:无法重置:只读的 variable neeo@neeo-labtop:~$

对于已经定义好的变量,可以用readonly命令转变为只读

neeo@neeo-labtop:~$ declare normal=normal
neeo@neeo-labtop:~$ readonly normal
neeo@neeo-labtop:~$ unset normal
bash: unset: normal:无法重置:只读的 variable
neeo@neeo-labtop:~$ normal=change
bash: normal: 只读变量
neeo@neeo-labtop:~$ 

 

typeset的用法和declare类似

unset var删除变量

neeo@neeo-labtop:~$ unset hi #删除变量hi,注意hi前面并没有$符号
neeo@neeo-labtop:~$ echo $hi #查看hi的值,变为空了。

neeo@neeo-labtop:~$ 

 

export var将变量设置为环境变量,像上面那样定义的变量并不是环境变量,姑且叫私有变量。二者的区别是环境变量是可以被子程序访问的,看下面的例子:

neeo@neeo-labtop:~$ hi=hello #定义变量hi
neeo@neeo-labtop:~$ echo $hi #查看变量值
hello
neeo@neeo-labtop:~$ bash #开启子shell
neeo@neeo-labtop:~$ echo $hi #查看变量hi的值,为空,因为hi仅仅是父shell的私有变量,子shell不能访问。

neeo@neeo-labtop:~$ exit #退出子shell
exit
neeo@neeo-labtop:~$ export hi #用export命令将hi变量转变为环境变量
neeo@neeo-labtop:~$ bash #启动另一个子程序
neeo@neeo-labtop:~$ echo $hi #这回可以获取hi的值了。
hello
neeo@neeo-labtop:~$ child='in child' #在子shell中定义变量child
neeo@neeo-labtop:~$ echo $child #查看child的值
in child
neeo@neeo-labtop:~$ export child #将child转变为环境变量。
neeo@neeo-labtop:~$ exit #退出子shell,回到父shell
exit
neeo@neeo-labtop:~$ echo $child #查看child的值,为空,因为在子shell中设定的环境变量,同样不能被父shell访问。

neeo@neeo-labtop:~$ 

那么,请问我在当前shell中设定的环境变量,在另一个shell中(新开的终端哦)能访问么?当然不能!

env 列出当前shell中的所有环境变量

neeo@neeo-labtop:~$ env | less #用less查看env的结果,不然实在是太多了 = =||| :
#------------下面是结果-----------------
ORBIT_SOCKETDIR=/tmp/orbit-neeo
SSH_AGENT_PID=1944
TERM=xterm
SHELL=/bin/bash
XDG_SESSION_COOKIE=d764e95dfe46a11008ed453a50ab62c3-1354339100.454898-280573025
GOBIN=/home/neeo/go/bin/
WINDOWID=58721450
GNOME_KEYRING_CONTROL=/tmp/keyring-fmEhLa
GTK_MODULES=canberra-gtk-module
hi=hello  #看到这个家伙了么?没错,就是刚刚用export导出的环境变量。
USER=neeo
LS_COLORS=rs=0:di=01;34:ln=01;36:hl=44;37:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.o:
#------------此处省略无数字---------------

export不加参数,列出所有被export成环境变量的变量。

neeo@neeo-labtop:~$ export | less #同样,用less查看export的结果。

#---------------下面是结果-------------
declare -x COLORTERM="gnome-terminal"
declare -x DBUS_SESSION_BUS_ADDRESS="unix:abstract=/tmp/dbus-aLW92yDkwV,guid=7bd3671bf9dbe59601cdec5b50b9931c"
declare -x DEFAULTS_PATH="/usr/share/gconf/gnome.default.path"
declare -x DESKTOP_SESSION="gnome"
declare -x DISPLAY=":0.0"
declare -x GDMSESSION="gnome"
declare -x GDM_KEYBOARD_LAYOUT="us"
declare -x GDM_LANG="zh_CN.utf8"
declare -x GNOME_DESKTOP_SESSION_ID="this-is-deprecated"
declare -x GNOME_KEYRING_CONTROL="/tmp/keyring-fmEhLa"
declare -x GNOME_KEYRING_PID="1891"
declare -x GOARCH="386"
declare -x GOBIN="/home/neeo/go/bin/"
declare -x GOOS="linux"
declare -x GOROOT="/home/neeo/go"
declare -x GTK_IM_MODULE="xim"
declare -x GTK_MODULES="canberra-gtk-module"
declare -x HOME="/home/neeo"
declare -x LANG="zh_CN.utf8"
#------------此处又省略了无数字---------------------

等等,茫茫人海,我们之前定义的hi哪里去了呢?这货八成被省略了。。。。

neeo@neeo-labtop:~$ export | grep \ hi #让他无所遁形
declare -x hi="hello" #这货就是我们之前定义的hi了。
neeo@neeo-labtop:~$ 

env和export查看的结果基本没差别,那么,如果想要看到所有变量该怎么办呢?答案是set。

neeo@neeo-labtop:~$ set | less #用less查看set的结果,
#------------------此处省略所有字-----------------------
neeo@neeo-labtop:~$ set | grep ^BASH= #用set查看 BASH变量(BASH是系统自带的一个环境变量)。
BASH=/bin/bash
neeo@neeo-labtop:~$ set | grep ^hi #用set查看刚刚定义的hi变量(这货已经升级为环境变量了)。
hi=hello
neeo@neeo-labtop:~$ newvar=newvar #重新定义一个新的变量。
neeo@neeo-labtop:~$ set | grep ^newvar #set可以查到newvar(还不是环境变量)。
newvar=newvar
neeo@neeo-labtop:~$ env | grep newvar #evn只能列出环境变量,他查不到这个新来的家伙。
neeo@neeo-labtop:~$ export | grep newvar #export也无能为力。
neeo@neeo-labtop:~$ 

另外declare和typeset如果不接参数,和set的结果相同

neeo@neeo-labtop:~$ declare | grep BASH=
BASH=/bin/bash
neeo@neeo-labtop:~$ typeset | grep BASH=
BASH=/bin/bash
neeo@neeo-labtop:~$ 

同样 readonly不接参数可以列出所有readonly变量。

neeo@neeo-labtop:~$ normal=normal
neeo@neeo-labtop:~$ readonly normal
neeo@neeo-labtop:~$ readonly | grep normal
declare -r normal="normal"
neeo@neeo-labtop:~$ 

如果某些变量非常常用,但每次启动shell都要重新定义就变得非常讨厌,解决办法是有的,但要先说说shell启动之前都干了些什么。

/etc/profile ,~/.bash_profile ,~/.bash_login ,~/.profile,~/.bashrc 以上文件,按先后顺序,如果存在就读入,否则跳过。

看到这里应该想到了,如果把变量定义的语句添加到这些文件中的一个,就可以实现每次启动都自动定义变量了(这篇的alias中已经提到了)

例如设置GO语言的环境变量可以在~/.bashrc文件中添加这样的代码

export GOROOT=~/go
export GOARCH=386
export GOOS=linux
export GOBIN=$GOROOT/bin/
export PATH=$PATH:$GOBIN
export PATH=$PATH:$GOROOT/pkg/tool/linux_386/

这篇好乱,更多有关set,export,env的区别请看这里,其实最好的办法是找man!

posted @ 2012-12-01 20:11  Neeo  阅读(1773)  评论(0编辑  收藏  举报