Bash script absolute path with OS X

后端 未结 15 986
误落风尘
误落风尘 2020-11-29 18:20

I am trying to obtain the absolute path to the currently running script on OS X.

I saw many replies going for readlink -f $0. However since OS X\'s

相关标签:
15条回答
  • 2020-11-29 18:40

    Based on the communication with commenter, I agreed that it is very hard and has no trival way to implement a realpath behaves totally same as Ubuntu.

    But the following version, can handle corner cases best answer can't and satisfy my daily needs on macbook. Put this code into your ~/.bashrc and remember:

    • arg can only be 1 file or dir, no wildcard
    • no spaces in the dir or file name
    • at least the file or dir's parent dir exists
    • feel free to use . .. / thing, these are safe

        # 1. if is a dir, try cd and pwd
        # 2. if is a file, try cd its parent and concat dir+file
        realpath() {
         [ "$1" = "" ] && return 1
    
         dir=`dirname "$1"`
         file=`basename "$1"`
    
         last=`pwd`
    
         [ -d "$dir" ] && cd $dir || return 1
         if [ -d "$file" ];
         then
           # case 1
           cd $file && pwd || return 1
         else
           # case 2
           echo `pwd`/$file | sed 's/\/\//\//g'
         fi
    
         cd $last
        }
    
    0 讨论(0)
  • 2020-11-29 18:44

    Use Python to get it:

    #!/usr/bin/env python
    import os
    import sys
    
    print(os.path.realpath(sys.argv[1]))
    
    0 讨论(0)
  • 2020-11-29 18:46

    I was looking for a solution for use in a system provision script, i.e., run before Homebrew is even installed. Lacking a proper solution I'd just offload the task to a cross-platform language, e.g., Perl:

    script_abspath=$(perl -e 'use Cwd "abs_path"; print abs_path(@ARGV[0])' -- "$0")
    

    More often what we actually want is the containing directory:

    here=$(perl -e 'use File::Basename; use Cwd "abs_path"; print dirname(abs_path(@ARGV[0]));' -- "$0")
    
    0 讨论(0)
  • 2020-11-29 18:46

    realpath for Mac OS X

    realpath() {
        path=`eval echo "$1"`
        folder=$(dirname "$path")
        echo $(cd "$folder"; pwd)/$(basename "$path"); 
    }
    

    Example with related path:

    realpath "../scripts/test.sh"
    

    Example with home folder

    realpath "~/Test/../Test/scripts/test.sh"
    
    0 讨论(0)
  • 2020-11-29 18:47

    These three simple steps are going to solve this and many other OS X issues:

    1. Install Homebrew
    2. brew install coreutils
    3. grealpath .

    (3) may be changed to just realpath, see (2) output

    0 讨论(0)
  • 2020-11-29 18:49

    Ugh. I found the prior answers a bit wanting for a few reasons: in particular, they don't resolve multiple levels of symbolic links, and they are extremely "Bash-y". While the original question does explicitly ask for a "Bash script", it also makes mention of Mac OS X's BSD-like, non-GNU readlink. So here's an attempt at some reasonable portability (I've checked it with bash as 'sh' and dash), resolving an arbitrary number of symbolic links; and it should also work with whitespace in the path(s), although I'm not sure of the behavior if there is white space the base name of the utility itself, so maybe, um, avoid that?

    #!/bin/sh
    realpath() {
      OURPWD=$PWD
      cd "$(dirname "$1")"
      LINK=$(readlink "$(basename "$1")")
      while [ "$LINK" ]; do
        cd "$(dirname "$LINK")"
        LINK=$(readlink "$(basename "$1")")
      done
      REALPATH="$PWD/$(basename "$1")"
      cd "$OURPWD"
      echo "$REALPATH"
    }
    realpath "$@"
    

    Hope that can be of some use to someone.

    0 讨论(0)
提交回复
热议问题