我们知道,linux/unix下shell作为用户与操作系统,或者说shell作为人与计算机之间的接口,详细的了解shell所支持的各项功能,对
用户操作系统是一件有必要的事情。这里我说一些我在使用的过程中发现的一些有意思的shell变量特性。
一、简单变量
1、“ 和 \ 以及 ' 的转义作用
在linux的shell使用过程中,如果一行命令太长我们可以使用 \ 来转义Enter,从而实现续行,这延续了C语言的规范。
Exp1:
[volcanol@volcanol home]$ test=\ > "this is a test" [volcanol@volcanol home]$ echo $test this is a test
可以发现,我们成功的以\ 进行了续行的作用。
Exp2:
[volcanol@volcanol home]$ test=" > "this is another test" > [volcanol@volcanol home]$ echo $test this is a test
可以发现 ” 符号虽然可以讲表示续行输入的> 提示符引出来,但是并没有真正的实现换行,而是将Enter转义了,并且不能正常的执行命令。
Exp3:
[volcanol@volcanol home]$ test=vol's name > i am a linux funs [volcanol@volcanol home]$ echo $test this is a test
[volcanol@volcanol home]$ test='volcanol's name' > this is the third test > [volcanol@volcanol home]$ echo $test
通过这里可以发现 ' 也不能续行,而是将enter转义了,只要存在没有配对的 ',不管 ' 后面是否有字符,均会将Enter转义掉
Exp4:
[volcanol@volcanol home]$ test="this is another test" [volcanol@volcanol home]$ echo $test this is another test
Exp5:
[volcanol@volcanol home]$ test="this is a test" [volcanol@volcanol home]$ echo $test this is a test [volcanol@volcanol home]$ test='volcanol' [volcanol@volcanol home]$ echo $test volcanol [volcanol@volcanol home]$ test='volcanol name' [volcanol@volcanol home]$ echo $test volcanol name
通过这里可以发现,' ' 和 " " 具有相同的效果,如果要给变量赋值字符串字面值需要用这两对符号,否则出错。
Exp6:
test="volcanol" [volcanol@volcanol home]$ test=$test"'s name" [volcanol@volcanol home]$ echo $test volcanol's name
[volcanol@volcanol home]$ unset test [volcanol@volcanol home]$ test='volcanol' [volcanol@volcanol home]$ tetst=$test'"name' [volcanol@volcanol home]$ echo $test volcanol
test='"' [volcanol@volcanol home]$ echo $test "
可以发现“”符号在shell里面保持了C语言中的特性,具有粘滞的特性,而''不具有粘滞的特性;并且"'"表示的是一个字符 ' 构成的字符串,'"'则表示一个 " 表示的字符串。
这里我们发现shell中保留了,或者说沿用了很多C语言的特性。
我们还需要注意一点" 和 ' 之间的差别。
[volcanol@volcanol home]$ name="vb" [volcanol@volcanol home]$ name="$name' book" [volcanol@volcanol home]$ echo $name vb' book [volcanol@volcanol home]$ unset vb [volcanol@volcanol home]$ unset name [volcanol@volcanol home]$ name='vb' [volcanol@volcanol home]$ name='$name book' [volcanol@volcanol home]$ echo $name $name book
可以发现,""可以保持特殊的特性,而'不会保持特殊的特性。
2、变量的”累加“,可以利用 : 符号实现变量的”累加“
这里的变量的累加主要指字符串变量的累加,而不是只数值的累加。这个符号通常用来往一些具有分段意义的变量的累加过程。
[volcanol@volcanol home]$ test=$PATH [volcanol@volcanol home]$ test=$test:/home/volcanol [volcanol@volcanol home]$ echo $test /usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/volcanol/bin:/home/volcanol
这里我们发现test变量通过:符号成功的将/home/volcano目录链接到$test变量中了。下面我们来看一个关于:的其他特性。
[volcanol@volcanol home]$ test=1 [volcanol@volcanol home]$ test=$test:2 [volcanol@volcanol home]$ echo $test 1:2
这里原本是想试一下用一个整数赋值给变量,然后看用:是否会报错,: 还是将各个值连接起来了。这里有一个特性,如果要进行算术运算,则必须
申明/定义具有数值类型的特性的变量,可以通过declare命令实现,这里暂时不介绍。
3、不利用利用""符号实现cat(str1,str2)功能
Exp:
[volcanol@volcanol home]$ unset test [volcanol@volcanol home]$ test="/" [volcanol@volcanol home]$ test="$test"home [volcanol@volcanol home]$ echo $test /home [volcanol@volcanol home]$ test=${test}/volcanol [volcanol@volcanol home]$ echo $test /home/volcanol
可以发现,如果不用"str1""str2"同样可以实现两个字符串的cat功能。
4、export一个变量
通过export变量可以使一个变量成为环境变量
Exp:
[volcanol@volcanol home]$ test='name' [volcanol@volcanol home]$ bash [volcanol@volcanol home]$ echo $test [volcanol@volcanol home]$ exit exit [volcanol@volcanol home]$ echo $test name
可以发现如果没有用export命令将test变成环境变量则在子进程bash中test是不可见的,即不能使用的。
[volcanol@volcanol home]$ export test [volcanol@volcanol home]$ bash [volcanol@volcanol home]$ echo $test name [volcanol@volcanol home]$ exit exit [volcanol@volcanol home]$ echo $test name
可以发现通过export命令,test可以在子进程的bash中使用,具有环境变量的效果。这样后如果需要取消这个变量的,可以使用unset命令取消即可。
5、命令中命令
在linux的shell中,可以在命令中执行命令。就是说可以在命令1中执行命令2,并且可以讲命令2的输出作为命令1的输入使用。
Exp:
[volcanol@volcanol home]$ ls /`ls /` ls: boot: No such file or directory ls: dev: No such file or directory ls: etc: No such file or directory ls: home: No such file or directory ls: lib: No such file or directory ls: lost+found: No such file or directory ls: media: No such file or directory ls: misc: No such file or directory ls: mnt: No such file or directory ls: net: No such file or directory ls: opt: No such file or directory ls: perl: No such file or directory ls: proc: No such file or directory ls: root: No such file or directory ls: sbin: No such file or directory ls: selinux: No such file or directory ls: srv: No such file or directory ls: sys: No such file or directory ls: tmp: No such file or directory ls: usr: No such file or directory ls: var: No such file or directory /bin: arch chown df ed gettext ipcalc login mount ping6 rvi sort tracepath unicode_start zcat awk cp dmesg egrep grep kbd_mode ls mv ps rview stty tracepath6 unicode_stop zsh basename cpio dnsdomainname env gtar kill mail netstat pwd sed su traceroute unlink bash csh doexec ex gunzip ksh mkdir nice red setfont sync traceroute6 usleep cat cut domainname false gzip link mknod nisdomainname rm setserial tar true vi chgrp date dumpkeys fgrep hostname ln mktemp pgawk rmdir sh tcsh umount view chmod dd echo gawk igawk loadkeys more ping rpm sleep touch uname ypdomainname
而我们执行ls / 命令得到的结果是:
[volcanol@volcanol home]$ ls / bin boot dev etc home lib lost+found media misc mnt net opt perl proc root sbin selinux srv sys tmp usr var [volcanol@volcanol home]$
利用 `` 对将在命令1中的命令2先执行,并且将命令2的执行结果作为命令1的输入,从而进一步执行整个命令。
6、直接引用变量
当中shell中直接引用变量,bash会将变量所存储的内容看出一个可执行程序来执行
[volcanol@volcanol ~]$ mypath="vb" [volcanol@volcanol ~]$ $mypath bash: vb: command not found [volcanol@volcanol ~]$
二、变量作用
1、变量可以作为命令的参数
2、变量可以简化shell的应用和编程,最主要的功能
Exp:
[volcanol@volcanol home]$ mypath="$HOME" [volcanol@volcanol home]$ 传 [volcanol@volcanol home]$ cd $mypath [volcanol@volcanol ~]$ pwd /home/volcanol
上面的实例为变量作为命令的参数。
unset mypath [volcanol@volcanol ~]$ mypath="/bin/ls" [volcanol@volcanol ~]$ $mypath java mysql samba [volcanol@volcanol ~]$
上例中,我将mypath设置为ls命令所在的绝对路径,我们可以发现利用$mypath可以正常的执行命令,因此通过这样的手动可以简化shell编程
三、环境变量
1、env环境变量
通过env命令可以查看主机中所有的环境变量。
[volcanol@volcanol ~]$ env HOSTNAME=volcanol SHELL=/bin/bash TERM=vt100 HISTSIZE=1000 SSH_CLIENT=::ffff:192.168.0.106 17854 22 SSH_TTY=/dev/pts/0 USER=volcanol LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35: PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/volcanol/bin MAIL=/var/spool/mail/volcanol PWD=/home/volcanol INPUTRC=/etc/inputrc LANG=en_US.UTF-8 HOME=/home/volcanol SHLVL=2 LOGNAME=volcanol SSH_CONNECTION=::ffff:192.168.0.106 17854 ::ffff:192.168.0.103 22 LESSOPEN=|/usr/bin/lesspipe.sh %s G_BROKEN_FILENAMES=1 _=/bin/env
可以发现这里env显示的也是当前用户的环境变量。
2、set命令
利用set命令可以查看在shell环境下有效的变量,如果在子程序中,这里变量的值可能不一样。
[volcanol@volcanol ~]$ set BASH=/bin/bash BASH_ARGC=() BASH_ARGV=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="3" [1]="00" [2]="16" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") BASH_VERSION='3.00.16(1)-release' COLORS=/etc/DIR_COLORS COLUMNS=168 DIRSTACK=() EUID=500 GROUPS=() G_BROKEN_FILENAMES=1 HISTFILE=/home/volcanol/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOME=/home/volcanol HOSTNAME=volcanol HOSTTYPE=i386 IFS=$' \t\n' INPUTRC=/etc/inputrc LANG=en_US.UTF-8 LESSOPEN='|/usr/bin/lesspipe.sh %s' LINES=47 LOGNAME=volcanol LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:' MACHTYPE=i386-redhat-linux-gnu MAIL=/var/spool/mail/volcanol MAILCHECK=60 OLDPWD=/home OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/volcanol/bin PIPESTATUS=([0]="127") PPID=2911 PS1='[\u@\h \W]\$ ' PS2='> ' PS4='+ ' PWD=/home/volcanol SHELL=/bin/bash SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHLVL=2 SSH_CLIENT='::ffff:192.168.0.106 17854 22' SSH_CONNECTION='::ffff:192.168.0.106 17854 ::ffff:192.168.0.103 22' SSH_TTY=/dev/pts/0 SUPPORTED=en_US.UTF-8:en_US:en TERM=vt100 UID=500 USER=volcanol _=himBH mypath=vb name='$name book'
上图为set命令查看到的变量 ,为当前用户的shell中的有效变量。
[volcanol@volcanol ~]$ bash [volcanol@volcanol ~]$ set BASH=/bin/bash BASH_ARGC=() BASH_ARGV=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="3" [1]="00" [2]="16" [3]="1" [4]="release" [5]="i386-redhat-linux-gnu") BASH_VERSION='3.00.16(1)-release' COLORS=/etc/DIR_COLORS COLUMNS=168 DIRSTACK=() EUID=500 GROUPS=() G_BROKEN_FILENAMES=1 HISTFILE=/home/volcanol/.bash_history HISTFILESIZE=1000 HISTSIZE=1000 HOME=/home/volcanol HOSTNAME=volcanol HOSTTYPE=i386 IFS=$' \t\n' INPUTRC=/etc/inputrc LANG=en_US.UTF-8 LESSOPEN='|/usr/bin/lesspipe.sh %s' LINES=47 LOGNAME=volcanol LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35:' MACHTYPE=i386-redhat-linux-gnu MAIL=/var/spool/mail/volcanol MAILCHECK=60 OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/volcanol/bin PIPESTATUS=([0]="0") PPID=4037 PS1='[\u@\h \W]\$ ' PS2='> ' PS4='+ ' PWD=/home/volcanol SHELL=/bin/bash SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHLVL=3 SSH_CLIENT='::ffff:192.168.0.106 17854 22' SSH_CONNECTION='::ffff:192.168.0.106 17854 ::ffff:192.168.0.103 22' SSH_TTY=/dev/pts/0 SUPPORTED=en_US.UTF-8:en_US:en TERM=vt100 UID=500 USER=volcanol _=/etc/bashrc [volcanol@volcanol ~]$
上图为当前登录用户在开启另外一个shell后的shell中的有效变量。
可以发现不是环境变量的值不能继承到子进程中。
Tip :
在这里有一个约定俗成的惯例,那就是大写字母的变量通常用作系统的环境变量(退出当前会话,开始新的会话,这些变量仍有效),而其他变量则是用户的变量,
除非通过export命令,否则一般为会话变量(当前会话有效的变量)。
3、PS1环境变量
这个变量决定console的提示符的样式,例如我们查看一下这个变量的内容:
[volcanol@volcanol ~]$ echo $PS1 [\u@\h \W]\$
可以发现$PS1是: [\u@\h \W]\$
这里 \u 表达当前登录用户名,
[ ] @ $ 字符,原样显示的字符
\h 表示的网站主机名的第一个字段,
\W表示当前的工作路径的最后一个目录,
我们可以试一下修改这个环境变量的值看看:
[volcanol@volcanol ~ 20:45 #6]$ PS1='\[\ulogin\H \w\]\$ ' volcanolloginvolcanol ~$ PS1='[\u login \H \t \w]\>' [volcanol login volcanol 20:49:13 ~]\>PS1='[\u login \H and now \t \w]\>' [volcanol login volcanol and now 20:49:33 ~]\>
可以发现我们成功的修改了这个变量的值,但是这个修改仅在当前会话中有效,退出后即不能有效。为了使这个修改一直有效必须修改bash的profile配置
文件;如果要对整个系统有效则需要修改/etc/bashrc profile 文件,而对于当前用户则需要修改~/.bashrc文件;有些地方说要修改~/.bash_profile文件,其实
两者存在一个调用关系。我们可以看~/.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 unset USERNAME
4、export命令
我们可以通过整个变量来改变设置环境变量,通过export var_name可以使var_name在同一次的login会话中的不同console会话中有效, 但是logout后将不再有效。
如果要使这个设置有效必须修改用户或者系统的profile配置文件。这里就不多说了。
可以使用export查看当前用户的环境变量。注意这个命令查看的与set的差别。
[volcanol@volcanol ~]$ export declare -x G_BROKEN_FILENAMES="1" declare -x HISTSIZE="1000" declare -x HOME="/home/volcanol" declare -x HOSTNAME="volcanol" declare -x INPUTRC="/etc/inputrc" declare -x LANG="en_US.UTF-8" declare -x LESSOPEN="|/usr/bin/lesspipe.sh %s" declare -x LOGNAME="volcanol" declare -x LS_COLORS="no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:" declare -x MAIL="/var/spool/mail/volcanol" declare -x OLDPWD declare -x PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/home/volcanol/bin" declare -x PWD="/home/volcanol" declare -x SHELL="/bin/bash" declare -x SHLVL="1" declare -x SSH_CLIENT="::ffff:192.168.0.106 20999 22" declare -x SSH_CONNECTION="::ffff:192.168.0.106 20999 ::ffff:192.168.0.103 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm" declare -x USER="volcanol"
5、语系环境变量
可以通过locale命令查看语系环境变量。
[volcanol@volcanol ~]$ locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF-8" LC_NUMERIC="en_US.UTF-8" LC_TIME="en_US.UTF-8" LC_COLLATE="en_US.UTF-8" LC_MONETARY="en_US.UTF-8" LC_MESSAGES="en_US.UTF-8" LC_PAPER="en_US.UTF-8" LC_NAME="en_US.UTF-8" LC_ADDRESS="en_US.UTF-8" LC_TELEPHONE="en_US.UTF-8" LC_MEASUREMENT="en_US.UTF-8" LC_IDENTIFICATION="en_US.UTF-8" LC_ALL=
这些变量的意思可以查看相关的手册。 值得一提的是语系的环境配置文件为/etc/sysconfig/i18n 文件,我们可以查看一下这个文件的内容。
[volcanol@volcanol ~]$ cat /etc/sysconfig/i18n LANG="en_US.UTF-8" SYSFONT="latarcyrheb-sun16" SUPPORTED="en_US.UTF-8:en_US:en" [volcanol@volcanol ~]$
可以看到我目前主机的字符编码是en_US.UTF-8编码格式,注意这里设置变量的格式。
待续.......