kooyee ‘s blog

开源软件, 众人努力的结晶, 全人类的共同财富
posts - 103, comments - 55, trackbacks - 0, articles - 66
   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

shell基础学习系列(2):学习shell变量

Posted on 2008-01-25 18:39 kooyee 阅读(508) 评论(0)  编辑  收藏 所属分类: Lniux/Unix
1、登陆过程:

第一步:键入用户名和密码
第二步:系统通过查询/etc/passwd来检测是否为有效用户
第三步:如果登陆正确并且密码有效,则系统执行环境设置文件/etc/profile-->.bash_profile。

一般情况下,root的权限太高,为了防止误操作造成系统崩溃,我现在的做法是以一个普通用户的身份登陆,重新定制环境,需要root权限时以su指令切换过去执行。这样比较安全。对于shell变量的定制,有新的理解。变量的作用很多,可以定制用户本身的工作环境,可以保存有用的信息,也可以暂时保存信息。所以出现了下面变量:

1)本地变量。只是在当前shell生命期的脚本中使用,一旦shell中启动另一个进程或者退出,则失效。好处就是不会对其他的shell或者进程产生影响。

2)环境变量。在建立嵌入式交叉编译环境的工具链时设置过环境变量,在这里算是对环境变量的位置特点比较清晰了。环境变量用于所有用户进程,登录进程称为父进程,shell中执行的用户进程称为子进程。按照传统方法,所有环境变量均为大写,这点与本地变量不同。而且,环境变量在应用于用户进程前,必须用export命令导出,而本地变量不需要。环境变量的两种定制方法前面已经掌握了,在命令行中定制用户注销时就会丢失,所以最好还是在.bash_profile中定制。

3)位置变量。这种为特殊变量,因为它们是只读的。它的作用是向一个shell脚本传递参数,用位置参数的方式完成此功能。参数数目可以任意多,但是只有前9个可以被访问,不过使用shift命令可以改变这个限制。参数从第一个开始,在第9个结束;每个访问参数前都要加$符号。其中第一个参数为0,表示预留保存实际脚本名称,无论脚本是否有参数,此值均可用。以前为openvpn的启动看过一个脚本,实质上就是使用了位置变量。现在才理解,也能够编写此类脚本了。

4)特定参数变量。为特殊变量,只读。共有7个特定变量,在编程时用的比较多。

$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数,与位置变量不同,此选项参数可以超过9个。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的进程ID号
$@ 与$#相同,但是使用时加引号,并在引号中返回每个参数
$- 显示shell使用的当前选项,与set命令功能相同
$? 显示最后命令的退出状态,0表示没有错误,其他表明错误。

2、密码文件/etc/passwd的格式:7个域

登陆名:加密的密码:uid:gid:用户全名:用户home目录:用户的shell路径
以前总结过忘记root密码的处理方法,当时只是依葫芦画瓢,现在才明白原理。只要将加密的密码域去除,密码自然也就没有了。即“::”
 
-------------------------------------
实例设置1
注:使用RedHat 9.0默认的bash shell
 
嵌入式shell变量中有一些预留的环境变量,比如HOME,PATH等。现在要利用PS1,PS2来定制自己的命令提示符。
 
PS1:基本提示符包含shell提示符,缺省是对超级用户为#,其他为$。
在默认情况下,我的命令提示符如下:
[armlinux@lqm armlinux]$ echo $PS1
[\u@\h \W]\$
其中\u代表用户名,\h代表主机名,\W代表当前的文件夹。
现在我希望我的命令提示符由如下几个部分组成,首先要显示用户名,然后要显示绝对路径,方便使用。那么就可以用如下的命令定制:
[armlinux@lqm armlinux]$PS1="\u: \`pwd\`>"
armlinux: /home/armlinux>
如果想设置系统主机名做提示符,则只需令PS1="`hostname`>"即可。
要想始终起作用,当然是修改.bash_profile文件,前面刚刚学了。
 
