How to retrieve the absolute path of an arbitrary file from the OS X












18















I'm looking for a simple command that can be used within Bash to find the absolute and canonicalized path to a file on an OS X (similar to ``readlink -f'` under Linux).



The following sample bash session describes a [fictitious] utility called ``abspath'` that exhibits the desired behavior:



$ pwd
/Users/guyfleegman

$ ls -lR
drwxr-xr-x 4 guyfleegman crew 136 Oct 30 02:09 foo

./foo:
-rw-r--r-- 1 guyfleegman crew 0 Oct 30 02:07 bar.txt
lrwxr-xr-x 1 guyfleegman crew 7 Oct 30 02:09 baz.txt -> bar.txt


$ abspath .
/Users/guyfleegman

$ abspath foo
/Users/guyfleegman/foo

$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt

$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt


As with the last invocation of ``abspath'` in the above example, I'd prefer it didn't automatically resolve symlinks, but I'm not going to be too picky here.










share|improve this question























  • A similar question at Stack Overflow

    – user495470
    Aug 21 '12 at 20:11
















18















I'm looking for a simple command that can be used within Bash to find the absolute and canonicalized path to a file on an OS X (similar to ``readlink -f'` under Linux).



The following sample bash session describes a [fictitious] utility called ``abspath'` that exhibits the desired behavior:



$ pwd
/Users/guyfleegman

$ ls -lR
drwxr-xr-x 4 guyfleegman crew 136 Oct 30 02:09 foo

./foo:
-rw-r--r-- 1 guyfleegman crew 0 Oct 30 02:07 bar.txt
lrwxr-xr-x 1 guyfleegman crew 7 Oct 30 02:09 baz.txt -> bar.txt


$ abspath .
/Users/guyfleegman

$ abspath foo
/Users/guyfleegman/foo

$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt

$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt


As with the last invocation of ``abspath'` in the above example, I'd prefer it didn't automatically resolve symlinks, but I'm not going to be too picky here.










share|improve this question























  • A similar question at Stack Overflow

    – user495470
    Aug 21 '12 at 20:11














18












18








18


10






I'm looking for a simple command that can be used within Bash to find the absolute and canonicalized path to a file on an OS X (similar to ``readlink -f'` under Linux).



The following sample bash session describes a [fictitious] utility called ``abspath'` that exhibits the desired behavior:



$ pwd
/Users/guyfleegman

$ ls -lR
drwxr-xr-x 4 guyfleegman crew 136 Oct 30 02:09 foo

./foo:
-rw-r--r-- 1 guyfleegman crew 0 Oct 30 02:07 bar.txt
lrwxr-xr-x 1 guyfleegman crew 7 Oct 30 02:09 baz.txt -> bar.txt


$ abspath .
/Users/guyfleegman

$ abspath foo
/Users/guyfleegman/foo

$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt

$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt


As with the last invocation of ``abspath'` in the above example, I'd prefer it didn't automatically resolve symlinks, but I'm not going to be too picky here.










share|improve this question














I'm looking for a simple command that can be used within Bash to find the absolute and canonicalized path to a file on an OS X (similar to ``readlink -f'` under Linux).



The following sample bash session describes a [fictitious] utility called ``abspath'` that exhibits the desired behavior:



$ pwd
/Users/guyfleegman

$ ls -lR
drwxr-xr-x 4 guyfleegman crew 136 Oct 30 02:09 foo

./foo:
-rw-r--r-- 1 guyfleegman crew 0 Oct 30 02:07 bar.txt
lrwxr-xr-x 1 guyfleegman crew 7 Oct 30 02:09 baz.txt -> bar.txt


$ abspath .
/Users/guyfleegman

$ abspath foo
/Users/guyfleegman/foo

$ abspath ./foo/bar.txt
/Users/guyfleegman/foo/bar.txt

$ abspath foo/baz.txt
/Users/guyfleegman/foo/baz.txt


As with the last invocation of ``abspath'` in the above example, I'd prefer it didn't automatically resolve symlinks, but I'm not going to be too picky here.







macos osx-snow-leopard bash shell






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Oct 30 '10 at 9:53









Michael WehnerMichael Wehner

191113




191113













  • A similar question at Stack Overflow

    – user495470
    Aug 21 '12 at 20:11



















  • A similar question at Stack Overflow

    – user495470
    Aug 21 '12 at 20:11

















A similar question at Stack Overflow

– user495470
Aug 21 '12 at 20:11





A similar question at Stack Overflow

– user495470
Aug 21 '12 at 20:11










9 Answers
9






active

oldest

votes


















16














