shell中的点命令与source命令的区别

1 shell脚本执行方法

有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不再启用其他shell。

新产生一个shell然后再执行scripts的方法是在scripts文件开头加入语句:#!/bin/sh。一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。source: source命令即点(.)命令。在 bash下输入man source,找到source命令解释处,可以看到解释"Read and execute commands from filename in the current shell environment and ..."。从中可以知道,source命令是在当前进程中执行参数文件中的各个命令,而不是另起子进程(或sub-shell)。

2 source与点命令

  • source 命令是 bash shell 的内置命令,从 C Shell 而来。
  • source 命令的另一种写法是点符号,用法和 source 相同,从Bourne Shell而来。
  • source 命令可以强行让一个脚本去立即影响当前的环境。
  • source 命令会强制执行脚本中的全部命令,而忽略文件的权限。
  • source 命令通常用于重新执行刚修改的初始化文件,如 .bash_profile 和 .profile 等等。
  • source 命令可以影响执行脚本的父shell的环境,而 export 则只能影响其子shell的环境。

使用方法举例:

$source ~/.bashrc 或者:$. ~/.bashrc

执行后 ~/.bashrc 中的内容立即生效。

source命令(从 C Shell 而来)是bash shell的内置命令。点命令,就是个点符号,(从Bourne Shell而来)是source的另一名称。同样的,当前脚本中设置的变量也将作为脚本的环境,source(或点)命令通常用于重新执行刚修改的初始化文件,如 .bash_profile 和 .profile 等等。例如,如果在登录后对 .bash_profile 中的 EDITER 和 TERM 变量做了修改,则能用source命令重新执行 .bash_profile 中的命令而不用注销并重新登录。

source命令的作用就是用来执行一个脚本,那么:source a.sh 同直接执行 ./a.sh 有什么不同呢,比如你在一个脚本里export $KKK=111 ,如果你用./a.sh执行该脚本,执行完毕后,你运行 echo $KKK ,发现没有值,如果你用source来执行,然后再echo ,就会发现KKK=111。因为调用./a.sh来执行shell是在一个子shell里运行的,所以执行后,结果并没有反应到父shell里,不过source不同,他就是在本shell中执行的,所以能看到结果。

source命令是shell的一个内部命令,它从指定的shell 文件中读入所有命令语句并在当前进程中执行。 因此当多个shell进程(父子进程或无关进程均可)共享一组变量值时,就可以将这些变量赋值语句定义到一个shell文件里,并在需要这些变量值的程序中使用点语句来引用这个shell文件,从而实现变量值共享(对这些变量值的修改仅涉及到这个shell文件)。但要注意的是,这个shell文件不能包括含有位置参数的语句,即不能接受$1、$2等命令行参数。

从上面可以看出,其实点命令相当于c语言里面的#include。下面我们将举例来说明。

我们先写一个简单的shell脚本文件,暂且命名为file1吧:

?


1

2

3

#! /bin/bash

a="hi"

echo
$a

我们先来执行一下这个shell脚本,打开终端,敲入: ./file1

结果是什么,你应该也看到了吧:

?


1

bash: ./file1: Permission denied

为什么呢。我们先不管这个吧,先看一下,另一个结果:

. ./file1(注意啊,两个点之间有个空格的哦,要不就成了上一级目录了,如果你不嫌麻烦的话,也可以写source ./file1)这个的结果呢,跟前面就不一样了,正如我们所愿的,输出了hi。

./file1,直接执行,需要另起shell进程,而你似乎还没有这个权限(这个改一下就OK了,后面再说),而用点命令就不一样了(注意啊,./file这里的点是当前目录的意思),点命令会在当前的shell下执行。补充说一下怎么改一下file1的权限,让我们可以在按shell脚本来执行:

?


1

chmod
+x file1

再执行一下./file1,是不是OK了?

再来看另一个例子吧。首先脚本文件file1

?


1

2

#! /bin/bash

a="hi"

脚本文件file2(与file1在同一个目录下)

?


1

2

3

#! /bin/bash

./file1

echo
$a

记得改一下file1的权限啊,要不./file1就没法执行了。执行一下看看结果。什么都没有,是吧。我们再改一下file2,这回用一下咱们的点命令

?


1

2

3

#! /bin/bash

. ./file1

echo
$a

怎么样结果不一样了吧。这个例子应该还是能说明点问题的吧。如果不用点命令的话,会另起shell进程,而启动这个进行的时候,它会建立自己的进程环境(暂且这么叫它吧),然后在这个进行结束的时候,它所建立的环境也随之被销毁。而且点命令就不一样了,它会把点命令所带的shell脚本里的所以内容带到当前的shell进程里,在本程序里,就是变量a了。

同样,可以解释下面这个问题:

为什么在shell脚本里面用export设置环境变量之后,当shell执行完了,用set命令看不到呢?但是你如果直接在终端里export 环境变量用set是看到的。

一个shell脚本test.sh的内容为:

?


1

2

#!/bin/bash

export
AA=123

