IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    shell下精确的定位一个命令

    hongjiang发表于 2016-10-08 09:16:09
    love 0

    之前在这篇SIGTTIN? 里提出了问题,但没有交代背景,为什么用交互式shell执行”which mvn”命令,是为了更准确的获取用户当前环境里所用的mvn命令到底是哪个。若用户对mvn做过alias,优先使用alias过的指令,然后再选择$PATH路径下的命令;这个函数的完整内容如下:

    function get_mvn_cmd() {
      if [[ "$OSTYPE" == *cygwin* ]];then
        ppid=$( ps -ef -p $$ | awk 'NR==2{print $3}' )
        user_shell=$( ps -p $ppid | awk 'NR==2{print $8}' )
        #has some trouble with cygwin, while Ctrl-c cannot terminal
        set -m
      else
        ppid=$( ps -oppid= $$ )
        user_shell=$( ps -ocomm= -p $ppid )
      fi
    
      # while as login shell, it's -bash not bash
      if [[ "$user_shell" == "-"* ]];then
        user_shell=${user_shell:1}
      fi
    
      mvn=$( $user_shell -ic "alias mvn" 2>/dev/null | cut -d'=' -f2 | sed "s/'//g" )
    
      if [ -z "$mvn" ];then
        $user_shell -ic "which mvn" >/dev/null
        if [ $? -eq 0 ];then
          mvn=$( $user_shell -ic "which mvn" | head -1 )
        fi
      fi
    
      if [ -z "$mvn" ]; then
        echo "mvn command not found" >&2
        kill -s TERM $TOP_PID
      else
        echo $mvn
      fi
    }
    

    函数里先获取用户所使用的shell(即当前脚本的父进程),然后以交互式执行alias mvn看看是否又被用户别名过,没有的话再使用which mvn获取mvn命令。

    为什么写的那么啰嗦是想兼容好几种用户环境,如果是linux或者使用的gnu-which,可以利用gnu-which的一些参数一次性按优先级依次从”alias, functions, commands”里查找命令

    $ (alias; declare -f) | gwhich --read-alias --read-functions mvn
    

    上面利用gnu-which的--read-alias和--read-functions参数优先从前边alias和declare -f输出的结果里查找,最后再从$PATH里查找。实际上centos7的bash下which命令就被alias过了:

    alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'    
    


沪ICP备19023445号-2号
友情链接