原来刘项不读书:怎样用脚本来设置环境变量

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 22:34:51

怎样用脚本来设置环境变量  

2009-02-22 19:15:30|  分类: 关于 linux |  标签: |字号大中小 订阅

[shell][linux]怎样用脚本来设置环境变量(要用source命令export为什么不行)

我也一直不明白,以下两篇文章就能说明问题.
--------------------------------------------------
标题: 怎样用脚本来设置环境变量
我想编一个脚本程序,用来对一组环境变量进行设置或取消
但由于脚本程序对变量的设置在退出脚本后就消失了,有没有间接办法能够实现这个功能? 
你说的是 export ?
在脚本中使用export, 好像只在脚本中有效,退出这个脚本,设置的变量就没有了
在你的脚本中做设置
在~/.profile 或 ~/.bashrc 等 用source运行    
我试了一下,
用source可以运行普通的shell脚本,也可达到设置环境变量的目的,
想问一下source是什么命令?用man和info没有查到说明  
source 是 bash 的内嵌命令,
man bash
/source filename \[arguments\]
Thank u
source filename
or
代码:
. filename
source 是 bash 的内嵌命令,
man bash
/source filename \[arguments\]
source好像不一定是bash的‘内嵌命令’
忘了是哪个发行版了
source是外部命令
$ type source
source is a shell builtin
哪个BT的发行版把 source 外部化了?忽忽。。
--------------------------------------------------
我自己也是一个菜鸟,接触linux没有多久,最近在学习BASH的export命令时碰到了一个难道(书上说export是将自定义变量变成系统环境变量):我在一个脚本文件中定义一个了变量,然后export变量,按照我自己的想法,执行完这个脚本后,在提示符下一定可以用echo显示出它的值,可结果却不是这样,脚本执行完后用set根本看不到有这个变量存在。为什么呢?我百思不得其解,最后将问题贴出来,一位前辈告诉我说用source+脚本文件就可以了,我试了一下果然可以,但一个新的问题又出来了。我将脚本中export命令删除后,用source一样可以。那这个export好像没有什么用呀。
在经过多次尝试后发现了一些东西,是我自己猜的,如果有什么不对的地方,请指正,谢谢。
执行一个脚本时,会先开启一个子shell环境(不知道执行其它程序是不是这样),然后将父shell中的所有系统环境变量复制过来,这个脚本中的语句就在子shell中执行。(也就是说父shell的环境变量在子shell中可以调用,但反过来就不行,如果在子shell中定义了环境变量,只对该shell或者它的子shell有效,当该子shell结束时,也可以理解为脚本执行完时,变量消失。)为了证明这一点,请看脚本内容:
test='value'
export test
这样的脚本执行完后,test实际上是不存在的。接着看下面的:
test='value'
export test
bash
这里在脚本最后一行再开一个子shell,该shell应该是脚本文件所在shell的子shell,这个脚本执行完后,是可以看到test这个变量的,因为现在是处于它的子shell中,当用exit退出子shell后,test变量消失。
如果用source对脚本进行执行时,如果不加export,就不会在子shell中看到这个变量,因为它还不是一个系统环境变量呀,如脚本内容是:
test='value'
用source执行后,在shell下是能看到这个变量,但再执行bash开一个子shell时,test是不会被复制到子shell中的,因为执行脚本文件其实也是在一个子shell中运行,所以我再建另一个脚本文件执行时,是不会输入任何东西的,内容如:echo$test。所以这点特别注意了,明明在提示符下可以用echo $test输出变量值,为什么把它放进脚本文件就不行了呢?
所以得出的结论是:1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;2、一个shell中的系统环境变量才会被复制到子shell中(用export定义的变量);3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失(并不能返回到父shell中)。3、不用export定义的变量只对该shell有效,对子shell也是无效的。
后来根据版主的提示,整理了一下贴子:为什么一个脚本直接执行和用source执行不一行呢?这也是我自己碰到的一个问题。manual原文是这样的:Read and executecommands from filename in the current shell environment and return theexit status of the last command executed fromfilename.明白了为什么不一样了吧?直接执行一个脚本文件是在一个子shell中运行的,而source则是在当前shell环境中运行的。根据前面的内容,你也已经明白其中的道理了吧。
困扰了我几天的问题终于可以圆满的解决了。
--------------------------------------------------

