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











up vote
18
down vote

favorite
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






















  • A similar question at Stack Overflow
    – user495470
    Aug 21 '12 at 20:11















up vote
18
down vote

favorite
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






















  • A similar question at Stack Overflow
    – user495470
    Aug 21 '12 at 20:11













up vote
18
down vote

favorite
10









up vote
18
down vote

favorite
10






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 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










8 Answers
8






active

oldest

votes

















up vote
16
down vote













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






























    up vote
    11
    down vote













    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


















    up vote
    8
    down vote













    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






























      up vote
      2
      down vote













      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




















      up vote
      1
      down vote













      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




























        up vote
        0
        down vote













        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


















        up vote
        0
        down vote













        Install the following library for OSX:



        brew install coreutils

        greadlink -f file.txt





        share|improve this answer




























          up vote
          0
          down vote













          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





















            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',
            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

























            8 Answers
            8






            active

            oldest

            votes








            8 Answers
            8






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            16
            down vote













            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



























              up vote
              16
              down vote













              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

























                up vote
                16
                down vote










                up vote
                16
                down vote









                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.6k114762




                15.6k114762










                answered Dec 5 '10 at 16:01









                mschrag

                1612




                1612
























                    up vote
                    11
                    down vote













                    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















                    up vote
                    11
                    down vote













                    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













                    up vote
                    11
                    down vote










                    up vote
                    11
                    down vote









                    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 Beck

                    91.7k12230284




                    91.7k12230284








                    • 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










                    up vote
                    8
                    down vote













                    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



























                      up vote
                      8
                      down vote













                      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

























                        up vote
                        8
                        down vote










                        up vote
                        8
                        down vote









                        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









                        user495470

                        30.8k586125




                        30.8k586125






















                            up vote
                            2
                            down vote













                            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

















                            up vote
                            2
                            down vote













                            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















                            up vote
                            2
                            down vote










                            up vote
                            2
                            down vote









                            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









                            Jay

                            561412




                            561412












                            • 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












                            up vote
                            1
                            down vote













                            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

























                              up vote
                              1
                              down vote













                              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























                                up vote
                                1
                                down vote










                                up vote
                                1
                                down vote









                                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









                                Dodger

                                111




                                111






















                                    up vote
                                    0
                                    down vote













                                    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















                                    up vote
                                    0
                                    down vote













                                    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













                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    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 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










                                    up vote
                                    0
                                    down vote













                                    Install the following library for OSX:



                                    brew install coreutils

                                    greadlink -f file.txt





                                    share|improve this answer

























                                      up vote
                                      0
                                      down vote













                                      Install the following library for OSX:



                                      brew install coreutils

                                      greadlink -f file.txt





                                      share|improve this answer























                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote









                                        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_ng8

                                        1113




                                        1113






















                                            up vote
                                            0
                                            down vote













                                            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

























                                              up vote
                                              0
                                              down vote













                                              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























                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                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 at 21:28









                                                Oliver

                                                1317




                                                1317






























                                                    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.





                                                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                    Please pay close attention to the following guidance:


                                                    • 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

                                                    flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

                                                    Mangá

                                                     ⁒  ․,‪⁊‑⁙ ⁖, ⁇‒※‌, †,⁖‗‌⁝    ‾‸⁘,‖⁔⁣,⁂‾
”‑,‥–,‬ ,⁀‹⁋‴⁑ ‒ ,‴⁋”‼ ⁨,‷⁔„ ‰′,‐‚ ‥‡‎“‷⁃⁨⁅⁣,⁔
⁇‘⁔⁡⁏⁌⁡‿‶‏⁨ ⁣⁕⁖⁨⁩⁥‽⁀  ‴‬⁜‟ ⁃‣‧⁕‮ …‍⁨‴ ⁩,⁚⁖‫ ,‵ ⁀,‮⁝‣‣ ⁑  ⁂– ․, ‾‽ ‏⁁“⁗‸ ‾… ‹‡⁌⁎‸‘ ‡⁏⁌‪ ‵⁛ ‎⁨ ―⁦⁤⁄⁕