如何获得 sh 或 source 执行的shell 脚本位置

时间:2020-12-29 09:15:45

* 支持从其他目录执行,如 source xxx/yyy/test.sh

* 支持 sh 和 source 执行

* 支持路径中有空格

* 支持 zsh 跟 bash

* 支持 ubuntu/centos

 

#!/bin/bash

#获得该文件的位置
echo "$0" | grep -q "$0"
if [ $? -eq 0 ]; then
        cd "$(dirname "$BASH_SOURCE")"
        CUR_FILE=$(pwd)/$(basename "$BASH_SOURCE")
        CUR_DIR=$(dirname "$CUR_FILE")
        cd - > /dev/null
else
        if [ ${0:0:1} = "/" ]; then
                CUR_FILE=$0
        else
                CUR_FILE=$(pwd)/$0
        fi
        CUR_DIR=$(dirname "$CUR_FILE")
fi
#去掉路径中的相对路径,如a/..b/c
cd "$CUR_DIR"
CUR_DIR=$PWD
cd - > /dev/null

echo $CUR_DIR

 

为什么这么多双引号

参考:http://tech.idv2.com/2008/01/09/bash-pitfalls/

 

为什么else里有个判断

使用virtualenvwrapper时,workon xxx进入环境, 会自动source xxx/bin/postactive等脚本, 如果这些脚本中这样用时,$0不知道为什么不是相对路径,而是绝对路径。

故if [ ${0:0:1} = "/" ] 判断$0 是相对路径还是绝对路径。

 

为什么判断$0的值

$ cat test.sh
#!/bin/sh
echo $0

bash中sh执行脚本,$0为脚本的名字
$ sh test.sh
test.sh

bash中source执行脚本,$0与直接在终端echo $0的值一样
$ source test.sh
bash

bash中执行echo $0,ubuntu中为bash,centos中为-bash
$ echo $0
bash


zsh中sh跟source执行脚本,$0都为脚本的相对路径
$ sh test.sh
test.sh
$ source test.sh
test.sh
zsh中执行echo $0,有时为-zsh,有时为zsh,有时为/usr/bin/zsh

archlinux 中打开终端,直接执行echo $0为/bin/bash,输入bash后再执行echo $0为bash

 

若写成函数,bash没问题。但zsh中source执行时函数内的$0不正确,导致结果不正确,sh执行没问题。

比如 source test\ space/get_cur_dir.sh,函数外$0为test space/get_cur_dir.sh,函数内$0为get_cur_dir。

 

各种情况不一样,懒得总结,讨厌shell 脚本!

 

从这里:http://*.com/questions/5708339/script-full-name-and-path-0-not-visible-when-called,得到启发,判断$0的值以分解问题;

从这里:http://bbs.chinaunix.net/thread-1288910-2-1.html,得到了正确的方法。