不过还有一个问题,听说子shell的环境变量与父shell的也不完全一样,究竟差别是什么?

source命令:
source命令也称为“点命令”,也就是一个点符号(.)。source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
用法:
source filename 或 . filename
source命令除了上述的用途之外,还有一个另外一个用途。在对编译系统核心时常常需要输入一长串的命令,如:
make mrproper
make menuconfig
make dep
make clean
make bzImage
…………

如果把这些命令做成一个文件,让它自动顺序执行,对于需要多次反复编译系统核心的用户来说会很方便,而用source命令就可以做到这一点,它的作用就是把一个文件的内容当成shell来执行,先在linux的源代码目录下(如/usr/src/linux-2.4.20)建立一个文件,如make_command,在其中输入一下内容:

make mrproper &&
make menuconfig &&
make dep &&
make clean &&
make bzImage &&
make modules &&
make modules_install &&
cp arch/i386/boot/bzImage /boot/vmlinuz_new &&
cp System.map /boot &&
vi /etc/lilo.conf &&
lilo -v
文件建立好之后,每次编译核心的时候,只需要在/usr/src/linux-2.4.20下输入:
source make_command
即可,如果你用的不是lilo来引导系统,可以把最后两行去掉,配置自己的引导程序来引导内核。
顺便补充一点,&&命令表示顺序执行由它连接的命令,但是只有它之前的命令成功执行完成了之后才可以继续执行它后面的命令。

==============================================================

1、引言

   在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现“command notfound”的提示内容。如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁琐了。这涉及到环境变量PATH的设置问题,而PATH的设置也是在linux下定制环境变量的一个组成部分。本文基于RedHat 9.0,详细讲解了环境变量定制的问题。

2、变量简介

Linux是一个多用户的操作系统。每个用户登录系统后,都会有一个专用的运行环境。通常每个用户默认的环境都是相同的,这个默认环境实际上就是一组环境变量的定义。用户可以对自己的运行环境进行定制,其方法就是修改相应的系统环境变量。

3、定制环境变量

   环境变量是和Shell紧密相关的,用户登录系统后就启动了一个Shell。对于Linux来说一般是bash,但也可以重新设定或切换到其它的Shell。根据发行版本的情况,bash有两个基本的系统级配置文件:/etc/bashrc和/etc/profile。这些配置文件包含两组不同的变量:shell变量和环境变量。前者只是在特定的shell中固定(如bash),后者在不同shell中固定。很明显,shell变量是局部的,而环境变量是全局的。环境变量是通过Shell命令来设置的,设置好的环境变量又可以被所有当前用户所运行的程序所使用。对于bash这个Shell程序来说,可以通过变量名来访问相应的环境变量,通过export来设置环境变量。下面通过几个实例来说明。

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


 

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

$ echo $HOME  

/home/lqm


 

3.2 设置一个新的环境变量


 

$ export HELLO=”Hello!”

$ echo $HELLO

Hello!


 

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


 

$ env

SSH_AGENT_PID=1875

HOSTNAME=lqm

SHELL=/bin/bash

TERM=xterm

HISTSIZE=1000

……


 

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


 

$ set

BASH=/bin/bash

……


 

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


 

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

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

TEST=test

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

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


 

3.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


 

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

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

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

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

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

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


 

#include

extern char**environ;

int main ()

{

char**var;

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

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

return 0;

}


 

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

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


 

$cd                                     #到用户根目录下

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

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


 

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

PATH=$PATH::::------:

你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效,如果想立刻生效,则可执行下面的语句:$source .bash_profile

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

4  总结

    通过以上的设置,你可以有一个比较方便有效的环境来提高你的