source命令用法

source FileName

通常用”.“来替代

source命令作用

在当前bash环境下读取并执行FileName中的命令

  • 功能:
    使当前shell读入路径为filepath的shell文件并依次执行文件中的所有语句,通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。例如,当我们修改了/etc/profile文件,并想让它立刻生效,而不用重新登录,就可以使用source命令,如source /etc/profile。
     
    source命令(从 C Shell 而来)是bash shell的内置命令。点命令(.),就是个点符号(从Bourne Shell而来)是source的另一名称。

source命令应用

鉴于上述的描述,最简单的一种应用场景就是,进行交叉编译时,在当前shell内采用source命令临时指定系统的编译环境为嵌入式编译环境,然后进行源码的编译和调试。而在别的shell内或者你关闭本shell时,一切又恢复原样。

所以把编译所需环境放在一个脚本文件中,在当前shell需要编译时可以执行source即可获得编译环境,就可以操作编译了。

还有一种情况是命令串,如

1
2
3
4
5
6
make mrproper
make menuconfig
make dep
make clean
make bzImage
.......

这些命令既长,又繁琐。而且有时候容易输错,浪费你的时间和精力。如果把这些命令做成一个文件,让它自动按顺序执行,对于需要多次反复编译核心的用户来说,会很方便。

用source命令可以办到这一点。它的作用就是把一个文件的内容当成是shell来执行。

先在/usr/src/linux-2.4.20目录下建立一个文件,取名为make_command,在其中输入如下内容:

1
2
3
4
5
6
7
8
9
10
11
make mrproper &&
make menuconfig &&
make dep &&
make clean &&
make bzImage &&
make modules &&
make modules_install &&
cp arch/i386/boot/bzImge /boot/vmlinuz_new &&
cp System.map /boot &&
vi /etc/lilo.conf &&
lilo -v

文件建立好之后,以后每次编译核心,只需要在/usr/src/linux-2.4.20下输入source make_command 就行了。这个文件也完全可以做成脚本,只需稍加改动即可。

shell编程中的命令有时和C语言是一样的。&&表示与,||表示或。把两个命令用&&联接起来,如 make mrproper && make menuconfig,表示要第一个命令执行成功才能执行第二个命令。对执行顺序有要求的命令能保证一旦有错误发生,下面的命令不会盲目地继续执行。

比较

  • source filepathsh filepath./filepath的区别

    1. source

    source a.sh

    在当前 shell 内去读取、执行a.sh,而a.sh不需要有 “执行权限”
    source命令可以简写为“.”

    . a.sh

    总结:source filename其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。
     
    2. sh/bash

    sh a.sh
    bash a.sh

    都是打开一个 subshell 去读取、执行a.sh,而a.sh不需要有 “执行权限”
    通常在subshell里运行的脚本里设置变量,不会影响到父shell的。

    总结:sh filepath 会重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell是新建的,其改变的变量不会被带回父shell。
     
    3. ./

    ./a.sh
    #bash: ./a.sh: 权限不够
    chmod +x a.sh
    ./a.sh

    打开一个 subshell 去读取、执行a.sh,但a.sh需要有 “执行权限”
    可以用chmod +x添加执行权限
    另外,使用./来执行的文件里有alias语句的话,shell并不会把alias别名扩展成对应的命令,要解决的话,得使用shopt命令来开启alias扩展选项

    shopt -s expand_aliases

    总结:当shell脚本具有可执行权限时,用sh filepath./filepath是没有区别的。./filepath是因为当前目录没有在PATH中,所有”.”是用来表示当前目录的。

 

  • fork、source、exec区别

    1. 使用fork方式运行script时, 就是让shell(parent process)产生一个child process去执行该script,当child process结束后,会返回parent process,但parent process的环境是不会因child process的改变而改变的。
    2. 使用source方式运行script时, 就是让script在当前process内执行, 而不是产生一个child process来执行。由于所有执行结果均于当前process内完成,若script的环境有所改变, 当然也会改变当前process环境了。
    3. 使用exec方式运行script时, 它和source一样,也是让script在当前process内执行,但是process内的原代码剩下部分将被终止。同样,process内的环境随script改变而改变。

 

  • 举例说明

    1.sh

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/bin/bash
    A=B
    echo "PID for 1.sh before exec/source/fork:$$"
    export A
    echo "1.sh: \$A is $A"
    case $1 in
    exec)
    echo "using exec..."
    exec ./2.sh ;;
    source)
    echo "using source..."
    . ./2.sh ;;
    *)
    echo "using fork by default..."
    ./2.sh ;;
    esac
    echo "PID for 1.sh after exec/source/fork:$$"
    echo "1.sh: \$A is $A"

    2.sh

    1
    2
    3
    4
    5
    6
    #!/bin/bash
    echo "PID for 2.sh: $$"
    echo "2.sh get \$A=$A from 1.sh"
    A=C
    export A
    echo "2.sh: \$A is $A"

    运行结果:

    1
    2
    3
    4
    5
    chmod +x 1.sh
    chmod +x 2.sh
    ./1.sh fork
    ./1.sh source
    ./1.sh exec