PS2:为附属提示符,缺省符号为>。当执行多行命令时,出现的符号。这个一般我习惯用默认的。
举例:
armlinux: /home/armlinux>cat >>test<<EOF
> test
> test
> test
> EOF
armlinux: /home/armlinux>cat test
test
test
test
如果设置成"@:",则显示如下:
armlinux: /home/armlinux>PS2="@:"
armlinux: /home/armlinux>cat >>test<<EOF
@:test
@:test
@:test
@:EOF
armlinux: /home/armlinux>cat test
test
test
test
-------------------------------------

实例设置2

注:使用RedHat 9.0默认的bash shell

 

1 使用命令echo显示环境变量

 

#本例使用echo显示常见的变量HOME

$ echo $HOME  

/home/lqm

 

2 设置一个新的环境变量

 

variable-name=value;export variable-name

或者

export variable-name=value

 

$ export HELLO=”Hello!”

$ echo $HELLO

Hello!

 

3 使用env命令显示所有的环境变量

 

$ env

SSH_AGENT_PID=1875

HOSTNAME=lqm

SHELL=/bin/bash

TERM=xterm

HISTSIZE=1000

……

 

4  使用set命令显示所有本地定义的Shell变量

 

$ set

BASH=/bin/bash

……

 

5  使用unset命令来清除环境变量

 

$ export TEST=”test”      #增加一个环境变量TEST

$ env | grep TEST           #此命令有输出,证明环境变量TEST已经存在了

TEST=test

$ unset $TEST                #删除环境变量TEST

$ env | grep TEST           #此命令无输出,证明环境变量TEST已经存在了

 

6  使用readonly命令设置只读变量

如果使用了readonly命令的话,变量就不可以被修改或清除了。示例如下:

 

$ export TEST="Test..."                                        #增加一个环境变量TEST

$ readonly TEST                                                   #将环境变量TEST设为只读

$ unset TEST                                                        #会发现此变量不能被删除

-bash: unset: TEST: cannot unset: readonly variable
$ TEST="New"                                                     #
会发现此变量不能被修改

-bash: TEST: readonly variable

 

C程序来访问和设置环境变量

对于C程序的用户来说,可以使用下列三个函数来设置或访问一个环境变量。

getenv()访问一个环境变量。输入参数是需要访问的变量名字,返回值是一个字符串。如果所访问的环境变量不存在,则会返回NULL

setenv()在程序里面设置某个环境变量的函数。

unsetenv()清除某个特定的环境变量的函数。

另外,还有一个指针变量environ,它指向的是包含所有的环境变量的一个列表。下面的程序可以打印出当前运行环境里面的所有环境变量:

 

#include <stdio.h>

extern char**environ;

int main ()

{

char**var;

for (var =environ;*var !=NULL;++var)

printf ("%s \n ",*var);

return 0;

}

 

8      通过修改环境变量定义文件来修改环境变量。

需要注意的是,一般情况下,这仅仅对于普通用户适用,避免修改根用户的环境定义文件,因为那样可能会造成潜在的危险。

 

$cd                                     #到用户根目录下

$ls -a                                  #查看所有文件,包含隐藏的文件

$vi .bash_profile                 #修改环境变量定义文件

 

红色部分也可以用一条语句代替:$vi ~/.bash_profile。在这里,~实际上是shell变量的扩展。它包含着内建命令cd。可以这样理解,~就是你当前登录shell的根目录的绝对路径。假设你的当前用户是armlinux,那么你执行ls ~,将会显示/home/armlinux文件夹下的内容。同样的,$vi ~/.bash_profile展开后,实际上是$vi /home/armlinux/.bash_profile。所以,很容易理解为什么与红色部分等价了。

 

然后编辑你的PATH声明,其格式为:

PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>

你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效,如果想立刻生效,则可执行下面的语句:$source .bash_profile。如果在命令行中定制环境变量,那么你所设置的环境变量的生命期就是你当前shell用户的登录时间。一旦退出,那么环境变量也就失效了。所以,如果想只要登录改用户,就要使环境变量生效,还是在.bash_profile中修改。至于原因,这就与shell的激活模式相关了,可了解相关内容。

 

需要注意的是,最好不要把当前路径”./”放到PATH里,这样可能会受到意想不到的攻击。完成后,可以通过$ echo $PATH查看当前的搜索路径。这样定制后,就可以避免频繁的启动位于shell搜索的路径之外的程序了。


只有注册用户登录后才能发表评论。


网站导航: