source命令用法:
source FileName
作用:在当前 bash 环境下读取并执行 FileName 中的命令。该 filename 文件可以无”执行权限”
注:该命令通常用命令“.”来替代。
如:source .bash_profile. .bash_profile两者等效。
source(或点) 命令通常用于重新执行刚修改的初始化文档。
source命令 (从 C Shell 而来)是bash shell的内置命令。
点命令,就是个点符号,(从Bourne Shell而来)。
sh和bash命令用法:
sh FileNamebash FileName
作用:在当前bash环境下读取并执行FileName中的命令。该filename文件可以无”执行权限”
注:两者在执行文件时的不同,是分别用自己的shell来跑文件。
sh使用“-n”选项进行shell脚本的语法检查,使用“-x”选项实现shell脚本逐条语句的跟踪,
可以巧妙地利用shell的内置变量增强“-x”选项的输出信息等。
./ 的命令用法:
./FileName
作用:打开一个子 shell 来读取并执行 FileName 中命令。
注:运行一个shell脚本时会启动另一个命令解释器。
每个 shell 脚本有效地运行在父shell(parent shell)的一个子进程里。
这个父 shell 是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程。
shell 脚本也可以启动他自已的子进程。
这些子shell(即子进程)使脚本并行地,有效率地地同时运行脚本内的多个子任务。
shell的嵌入命令:
: 空,永远返回为true. 从当前shell中执行操作break 退出for、while、until或case语句cd 改变到当前目录continue 执行循环的下一步echo 反馈信息到标准输出eval 读取参数,执行结果命令exec 执行命令,但不在当前shellexit 退出当前shellexport 导出变量,使当前shell可利用它pwd 显示当前目录read 从标准输入读取一行文本readonly 使变量只读return 退出函数并带有返回值set 控制各种参数到标准输出的显示shift 命令行参数向左偏移一个test 评估条件表达式times 显示shell运行过程的用户和系统时间trap 当捕获信号时运行指定命令ulimit 显示或设置shell资源umask 显示或设置缺省文件创建模式unset 从shell内存中删除变量或函数wait 等待直到子进程运行完毕
下面再看下 shell 脚本各种执行方式(source ./.sh, . ./.sh, ./*.sh)的区别
结论一: ./*.sh的执行方式等价于sh ./*.sh或者bash ./*.sh,此三种执行脚本的方式都是重新启动一个子 shell,在子 shell 中执行此脚本,脚本中设置的变量在脚本执行完毕后不会保存。但是若 script.sh 脚本不是以 #!/bin/bash 开头,那么也不会在子进程中执行。
结论二: source ./*.sh和 . ./*.sh的执行方式是等价的,即两种执行方式都是在当前shell进程中执行此脚本,而不是重新启动一个shell 在子shell进程中执行此脚本,并且脚本中设置的变量在脚本执行完毕后会保存下来。
验证依据:没有被export导出的变量(即非环境变量)是不能被子shell继承的
验证结果:
[root@dev workspace]# name=noobwu //定义一般变量[root@dev workspace]# echo $namenoobwu[root@dev workspace]#[root@dev workspace]# vi test.sh //验证脚本,实例化标题中的./*.sh#!/bin/shecho ${name}[root@dev workspace]# cat test.sh[root@dev workspace]# ls -l test.sh //验证脚本可执行-rw-r--r-- 1 root root 25 Jan 6 23:12 test.sh[root@dev workspace]# chmod 777 test.sh //设置权限[root@dev workspace]# ./test.sh //以下三个命令证明了结论一[root@dev workspace]# sh ./test.sh[root@dev workspace]# bash ./test.sh[root@dev workspace]# . ./test.sh //以下两个命令证明了结论二noobwu[root@dev workspace]# source ./test.shnoobwu

# cat test.sh#! /bin/bashtest=1234# ./test.sh# echo $test# . test.sh# echo $test1234# cat test.sh#! /bin/bashtest=123# source test.shecho $test123
那关于是否是在子进程运行的区别又有什么影响呢?下面我们来做另外一个测试。
下面有一个检测进程 PID 的脚本 check_process.sh,请问运行./check_process.sh gmond 和 source check_process.sh gmond 输出会有什么不同?(假设已存在 1 个 gmond 进程,pid 为 17255)
#! /bin/bashprocess=$1pid=$(ps x | grep $process | grep -v grep | awk '{print $1}')echo $pid
运行测试:
# ./check_process.sh gmond17255 25930 25931# source check_process.sh gmond17255
😱 结果是不是有点奇怪,gmond 明明只有一个进程啊,为什么会出来三个进程 pid?
我们在脚本里加个 sleep,然后从另外窗口看下多出的进程 pid 是谁? 👀
#! /bin/bashprocess=$1pid=$(ps x | grep $process | grep -v grep | awk '{print $1}')echo $pidsleep 100
再运行
# ./check_process.sh gmond8215 8216 17255# ps -ef|grep gmond|grep -v greproot 8215 17611 0 14:26 pts/8 00:00:00 /bin/bash ./check_process.sh gmondroot 17255 1 5 Feb02 ? 5-15:08:55 /usr/sbin/gmond
发现 pid 为 8215 的进程就是我们执行脚本本身的进程。同时也可以看到,./ 最终调用执行的是 /bin/bash。
所以,我们用 shell 脚本来获取进程 pid 时一定要对进程本身进程过滤,可以用 grep -v bash:
#! /bin/bashprocess=$1pid=$(ps x | grep $process | grep -v grep |grep -v bash| awk '{print $1}')echo $pid
遗留的问题,若脚本中不加 #! /bin/bash,又会是什么结果呢?
process=$1pid=$(ps x | grep $process | grep -v grep | awk '{print $1}')echo $pid
此时可以发现,三种运行方式的结果都是正常的 😯
# ./check_process.sh gmond17255# . check_process.sh gmond17255# source check_process.sh gmond17255
原文链接
常用命令
取得当前执行的shell脚本的相对路径
BASH_SOURCE和BASH_SOURCE[0]的作用都是一样的,就是取得当前执行的 shell 脚本的相对路径
如果希望获得,当前执行脚本的绝对路径,可以采用以下方式:
[root@dev workspace]# curDir="$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"[root@dev workspace]# echo ${curDir}/root/workspace[root@dev workspace]#
[root@dev workspace]# echo $0 $1 $2bash[root@dev workspace]# echo "BASH_SOURCE = ${BASH_SOURCE}"BASH_SOURCE =[root@dev workspace]# echo "BASH_SOURCE[0] = ${BASH_SOURCE[0]}"BASH_SOURCE[0] =[root@dev workspace]# echo "dirname BASH_SOURCE[0] = $(dirname "${BASH_SOURCE[0]}")"dirname BASH_SOURCE[0] = .[root@dev workspace]# curDir="$( cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"[root@dev workspace]# echo "curDir=$curDir"curDir=/root/workspace[root@dev workspace]#
清屏
[root@dev workspace]# vi $HOME/.bashrcalias clear=' printf "\033c" ' #清屏alias cls=' printf "\033c" ' #清屏[root@dev workspace]# bash