function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname "$1"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename "$1"`"; else echo "$cur_dir/`basename "$1"`"; fi; fi; popd > /dev/null; }


Examples:



abspath / => /

abspath /.DS_Store => /.DS_Store

abspath ~ => /Users/mschrag

cd /tmp; abspath . => /tmp

cd /; abspath .DS_Store => /.DS_Store





share|improve this answer

































    11














    I don't think there's a buildin command that does this. Jesse Wilson wrote a bash script for this:



    #!/bin/bash
    cd -P -- "$(dirname -- "$1")" &&
    printf '%sn' "$(pwd -P)/$(basename -- "$1")"


    However, it does not work well for paths directly below /, such as /etc (printing //etc), as well as . and .. (printing /cwd/. in both cases). I tried modifying it, but my unsufficient bash-fu failed me.



    Here's my suggestion:



    #!/usr/bin/env python
    import os.path
    import sys

    for arg in sys.argv[1:]:
    print os.path.abspath(arg)


    Save as /usr/bin/abspath or something like that and make it executable. Sample output:



    Servus08:~ danielbeck$ abspath .
    /Users/danielbeck
    Servus08:~ danielbeck$ abspath /tmp
    /tmp
    Servus08:~ danielbeck$ abspath Documents
    /Users/danielbeck/Documents
    Servus08:~ danielbeck$ abspath . /tmp Documents
    /Users/danielbeck
    /tmp
    /Users/danielbeck/Documents


    If you do want symlink resolution, change the print line like this:



        print os.path.realpath(os.path.abspath(arg))


    to get this:



    Servus08:~ danielbeck$ abspath . /tmp Documents
    /Users/danielbeck
    /private/tmp
    /Users/danielbeck/Documents





    share|improve this answer



















    • 1





      I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

      – Michael Wehner
      Nov 1 '10 at 4:47






    • 2





      @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

      – Daniel Beck
      Nov 1 '10 at 7:23











    • The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

      – Michael Wehner
      Nov 6 '10 at 9:21






    • 1





      @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

      – Daniel Beck
      Nov 6 '10 at 9:46






    • 2





      @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

      – Arjan
      Dec 5 '10 at 16:24



















    8














    One option would be to just install coreutils and use greadlink -f. It resolves symlinks and it works with /Foo/ or ~/foo.txt if they don't exist, but not with /Foo/foo.txt if /Foo/ doesn't exist.



    $ brew install coreutils
    $ greadlink -f /etc
    /private/etc
    $ greadlink -f ~/Documents/
    /Users/lauri/Documents
    $ greadlink -f ..
    /Users
    $ greadlink -f //etc/..////
    /private
    $ greadlink -f /Foo
    /Foo
    $ greadlink -f /Foo/foo.txt
    $


    This doesn't resolve symlinks, and it doesn't work with /Foo/foo.txt either.



    abspath() {
    if [ -d "$1" ]; then
    ( cd "$1"; dirs -l +0 )
    else
    ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
    fi
    }

    abspath /etc # /etc
    abspath ~/Foo/foo.txt # doesn't work
    abspath ~/Foo # works
    abspath .
    abspath ./
    abspath ../
    abspath ..
    abspath /
    abspath ~
    abspath ~/
    abspath ~/Documents
    abspath /" '
    abspath /etc/../etc/
    abspath /private//etc/
    abspath /private//
    abspath //private # //private
    abspath ./aa.txt
    abspath aa.tar.gz
    abspath .aa.txt
    abspath /.DS_Store
    abspath ~/Documents/Books/


    dirs -l performs tilde expansion. dirs +0 prints only the topmost directory if there are other directories in the stack.






    share|improve this answer

































      2














      I guess you could do it with either python or ruby.



      $ ruby -e 'puts File.expand_path("~/somepath")'


      or make it a command with



      #!/usr/bin/env ruby
      puts File.expand_path(ARGV[0])





      share|improve this answer
























      • My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

        – Michael Wehner
        Nov 1 '10 at 4:57





















      1














      If you have the File::Spec module installed for perl you can just do this:



      perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "n"'





      share|improve this answer































        0














        For bash/sh scripts you can use this recursive function:



        canonical_readlink ()
        {
        cd `dirname $1`;
        __filename=`basename $1`;
        if [ -h "$__filename" ]; then
        canonical_readlink `readlink $__filename`;
        else
        echo "`pwd -P`";
        fi
        }

        answer=$(canonical_readlink $0)





        share|improve this answer
























        • Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

          – user495470
          Aug 21 '12 at 20:07



















        0














        Install the following library for OSX:



        brew install coreutils

        greadlink -f file.txt





        share|improve this answer































          0














          If installing coreutils is not an option, the following handles combos of symlinks, . and .. and works on files and folders like GNU realpath does:



          #!/usr/bin/env bash
          realpath()
          {
          if ! pushd $1 &> /dev/null; then
          pushd ${1##*/} &> /dev/null
          echo $( pwd -P )/${1%/*}
          else
          pwd -P
          fi
          popd > /dev/null
          }


          But it does not support realpath's --relative-to. This would require https://stackoverflow.com/a/12498485/869951.






          share|improve this answer































            0














            Given that the constraint is MacOS (OS X at the time), PHP is available by default. This will return the root directory of the file. Remove dirname to get the file, too.



            export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"





            share|improve this answer























              Your Answer








              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "3"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f205127%2fhow-to-retrieve-the-absolute-path-of-an-arbitrary-file-from-the-os-x%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              9 Answers
              9






              active

              oldest

              votes








              9 Answers
              9






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              16














              function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname "$1"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename "$1"`"; else echo "$cur_dir/`basename "$1"`"; fi; fi; popd > /dev/null; }


              Examples:



              abspath / => /

              abspath /.DS_Store => /.DS_Store

              abspath ~ => /Users/mschrag

              cd /tmp; abspath . => /tmp

              cd /; abspath .DS_Store => /.DS_Store





              share|improve this answer






























                16














                function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname "$1"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename "$1"`"; else echo "$cur_dir/`basename "$1"`"; fi; fi; popd > /dev/null; }


                Examples:



                abspath / => /

                abspath /.DS_Store => /.DS_Store

                abspath ~ => /Users/mschrag

                cd /tmp; abspath . => /tmp

                cd /; abspath .DS_Store => /.DS_Store





                share|improve this answer




























                  16












                  16








                  16







                  function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname "$1"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename "$1"`"; else echo "$cur_dir/`basename "$1"`"; fi; fi; popd > /dev/null; }


                  Examples:



                  abspath / => /

                  abspath /.DS_Store => /.DS_Store

                  abspath ~ => /Users/mschrag

                  cd /tmp; abspath . => /tmp

                  cd /; abspath .DS_Store => /.DS_Store





                  share|improve this answer















                  function abspath() { pushd . > /dev/null; if [ -d "$1" ]; then cd "$1"; dirs -l +0; else cd "`dirname "$1"`"; cur_dir=`dirs -l +0`; if [ "$cur_dir" == "/" ]; then echo "$cur_dir`basename "$1"`"; else echo "$cur_dir/`basename "$1"`"; fi; fi; popd > /dev/null; }


                  Examples:



                  abspath / => /

                  abspath /.DS_Store => /.DS_Store

                  abspath ~ => /Users/mschrag

                  cd /tmp; abspath . => /tmp

                  cd /; abspath .DS_Store => /.DS_Store






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jun 26 '11 at 10:55









                  3498DB

                  15.7k114762




                  15.7k114762










                  answered Dec 5 '10 at 16:01









                  mschragmschrag

                  1612




                  1612

























                      11














                      I don't think there's a buildin command that does this. Jesse Wilson wrote a bash script for this:



                      #!/bin/bash
                      cd -P -- "$(dirname -- "$1")" &&
                      printf '%sn' "$(pwd -P)/$(basename -- "$1")"


                      However, it does not work well for paths directly below /, such as /etc (printing //etc), as well as . and .. (printing /cwd/. in both cases). I tried modifying it, but my unsufficient bash-fu failed me.



                      Here's my suggestion:



                      #!/usr/bin/env python
                      import os.path
                      import sys

                      for arg in sys.argv[1:]:
                      print os.path.abspath(arg)


                      Save as /usr/bin/abspath or something like that and make it executable. Sample output:



                      Servus08:~ danielbeck$ abspath .
                      /Users/danielbeck
                      Servus08:~ danielbeck$ abspath /tmp
                      /tmp
                      Servus08:~ danielbeck$ abspath Documents
                      /Users/danielbeck/Documents
                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /tmp
                      /Users/danielbeck/Documents


                      If you do want symlink resolution, change the print line like this:



                          print os.path.realpath(os.path.abspath(arg))


                      to get this:



                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /private/tmp
                      /Users/danielbeck/Documents





                      share|improve this answer



















                      • 1





                        I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                        – Michael Wehner
                        Nov 1 '10 at 4:47






                      • 2





                        @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                        – Daniel Beck
                        Nov 1 '10 at 7:23











                      • The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                        – Michael Wehner
                        Nov 6 '10 at 9:21






                      • 1





                        @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                        – Daniel Beck
                        Nov 6 '10 at 9:46






                      • 2





                        @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                        – Arjan
                        Dec 5 '10 at 16:24
















                      11














                      I don't think there's a buildin command that does this. Jesse Wilson wrote a bash script for this:



                      #!/bin/bash
                      cd -P -- "$(dirname -- "$1")" &&
                      printf '%sn' "$(pwd -P)/$(basename -- "$1")"


                      However, it does not work well for paths directly below /, such as /etc (printing //etc), as well as . and .. (printing /cwd/. in both cases). I tried modifying it, but my unsufficient bash-fu failed me.



                      Here's my suggestion:



                      #!/usr/bin/env python
                      import os.path
                      import sys

                      for arg in sys.argv[1:]:
                      print os.path.abspath(arg)


                      Save as /usr/bin/abspath or something like that and make it executable. Sample output:



                      Servus08:~ danielbeck$ abspath .
                      /Users/danielbeck
                      Servus08:~ danielbeck$ abspath /tmp
                      /tmp
                      Servus08:~ danielbeck$ abspath Documents
                      /Users/danielbeck/Documents
                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /tmp
                      /Users/danielbeck/Documents


                      If you do want symlink resolution, change the print line like this:



                          print os.path.realpath(os.path.abspath(arg))


                      to get this:



                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /private/tmp
                      /Users/danielbeck/Documents





                      share|improve this answer



















                      • 1





                        I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                        – Michael Wehner
                        Nov 1 '10 at 4:47






                      • 2





                        @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                        – Daniel Beck
                        Nov 1 '10 at 7:23











                      • The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                        – Michael Wehner
                        Nov 6 '10 at 9:21






                      • 1





                        @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                        – Daniel Beck
                        Nov 6 '10 at 9:46






                      • 2





                        @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                        – Arjan
                        Dec 5 '10 at 16:24














                      11












                      11








                      11







                      I don't think there's a buildin command that does this. Jesse Wilson wrote a bash script for this:



                      #!/bin/bash
                      cd -P -- "$(dirname -- "$1")" &&
                      printf '%sn' "$(pwd -P)/$(basename -- "$1")"


                      However, it does not work well for paths directly below /, such as /etc (printing //etc), as well as . and .. (printing /cwd/. in both cases). I tried modifying it, but my unsufficient bash-fu failed me.



                      Here's my suggestion:



                      #!/usr/bin/env python
                      import os.path
                      import sys

                      for arg in sys.argv[1:]:
                      print os.path.abspath(arg)


                      Save as /usr/bin/abspath or something like that and make it executable. Sample output:



                      Servus08:~ danielbeck$ abspath .
                      /Users/danielbeck
                      Servus08:~ danielbeck$ abspath /tmp
                      /tmp
                      Servus08:~ danielbeck$ abspath Documents
                      /Users/danielbeck/Documents
                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /tmp
                      /Users/danielbeck/Documents


                      If you do want symlink resolution, change the print line like this:



                          print os.path.realpath(os.path.abspath(arg))


                      to get this:



                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /private/tmp
                      /Users/danielbeck/Documents





                      share|improve this answer













                      I don't think there's a buildin command that does this. Jesse Wilson wrote a bash script for this:



                      #!/bin/bash
                      cd -P -- "$(dirname -- "$1")" &&
                      printf '%sn' "$(pwd -P)/$(basename -- "$1")"


                      However, it does not work well for paths directly below /, such as /etc (printing //etc), as well as . and .. (printing /cwd/. in both cases). I tried modifying it, but my unsufficient bash-fu failed me.



                      Here's my suggestion:



                      #!/usr/bin/env python
                      import os.path
                      import sys

                      for arg in sys.argv[1:]:
                      print os.path.abspath(arg)


                      Save as /usr/bin/abspath or something like that and make it executable. Sample output:



                      Servus08:~ danielbeck$ abspath .
                      /Users/danielbeck
                      Servus08:~ danielbeck$ abspath /tmp
                      /tmp
                      Servus08:~ danielbeck$ abspath Documents
                      /Users/danielbeck/Documents
                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /tmp
                      /Users/danielbeck/Documents


                      If you do want symlink resolution, change the print line like this:



                          print os.path.realpath(os.path.abspath(arg))


                      to get this:



                      Servus08:~ danielbeck$ abspath . /tmp Documents
                      /Users/danielbeck
                      /private/tmp
                      /Users/danielbeck/Documents






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Oct 30 '10 at 10:49









                      Daniel BeckDaniel Beck

                      92.2k12232284




                      92.2k12232284








                      • 1





                        I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                        – Michael Wehner
                        Nov 1 '10 at 4:47






                      • 2





                        @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                        – Daniel Beck
                        Nov 1 '10 at 7:23











                      • The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                        – Michael Wehner
                        Nov 6 '10 at 9:21






                      • 1





                        @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                        – Daniel Beck
                        Nov 6 '10 at 9:46






                      • 2





                        @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                        – Arjan
                        Dec 5 '10 at 16:24














                      • 1





                        I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                        – Michael Wehner
                        Nov 1 '10 at 4:47






                      • 2





                        @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                        – Daniel Beck
                        Nov 1 '10 at 7:23











                      • The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                        – Michael Wehner
                        Nov 6 '10 at 9:21






                      • 1





                        @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                        – Daniel Beck
                        Nov 6 '10 at 9:46






                      • 2





                        @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                        – Arjan
                        Dec 5 '10 at 16:24








                      1




                      1





                      I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                      – Michael Wehner
                      Nov 1 '10 at 4:47





                      I think you're on the right track with the first shell-based approach, but I believe that using another language for doing this somewhat defeats the purpose, as it introduces additional dependencies and is pretty much equivalent to simply compiling GNU's version of `readlink(1)' under OS X (assuming this can be done; I haven't verified it yet).

                      – Michael Wehner
                      Nov 1 '10 at 4:47




                      2




                      2





                      @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                      – Daniel Beck
                      Nov 1 '10 at 7:23





                      @Michael You're either on a system with GNU readlink, or on OS X -- right? OS X has Python out of the box. In theory it's a new dependency, in practice not. Anyway, it's all I can offer you.

                      – Daniel Beck
                      Nov 1 '10 at 7:23













                      The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                      – Michael Wehner
                      Nov 6 '10 at 9:21





                      The pragmatic approach you're implying is laudable, if overly simplistic. In any case, if we were to take this approach in lieu of anything written purely in bash (which is absolutely doable and doesn't depend on anything else--it just can't easily be done in one line), Python probably isn't the best choice. Both Perl and Ruby (and probably PHP) can do this succinctly on the command line without the need to create an actual script file.

                      – Michael Wehner
                      Nov 6 '10 at 9:21




                      1




                      1





                      @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                      – Daniel Beck
                      Nov 6 '10 at 9:46





                      @Michael: True, but that's not what I was commenting on. I offer you a 90% solution written in pure bash by Jesse Wilson + the analysis why it's only 90%. If that's no problem for you, that's fine. I also gave you a slightly more complicated, 100% solution in Python. While other scripting languages might be briefer (Perl infamously so :-) ), all require an additional file to store the command. Or do you want to write it out every time you want to use it? That's also why I added the multi-line ability to handle multiple parameters, 1 or 2 lines then don't make a different.

                      – Daniel Beck
                      Nov 6 '10 at 9:46




                      2




                      2





                      @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                      – Arjan
                      Dec 5 '10 at 16:24





                      @Michael, why wouldn't Python be a good choice on OS X? It even ships with commands that are actually Python scripts, like file /usr/bin/xattr

                      – Arjan
                      Dec 5 '10 at 16:24











                      8














                      One option would be to just install coreutils and use greadlink -f. It resolves symlinks and it works with /Foo/ or ~/foo.txt if they don't exist, but not with /Foo/foo.txt if /Foo/ doesn't exist.



                      $ brew install coreutils
                      $ greadlink -f /etc
                      /private/etc
                      $ greadlink -f ~/Documents/
                      /Users/lauri/Documents
                      $ greadlink -f ..
                      /Users
                      $ greadlink -f //etc/..////
                      /private
                      $ greadlink -f /Foo
                      /Foo
                      $ greadlink -f /Foo/foo.txt
                      $


                      This doesn't resolve symlinks, and it doesn't work with /Foo/foo.txt either.



                      abspath() {
                      if [ -d "$1" ]; then
                      ( cd "$1"; dirs -l +0 )
                      else
                      ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
                      fi
                      }

                      abspath /etc # /etc
                      abspath ~/Foo/foo.txt # doesn't work
                      abspath ~/Foo # works
                      abspath .
                      abspath ./
                      abspath ../
                      abspath ..
                      abspath /
                      abspath ~
                      abspath ~/
                      abspath ~/Documents
                      abspath /" '
                      abspath /etc/../etc/
                      abspath /private//etc/
                      abspath /private//
                      abspath //private # //private
                      abspath ./aa.txt
                      abspath aa.tar.gz
                      abspath .aa.txt
                      abspath /.DS_Store
                      abspath ~/Documents/Books/


                      dirs -l performs tilde expansion. dirs +0 prints only the topmost directory if there are other directories in the stack.






                      share|improve this answer






























                        8














                        One option would be to just install coreutils and use greadlink -f. It resolves symlinks and it works with /Foo/ or ~/foo.txt if they don't exist, but not with /Foo/foo.txt if /Foo/ doesn't exist.



                        $ brew install coreutils
                        $ greadlink -f /etc
                        /private/etc
                        $ greadlink -f ~/Documents/
                        /Users/lauri/Documents
                        $ greadlink -f ..
                        /Users
                        $ greadlink -f //etc/..////
                        /private
                        $ greadlink -f /Foo
                        /Foo
                        $ greadlink -f /Foo/foo.txt
                        $


                        This doesn't resolve symlinks, and it doesn't work with /Foo/foo.txt either.



                        abspath() {
                        if [ -d "$1" ]; then
                        ( cd "$1"; dirs -l +0 )
                        else
                        ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
                        fi
                        }

                        abspath /etc # /etc
                        abspath ~/Foo/foo.txt # doesn't work
                        abspath ~/Foo # works
                        abspath .
                        abspath ./
                        abspath ../
                        abspath ..
                        abspath /
                        abspath ~
                        abspath ~/
                        abspath ~/Documents
                        abspath /" '
                        abspath /etc/../etc/
                        abspath /private//etc/
                        abspath /private//
                        abspath //private # //private
                        abspath ./aa.txt
                        abspath aa.tar.gz
                        abspath .aa.txt
                        abspath /.DS_Store
                        abspath ~/Documents/Books/


                        dirs -l performs tilde expansion. dirs +0 prints only the topmost directory if there are other directories in the stack.






                        share|improve this answer




























                          8












                          8








                          8







                          One option would be to just install coreutils and use greadlink -f. It resolves symlinks and it works with /Foo/ or ~/foo.txt if they don't exist, but not with /Foo/foo.txt if /Foo/ doesn't exist.



                          $ brew install coreutils
                          $ greadlink -f /etc
                          /private/etc
                          $ greadlink -f ~/Documents/
                          /Users/lauri/Documents
                          $ greadlink -f ..
                          /Users
                          $ greadlink -f //etc/..////
                          /private
                          $ greadlink -f /Foo
                          /Foo
                          $ greadlink -f /Foo/foo.txt
                          $


                          This doesn't resolve symlinks, and it doesn't work with /Foo/foo.txt either.



                          abspath() {
                          if [ -d "$1" ]; then
                          ( cd "$1"; dirs -l +0 )
                          else
                          ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
                          fi
                          }

                          abspath /etc # /etc
                          abspath ~/Foo/foo.txt # doesn't work
                          abspath ~/Foo # works
                          abspath .
                          abspath ./
                          abspath ../
                          abspath ..
                          abspath /
                          abspath ~
                          abspath ~/
                          abspath ~/Documents
                          abspath /" '
                          abspath /etc/../etc/
                          abspath /private//etc/
                          abspath /private//
                          abspath //private # //private
                          abspath ./aa.txt
                          abspath aa.tar.gz
                          abspath .aa.txt
                          abspath /.DS_Store
                          abspath ~/Documents/Books/


                          dirs -l performs tilde expansion. dirs +0 prints only the topmost directory if there are other directories in the stack.






                          share|improve this answer















                          One option would be to just install coreutils and use greadlink -f. It resolves symlinks and it works with /Foo/ or ~/foo.txt if they don't exist, but not with /Foo/foo.txt if /Foo/ doesn't exist.



                          $ brew install coreutils
                          $ greadlink -f /etc
                          /private/etc
                          $ greadlink -f ~/Documents/
                          /Users/lauri/Documents
                          $ greadlink -f ..
                          /Users
                          $ greadlink -f //etc/..////
                          /private
                          $ greadlink -f /Foo
                          /Foo
                          $ greadlink -f /Foo/foo.txt
                          $


                          This doesn't resolve symlinks, and it doesn't work with /Foo/foo.txt either.



                          abspath() {
                          if [ -d "$1" ]; then
                          ( cd "$1"; dirs -l +0 )
                          else
                          ( cd "$(dirname "$1")"; d=$(dirs -l +0); echo "${d%/}/${1##*/}" )
                          fi
                          }

                          abspath /etc # /etc
                          abspath ~/Foo/foo.txt # doesn't work
                          abspath ~/Foo # works
                          abspath .
                          abspath ./
                          abspath ../
                          abspath ..
                          abspath /
                          abspath ~
                          abspath ~/
                          abspath ~/Documents
                          abspath /" '
                          abspath /etc/../etc/
                          abspath /private//etc/
                          abspath /private//
                          abspath //private # //private
                          abspath ./aa.txt
                          abspath aa.tar.gz
                          abspath .aa.txt
                          abspath /.DS_Store
                          abspath ~/Documents/Books/


                          dirs -l performs tilde expansion. dirs +0 prints only the topmost directory if there are other directories in the stack.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Feb 14 '13 at 16:52

























                          answered Aug 21 '12 at 20:54









                          user495470user495470

                          31k589128




                          31k589128























                              2














                              I guess you could do it with either python or ruby.



                              $ ruby -e 'puts File.expand_path("~/somepath")'


                              or make it a command with



                              #!/usr/bin/env ruby
                              puts File.expand_path(ARGV[0])





                              share|improve this answer
























                              • My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                                – Michael Wehner
                                Nov 1 '10 at 4:57


















                              2














                              I guess you could do it with either python or ruby.



                              $ ruby -e 'puts File.expand_path("~/somepath")'


                              or make it a command with



                              #!/usr/bin/env ruby
                              puts File.expand_path(ARGV[0])





                              share|improve this answer
























                              • My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                                – Michael Wehner
                                Nov 1 '10 at 4:57
















                              2












                              2








                              2







                              I guess you could do it with either python or ruby.



                              $ ruby -e 'puts File.expand_path("~/somepath")'


                              or make it a command with



                              #!/usr/bin/env ruby
                              puts File.expand_path(ARGV[0])





                              share|improve this answer













                              I guess you could do it with either python or ruby.



                              $ ruby -e 'puts File.expand_path("~/somepath")'


                              or make it a command with



                              #!/usr/bin/env ruby
                              puts File.expand_path(ARGV[0])






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 1 '10 at 0:50









                              JayJay

                              5661412




                              5661412













                              • My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                                – Michael Wehner
                                Nov 1 '10 at 4:57





















                              • My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                                – Michael Wehner
                                Nov 1 '10 at 4:57



















                              My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                              – Michael Wehner
                              Nov 1 '10 at 4:57







                              My earlier comment on Daniel Beck's answer applies here as well (I'd prefer a purely Bash-y solution), though if I were to resort to using another language achieve this, I like your solution best so far for its brevity. :) I'd also probably wrap the call to ruby (e.g. function abspath () { ruby -e "puts File.expand_path('$1')"; }) and put it into my `.profile'.

                              – Michael Wehner
                              Nov 1 '10 at 4:57













                              1














                              If you have the File::Spec module installed for perl you can just do this:



                              perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "n"'





                              share|improve this answer




























                                1














                                If you have the File::Spec module installed for perl you can just do this:



                                perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "n"'





                                share|improve this answer


























                                  1












                                  1








                                  1







                                  If you have the File::Spec module installed for perl you can just do this:



                                  perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "n"'





                                  share|improve this answer













                                  If you have the File::Spec module installed for perl you can just do this:



                                  perl -MFile::Spec -e 'print File::Spec->rel2abs("../however/complex/../you/want/to.get"), "n"'






                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Aug 10 '14 at 7:18









                                  DodgerDodger

                                  111




                                  111























                                      0














                                      For bash/sh scripts you can use this recursive function:



                                      canonical_readlink ()
                                      {
                                      cd `dirname $1`;
                                      __filename=`basename $1`;
                                      if [ -h "$__filename" ]; then
                                      canonical_readlink `readlink $__filename`;
                                      else
                                      echo "`pwd -P`";
                                      fi
                                      }

                                      answer=$(canonical_readlink $0)





                                      share|improve this answer
























                                      • Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                        – user495470
                                        Aug 21 '12 at 20:07
















                                      0














                                      For bash/sh scripts you can use this recursive function:



                                      canonical_readlink ()
                                      {
                                      cd `dirname $1`;
                                      __filename=`basename $1`;
                                      if [ -h "$__filename" ]; then
                                      canonical_readlink `readlink $__filename`;
                                      else
                                      echo "`pwd -P`";
                                      fi
                                      }

                                      answer=$(canonical_readlink $0)





                                      share|improve this answer
























                                      • Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                        – user495470
                                        Aug 21 '12 at 20:07














                                      0












                                      0








                                      0







                                      For bash/sh scripts you can use this recursive function:



                                      canonical_readlink ()
                                      {
                                      cd `dirname $1`;
                                      __filename=`basename $1`;
                                      if [ -h "$__filename" ]; then
                                      canonical_readlink `readlink $__filename`;
                                      else
                                      echo "`pwd -P`";
                                      fi
                                      }

                                      answer=$(canonical_readlink $0)





                                      share|improve this answer













                                      For bash/sh scripts you can use this recursive function:



                                      canonical_readlink ()
                                      {
                                      cd `dirname $1`;
                                      __filename=`basename $1`;
                                      if [ -h "$__filename" ]; then
                                      canonical_readlink `readlink $__filename`;
                                      else
                                      echo "`pwd -P`";
                                      fi
                                      }

                                      answer=$(canonical_readlink $0)






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Aug 21 '12 at 17:52









                                      Gregory BurdGregory Burd

                                      1011




                                      1011













                                      • Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                        – user495470
                                        Aug 21 '12 at 20:07



















                                      • Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                        – user495470
                                        Aug 21 '12 at 20:07

















                                      Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                      – user495470
                                      Aug 21 '12 at 20:07





                                      Some variables and command substitutions aren't quoted properly. You could use local variables instead of variable names like __filename. The script currently behaves more like dirname anyway.

                                      – user495470
                                      Aug 21 '12 at 20:07











                                      0














                                      Install the following library for OSX:



                                      brew install coreutils

                                      greadlink -f file.txt





                                      share|improve this answer




























                                        0














                                        Install the following library for OSX:



                                        brew install coreutils

                                        greadlink -f file.txt





                                        share|improve this answer


























                                          0












                                          0








                                          0







                                          Install the following library for OSX:



                                          brew install coreutils

                                          greadlink -f file.txt





                                          share|improve this answer













                                          Install the following library for OSX:



                                          brew install coreutils

                                          greadlink -f file.txt






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Apr 5 '15 at 4:53









                                          anh_ng8anh_ng8

                                          1213




                                          1213























                                              0














                                              If installing coreutils is not an option, the following handles combos of symlinks, . and .. and works on files and folders like GNU realpath does:



                                              #!/usr/bin/env bash
                                              realpath()
                                              {
                                              if ! pushd $1 &> /dev/null; then
                                              pushd ${1##*/} &> /dev/null
                                              echo $( pwd -P )/${1%/*}
                                              else
                                              pwd -P
                                              fi
                                              popd > /dev/null
                                              }


                                              But it does not support realpath's --relative-to. This would require https://stackoverflow.com/a/12498485/869951.






                                              share|improve this answer




























                                                0














                                                If installing coreutils is not an option, the following handles combos of symlinks, . and .. and works on files and folders like GNU realpath does:



                                                #!/usr/bin/env bash
                                                realpath()
                                                {
                                                if ! pushd $1 &> /dev/null; then
                                                pushd ${1##*/} &> /dev/null
                                                echo $( pwd -P )/${1%/*}
                                                else
                                                pwd -P
                                                fi
                                                popd > /dev/null
                                                }


                                                But it does not support realpath's --relative-to. This would require https://stackoverflow.com/a/12498485/869951.






                                                share|improve this answer


























                                                  0












                                                  0








                                                  0







                                                  If installing coreutils is not an option, the following handles combos of symlinks, . and .. and works on files and folders like GNU realpath does:



                                                  #!/usr/bin/env bash
                                                  realpath()
                                                  {
                                                  if ! pushd $1 &> /dev/null; then
                                                  pushd ${1##*/} &> /dev/null
                                                  echo $( pwd -P )/${1%/*}
                                                  else
                                                  pwd -P
                                                  fi
                                                  popd > /dev/null
                                                  }


                                                  But it does not support realpath's --relative-to. This would require https://stackoverflow.com/a/12498485/869951.






                                                  share|improve this answer













                                                  If installing coreutils is not an option, the following handles combos of symlinks, . and .. and works on files and folders like GNU realpath does:



                                                  #!/usr/bin/env bash
                                                  realpath()
                                                  {
                                                  if ! pushd $1 &> /dev/null; then
                                                  pushd ${1##*/} &> /dev/null
                                                  echo $( pwd -P )/${1%/*}
                                                  else
                                                  pwd -P
                                                  fi
                                                  popd > /dev/null
                                                  }


                                                  But it does not support realpath's --relative-to. This would require https://stackoverflow.com/a/12498485/869951.







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Nov 28 '18 at 21:28









                                                  OliverOliver

                                                  1318




                                                  1318























                                                      0














                                                      Given that the constraint is MacOS (OS X at the time), PHP is available by default. This will return the root directory of the file. Remove dirname to get the file, too.



                                                      export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"





                                                      share|improve this answer




























                                                        0














                                                        Given that the constraint is MacOS (OS X at the time), PHP is available by default. This will return the root directory of the file. Remove dirname to get the file, too.



                                                        export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"





                                                        share|improve this answer


























                                                          0












                                                          0








                                                          0







                                                          Given that the constraint is MacOS (OS X at the time), PHP is available by default. This will return the root directory of the file. Remove dirname to get the file, too.



                                                          export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"





                                                          share|improve this answer













                                                          Given that the constraint is MacOS (OS X at the time), PHP is available by default. This will return the root directory of the file. Remove dirname to get the file, too.



                                                          export SOURCE_DIRECTORY="$(php -r 'echo dirname(realpath($argv[1]));' -- "${BASH_SOURCE[0]}")"






                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered Jan 10 at 16:41









                                                          danemacmillandanemacmillan

                                                          1013




                                                          1013






























                                                              draft saved

                                                              draft discarded




















































                                                              Thanks for contributing an answer to Super User!


                                                              • Please be sure to answer the question. Provide details and share your research!

                                                              But avoid



                                                              • Asking for help, clarification, or responding to other answers.

                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                              To learn more, see our tips on writing great answers.




                                                              draft saved


                                                              draft discarded














                                                              StackExchange.ready(
                                                              function () {
                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f205127%2fhow-to-retrieve-the-absolute-path-of-an-arbitrary-file-from-the-os-x%23new-answer', 'question_page');
                                                              }
                                                              );

                                                              Post as a guest















                                                              Required, but never shown





















































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown

































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown







                                                              Popular posts from this blog

                                                              How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                                                              is 'sed' thread safe

                                                              How to make a Squid Proxy server?