Shell-case:获取执行的脚本所在目录的位置

     今天和大家分享一个,大家shell脚本中常常想用,但却很难完成的一个功能的shell脚本,如何获取当前运行shell脚本所在目录位置。
     很多时候,我们写一个shell脚本在实现一个功能的时候不单单是一个shell脚本在进行工作,我们可能还有其他的一些文件辅助进行,而我们分享的时候通常会压缩到一个包中,而用户下载后解压使用,但问题也就出现了,我们并不知道用户解压在上面位置,如果用绝对路径压缩,会大大降低用户个性化使用感,这时候我们就希望能执行shell脚本的时候,shell脚本能获取shell脚本自身所在位置,那如何实现?话不多说,先上代码:

  path=${0%/*}
  echo $path | grep '^/' &>/dev/null
  if [ $? -ne 0 ];then
    path=$(echo $path | sed -r 's/.\/*//')
    path=$PWD/$path
  fi
  path=$(echo $path | sed -r 's/\/{2,}/\//')

  echo '脚本所在位置为'$path

     思考方向和算法思考差不多,我们从问题着手,如何让一个shell脚本运行的时候获得其具体位置,说到位置,我们第一个想到的系统变量就是$PWD,但是他是获取用户当前路径,和脚本没有关系,再想和路径相关的就是$0,他可以获取用户执行脚本的时候使用的路径,不过不同的脚本运行方法其$0的含义都不同,那首先我们就要先弄清楚如何运行一个shell脚本呢?想运行一个shell脚本,我们就要知道什么是shell脚本,这就涉及到一堆理论了,具体的,大家可以去阅读我一周的shell脚本学习blog,下面我就直接来总结一下然后运行shell脚本,运行的方法大致是这三种

  1. 绝对路径执行(以当前用户默认的shell解释器解释启动脚本)
  2. ./相对路径的脚本执行(这实质上也是以绝对路径执行)
  3. 解释器   相对路径 (这是用户指定解释器,然后执行脚本)

     那就分着三种情况进行分析,具体每个方案来做具体的操作,操作前,我们要先想怎么才能分出用户用的什么方法,由上文的分类,我们不难看出,这三个方法中用户输入的路径都是不同的,绝对路径用户输入的一定是 / 开头,到脚本目录执行,用户一定是输入的 . 开头的,而解释器后面跟着相对路径一定是 / 开头或者字母数字,再分析一下,只要用户输入的不是以 / 开头的都是相对目录,那就好办了,我们用$0获取用户输入的是什么,然后用grep判断一下即可,具体操作如下:

  echo $0 | grep '^/' &>/dev/null
  if [ $? -ne 0 ];then
    echo 用户输入的是相对路径下的脚本
  else
    echo 用户输入的绝对路径,下的脚本
  fi

     绝对路径下的脚本无所谓,我们直接就可以拿来用,相对路径,我们把当前用户所在位置接上就好,那么就是相对路径的情况中,我们进行
path=$PWD$0
绝对路径直接引用
path=$0
     这样实质上就已经获取了路径了,path就可以算是一个完整的脚本所在的绝对路径的位置,不过在实际使用中,我们会想要获取的是脚本所在目录的路径,刚刚获取的是脚本所在完整路径,其中包含了脚本名,我们想去掉脚本名,这其实很简单,把path进行去尾操作即可,可以再开始做分隔前,也可以在分隔后,都一样,不过如果在执行后进行处理,必须在目录后加上 / ,防止本来位置就是 / ,进行去尾后什么都没有,而执行前处理结果以目录名结尾,删除不可能全部删完,所以大家自行斟酌取舍,具体去尾代码如下

path=${0%/*}

     到此为止,基本可以实现所有功能了,不过测试中发现了bug,就是用./执行脚本的时候,发现目录中还包含 ./ 这其实很简单,用sed吧 ./ 全部删掉即可,这里用到sed的拓展正则:

path=$(echo $path | sed -r 's/.\/*//')

     最后为了美观,我们把目录路径中全部多个 / 改成一个,这些是美化工作,不做也不会影响正常的使用,具体操作代码如下:

path=$(echo $path | sed -r 's/\/{2,}/\//')

     组合起来就得到最终代码,代码可以直接被套用,需要获取脚本所在位置的道友,直接拷贝进自己的脚本中即可,不过注意不要出现变量名冲突的情况即可。

附:有不足的地方,望各位大佬指出,可以留言也可以email给作者,如果喜欢可以收藏转发,但请注明出处,谢谢。

猜你喜欢

转载自blog.csdn.net/Yu1543376365/article/details/82937512