今天看脚本的时候看到了几个不懂的地方:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
这句的前面有个注释,Where am I?,而且后面还有一个pwd
,所以很明显这句的作用是获取当前所在的位置。
然后最后肯定是pwd
的值返回给DIR
。可是只知道双引号里面应该是字符串,怎么就可以执行指令并赋值给变量。
将命令结果赋值给变量
查了一下shell里面怎将命令结果赋值给变量,发现有两种方式实现:
- 将命令用反引号包起来,但是不支持嵌套。
- 使用
$(command)
的形式,支持嵌套。
$ A=`date`
$ echo $A
Sat Apr 16 22:51:26 CST 2011 # 变量A 存放了date 命令的执行结果
$ B=$(date)
$ echo $B
Sat Apr 16 22:57 :47 CST 2011 # 变量B 存放了date 命令的执行结果
而双引号的作用是让命令的返回值保留换行符。
参考资料:https://book.51cto.com/art/201411/457601.htm
对比分析
然后再来看这条命令,有2个$()
,一个&&
。第一个$()
有两个命令cd
和pwd
。然后cd
后面是一个嵌套的$()
,里面有个dirname
命令。下面分别来看这3个命令的作用。
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
第1和第3个是
cd
和pwd
。cd
的值是又是一个$()
包起来的命令。所以这个dirname
命令肯定是获取一个路径的。cd
进入一个目录之后,然后pwd
打印当前目录。 -
第2个
dirname
。这个就不是很懂了,查了一下才知道,这个
dirname
就是提取参数里面的目录,dirname "${BASH_SOURCE[0]}"
表示提取脚本运行时的第一个参数的目录。下面用一个例子来演式一下。我在桌面(
/mnt/c/Users/17303/Dekstop
)下建一个脚本test.sh
,内容如下:#!/bin/bash DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) echo ${DIR} DIR2="$(pwd)" echo ${DIR2} DIR3=`pwd` echo ${DIR3} DIR4="$( dirname "${BASH_SOURCE[0]}" )" echo ${DIR4}
然后再
Desktop
下执行,输出如下:# xs @ 108-XS in /mnt/c/Users/17303/desktop [21:37:05] $ ./test.sh /mnt/c/Users/17303/desktop /mnt/c/Users/17303/desktop /mnt/c/Users/17303/desktop .
第1,2,3条都获取到了
test.sh
所在的绝对路径。脚本执行的命令是./test.sh
,所以他的目录就是.
,第4条就打印出了点。第一条的cd .
,还是在当前的目录不变,然后再pwd
,得到的结果就和2,3一样。然后我切换到Desktop的上一个目录再来执行一下,输出如下:
# xs @ 108-XS in /mnt/c/Users/17303 [21:43:22] $ ./desktop/test.sh /mnt/c/Users/17303/desktop /mnt/c/Users/17303 /mnt/c/Users/17303 ./desktop
第1条仍然可以获取到脚本所在的绝对路径,而2,3条就是Desktop的上一级,第4条则是
./desktop/test.sh
命令的目录./desktop
。然后因为第一条的cd
命令进入了这个目录,再执行pwd
时就在脚本所在目录的绝对路径。参考资料:https://blog.youkuaiyun.com/davidhopper/article/details/78989369