Linux_shell编程基础_source命令和点命令

来源:互联网 发布:天刀男性角色捏脸数据 编辑:程序博客网 时间:2024/06/14 09:07

转自:http://blog.csdn.net/mci2004/article/details/7182829


       菜鸟最近在学习shell编程,好似太迟了,BS下自己。在学习shell编程的过程中,遇到了一个很弱智的问题,请教过别人但是被无情的BS了,决心回来弄明白。

       问题如下,当我们在基于Android源码开发的时候,总免不了会进入到各个模块的子目录下mm一把。然后把编译出来的东西push到手机上对应的目录下面。当时,我还是老老实实的敲 cd xx ....cd xx...mm...adb push xx....,总这么敲这几行重复的命令,时间一长就觉得烦了。看到公司某大牛在做同样事情的时候,老是敲一些我从来没见过的命令,遂菜鸟我厚着脸皮问人家,大牛回一了句:这是我自己写的脚本。当时菜鸟我顿悟啊!虽然之前就了解shell编程,但是没有好好学习过,现在借这个机会一定要好好恶补下了。shell脚本编程对于我们KUB的程序员来说还是很重要的。

        好了言归正转,但是我自己写了一个巨简单的shell脚本,如下,写这个脚本是为了能够快速的切换到某个android模块的Android.mk文件所在的目录。

        #!/bin/bash

        #cd2c.sh

         cd  /file/path

        但是我在运行这个脚本的时候(运行脚本前要跟该脚本加执行权限 chmod +x cd2c.sh),发现执行结果并不能切换到预期的目录,当时我就郁闷了,后来我又尝试了 source cd2c.sh,然后就正的cd到了/file/path目录,后来我就问旁边的大牛,大牛回答,好像跟什么父shell,子shell有点关系,然后我又问,为什么你直接执行就可以,我也没看你用啥source命令啊,大牛回答:因为我是用的alias,也就是别名。问了这个问题,我才感觉自己是多么sb,这里也要检讨下自己,大牛很忙,不要有一点问题就去问别人,遇到问题,还是先自己去找原因,尝试解决,不要马上就去寻求别人帮助,这样不助与我们解决问题能力的提升,而且也会耽误别人的时间。

           后来我自己又上网找了些资料学习了一下,总结如下:

        1,source命令和点(.)命令,其实是一回事,例如我在当前目录下要执行一个shell脚本,source filename.sh 和

. ./filename.sh是一样的效果注意点命令中,第一个点和第二点中间有一个空格(好白痴的注解,每个人应该都不会弄错吧)。

        2,来我们看看souce命令到底做了什么吧,先看看source命令的详解

        source filename [arguments]  Read and execute commands from filename in the current shell environment and return the exit sta-  tus of the last command executed from filename. If filename does not contain a slash, file names  in PATH are used to find the directory containing filename. The file searched for in PATH need  not be executable. When bash is not in posix mode, the current directory is searched if no file  is found in PATH. If the sourcepath option to the shopt builtin command is turned off, the PATH  is not searched. If any arguments are supplied, they become the positional parameters when file-  name is executed. Otherwise the positional parameters are unchanged. The return status is the  status of the last command exited within the script (0 if no commands are executed), and false if  filename is not found or cannot be read.

 看了以上这段第一句就应该大致明白了souece的意义,source 命令会将filename的命令都读进当前的shell环境中,并且在当前的shell环境中执行,因此 source cd2c.sh 会得到预期的结果,因为cd2c.sh中的命令就是在当前的shell环境中执行的。

         3,在看看如果直接运行一个shell脚本又到底做了什么呢?

          在当前的shell环境中(我们称作父shell),如果执行一个shell脚本,会做下面几件事

          a,当前的shell进程(父shell)fork/exec一个子shell用于执行filename中命令,这个时候,父shell进程wait等待子shell返回。

          b,子shell读取命令,开始执行builtin命令cd。

          c,子shell读到文件末尾,终止执行推出,从新回到父shell进程。

           可以看到,在执行一个shell的时候,cd /file/path命令确实执行了,但是是在子shell进程中执行的,执行完毕后子shell终止并返回到父进程中了,所以这时候并我们到达的预期效果。

----------------------------------------------------------------------------------------------------------------------------------------------------------

          上面讲了一些source的知识,现在说说source的应用场合。这里先打个插,还记得菜鸟我刚刚参加工作的时候,自己按照公司内部的文档,搭建linux上的android开发环境需要配置JDK或者android_SDK的时候,常常需要在~/.bashrc文件的末尾加上 export PATH=/PATH/TO/SDK_OR_JDK:$PATH 类是这样的命令,然后在source一下这个~/.bashrc ,当时菜鸟对linux的了解连皮毛都谈不上,所以根本不了解这么做的意义。现在接这个机会赶紧的补习一下吧。如果有不明白的同学赶紧学学吧。

          man bash 我们会看到下面的解释:

           ~/.bashrc

          The individual per-interactive-shell startup file,可以看出,~/.bash是一个独立的shell环境的启动文件(或者说启动脚本)。在这个~/.bash文件中,保存了一些设置例如别名,环境变量等。每次修改.bashrc后,使用source ~/.bashrc(或者 . ~/.bashrc)就可以立刻加载修改后的设置,使之生效。那么我们修改~/.bashrc文件后,下一次启动linux的时候,~/.bashrc文件中的内容会被执行到吗?又是如何被执行的呢?

          下面来看看另一个文件 ~/.bash_profile,man bash 关于这个文件的解释如下:

          The personal initialization file, executed for login shells,说实话不知道是什么意思,所以google之,得到如下结论,~/.bash_profile: 每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件。看重点,该文件仅仅在用户登录的时候执行一次,而且~/.bash_profile文件会去主动执行~/.bashrc。来看下该文件:

/*在我的电脑上,ubuntu11.04,~目录下没有.bash_profile取而代之的是.profile*/

           # exists.
           # see /usr/share/doc/bash/examples/startup-files for examples.
           # the files are located in the bash-doc package.

           # the default umask is set in /etc/profile; for setting the umask
           # for ssh logins, install and configure the libpam-umask package.
           #umask 022

          # if running bash
          if [ -n "$BASH_VERSION" ]; then
         # include .bashrc if it exists
         if [ -f "$HOME/.bashrc" ]; then
          .    "$HOME/.bashrc"    #注意看,点命令
          fi
          fi

           可以看到.profile文件有调用.bashrc,这样就保证我们之前修改过的.bashrc文件,在linux每次启动的时候都能被执行到。而.bashrc文件的内容在启动新的shell进程的时候会被执行。


----------------------------------------------------------------------------------------------------------------------------------------------------------           好了就写到这里吧!看来我真的是一个废话很多的人,这么简单的东西,写了这么多废话,:-)  !  各位大牛如果发现我写的有什么错误的话,一定要指正我哈,免得误导了那些跟我一样菜鸟。

          good night everyone!引用一句老罗的话,爱生活,爱android......


0 0