当我们执行test.sh的时候,是当前终端所在的shell fork一个子shell然后执行test.sh的,执行完了再返回终端所在的shell。明白这点,就容易理解了,我们在test.sh设置了AA环境变量,它只在fork出来的这个子shell中生效,子shell只能继承父shell的环境变量,而不能修改父shell的环境变量,所以test.sh结束后,父进程的环境就覆盖回去。所以在test.sh之后完之后,我们用set命令是看不了AA这个环境变量的值的。

那有什么办法可以让脚本的环境变量在脚本执行之后仍然对当前终端存在呢?用sorcue 或者.(dot) 。明确告诉shell不要fork执行脚本,而是在当前的shell执行,这样环境变量就可以保存下来了。

source命令与shell scripts的区别是:

source在当前bash环境下执行命令,而scripts是启动一个子shell来执行命令。这样如果把设置环境变量(或alias等等)的命令写进scripts中,就只会影响子shell,无法改变当前的BASH,所以通过文件(命令列)设置环境变量时,要用source 命令。

转自:http://blog.chinaunix.net/uid-22028566-id-3182362.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 09:18:32

shell中的点命令与source命令的区别的相关文章

[Z] shell中的点命令与source命令

1 shell脚本执行方法 有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts:一种是在当前shell下执行,不再启用其他shell. 新产生一个shell然后再执行scripts的方法是在scripts文件开头加入语句:#!/bin/sh.一般的script文件(.sh)即是这种用法.这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令. 另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前s

shell 中 grep、sed、awk 命令

grep 命令 grep命令基本语法 grep命令是打印匹配文本行,其全称为 Global Search Regular Expression and Print out the line:基本语法如下: grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] 其中,OPTIONS表示选项:PATTERN表示匹配模式,匹配模式可以是字符串.变量.正则表达式,若匹配模式中含义空格,则需要使用双

linux shell中的单引号与双引号的区别(看完就不会有引号的疑问了)(转)

" "(双引号)与 ' '(单引号)的区别  你在shell prompt后面敲打键盘.直到按下enter的时候,你输入的文字就是command line了,然后shell才会以进程方式执行你所提交的命令.但是,你又可知道:你在command line输入的每一个文字,对shell来说,有什么类别之分呢? 简单而言,command line的每一个charactor分为如下两种:   *literal:也就是普通纯文字,对shell来说没有特殊功能.   *meta:对shell来说,

shell中的单引号和双引号的区别

对于常规的字符串定义变量值应添加双引号,并且等号后不能 有空格,需要强引用的,则需要单引号,需要命令引用的使用反引号. 单引号:所见即所得,即输出时会将单引号内的所有内容都原样输出,或者描述为单引号里面看到的什么就输出什么,这成为强引用. 双引号:输出双引号的所有内容:如果内容中有命令(要反引).变量.特殊转义,会先把变量.命令.转义字符解析出结果,然后在输出最终内容,这称为弱引. 反引号:一般用于命令,执行的时候命令会被执行,相当于$(),赋值和输出都要用反引号引起来. [[email pro

Shell中4个关键的网络命令

ifconfig 这个命令与Windows的"ipconfig"作用一致,用于显示网络接口,子网掩码等详细信息. ifconfig 左边一列是网络接口名,占据10个字节,右边的若干列显示对应的网络接口的详细信息. 在每个系统中,默认都有一个称之为环回接口的lo,这个接口指向当前主机本身. 下面这张截图是在博主的电脑上运行这个命令之后显示的信息: 相关技巧: 1.打印网络接口列表 说明:ifconfig 输出的第一列的前十个字节显示的网络接口名,因此我们用 cut 命令提取每一行的前10

shell中exec命令

1.find中的-exec参数 在当前目录下(包含子目录),查找所有txt文件并找出含有字符串"bin"的行 find ./ -name "*.txt" -exec grep "bin" {} \; 在当前目录下(包含子目录),删除所有txt文件 find ./ -name "*.txt" -exec rm {} \; Execute  command;  true  if 0 status is returned.  All

linux shell 结构 与source 命令

Linux Shell&环境变量 登录到系统后,系统将启动一个用户shell.在这个shell中,可以使用shell命令或声明变量,也可以创建并运行shell脚本程序.运行 shell脚本程序时,系统将创建一个子shell.此时,系统中将有两个shell,一个是登录时系统启动的shell,另一个是系统为运行脚本程序创 建的shell.当一个脚本程序运行完毕,它的脚本shell将终止,可以返回到执行该脚本之前的shell.从这种意义上来说,用户可以有许多 shell,每个shell都是由某个she

shell 中的 envl 及 crontab 命令

envl eval会对后面的命令进行两遍扫描,如果第一遍扫描后,命令是个普通命令,则执行此命令:如果命令中含有变量的间接引用,则保证间接引用的语义.也就是说,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令.因此,eval命令适用于那些一次扫描无法实现其功能的变量. eval 执行以下两个步骤 第一次,执行变量替换,类似与C语言的宏替代 第二次,执行替换后的命令串 栗子: 1.  有一个名为test的文件,其内容为“Please move on !”,定义一个内容是cat test

Linux下的Source命令及脚本的执行方式解析

Linux Source命令及脚本的执行方式解析 http://blog.csdn.net/wangyangkobe/article/details/6595143 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用source命令,如:source /etc/profile对source进行了学习,并且用它与sh 执行脚本进行了对比,现在总结一下. source命令:source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令.功能:使Sh