{"id":152,"date":"2013-06-28T08:39:35","date_gmt":"2013-06-28T12:39:35","guid":{"rendered":"http:\/\/www.mbeckler.org\/blog\/?p=152"},"modified":"2013-06-28T12:00:01","modified_gmt":"2013-06-28T16:00:01","slug":"bash-script-pwd-vs-true-script-location-with-symlinks","status":"publish","type":"post","link":"https:\/\/www.mbeckler.org\/blog\/?p=152","title":{"rendered":"Bash script: PWD vs true script location, with symlinks"},"content":{"rendered":"<p>I recently needed to keep a Bash script in a centralized location, with many symbolic links to that script sprinkled throughout my repository. I wanted the script be able to determine both the user&#8217;s PWD, as well as the true location of the script. Based on all the different suggestions found online, I created a little test script to see how well each suggestion worked:<\/p>\n<pre lang=\"bash\">#!\/bin\/bash\r\n\r\necho \"\\$0\"\r\necho $0\r\necho \"\"\r\n\r\necho \"pwd -P\"\r\npwd -P\r\necho \"\"\r\n\r\necho \"pwd -L\"\r\npwd -L\r\necho \"\"\r\n\r\necho \"which \\$0\"\r\nwhich $0\r\necho \"\"\r\n\r\necho \"readlink -e \\$0\"\r\nreadlink -e $0\r\necho \"\"\r\n\r\necho \"readlink -e \\$BASH_SOURCE\"\r\nreadlink -e $BASH_SOURCE\r\necho \"\"<\/pre>\n<p>I put this script (test.sh) in ~\/ and then created a symlink to it in a different directory. Here are the results.<\/p>\n<p><strong style=\"color: red;\">My friend JT left a comment below to say that using $BASH_SOURCE is probably the better choice than using $0, since $0 can be changed, and is only set equal to the file name by convention.<\/strong><\/p>\n<p><strong>Directly calling the script from the same directory (\/home\/matthew\/):<\/strong><\/p>\n<pre>matthew@broderick:~$ .\/test.sh\r\n$0\r\n.\/test.sh\r\n\r\npwd -P\r\n\/home\/matthew\r\n\r\npwd -L\r\n\/home\/matthew\r\n\r\nwhich $0\r\n.\/test.sh\r\n\r\nreadlink -e $0\r\n\/home\/matthew\/test.sh<\/pre>\n<p><strong>Directly calling the script from some other directory (\/some\/other\/directory\/):<\/strong><\/p>\n<pre>matthew@broderick:~\/some\/other\/directory$ ~\/test.sh\r\n$0\r\n\/home\/matthew\/test.sh\r\n\r\npwd -P\r\n\/home\/matthew\/some\/other\/directory\r\n\r\npwd -L\r\n\/home\/matthew\/some\/other\/directory\r\n\r\nwhich $0\r\n\/home\/matthew\/test.sh\r\n\r\nreadlink -e $0\r\n\/home\/matthew\/test.sh<\/pre>\n<p><strong>Creating a symlink to ~\/test.sh in ~\/some\/other\/directory, and calling it directly (.\/test.sh):<\/strong><\/p>\n<pre>matthew@broderick:~\/some\/other\/directory$ ln -s ~\/test.sh .\/test.sh\r\nmatthew@broderick:~\/some\/other\/directory$ .\/test.sh\r\n$0\r\n.\/test.sh\r\n\r\npwd -P\r\n\/home\/matthew\/some\/other\/directory\r\n\r\npwd -L\r\n\/home\/matthew\/some\/other\/directory\r\n\r\nwhich $0\r\n.\/test.sh\r\n\r\nreadlink -e $0\r\n\/home\/matthew\/test.sh<\/pre>\n<p><strong>Creating a symlink to ~\/test.sh in ~\/some\/other\/directory, and calling it from yet another location:<\/strong><\/p>\n<pre>matthew@broderick:~\/some\/other\/directory$ ln -s ~\/test.sh .\/test.sh\r\nmatthew@broderick:~\/some\/other\/directory$ cd ~\/somewhere\/else\r\nmatthew@broderick:~\/somewhere\/else$ ~\/some\/other\/directory\/test.sh\r\n$0\r\n\/home\/matthew\/some\/other\/directory\/test.sh\r\n\r\npwd -P\r\n\/home\/matthew\/somewhere\/else\r\n\r\npwd -L\r\n\/home\/matthew\/somewhere\/else\r\n\r\nwhich $0\r\n\/home\/matthew\/some\/other\/directory\/test.sh\r\n\r\nreadlink -e $0\r\n\/home\/matthew\/test.sh<\/pre>\n<p><strong>Conclusion:<\/strong><br \/>\nSo, it looks like &#8220;readlink -e $0&#8221; will always return the full, non-symlink, &#8220;physical&#8221; location of the script (regardless of whether or not symlinks are involved). Looks like &#8220;pwd&#8221; returns the user&#8217;s current working directory reliably.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently needed to keep a Bash script in a centralized location, with many symbolic links to that script sprinkled throughout my repository. I wanted the script be able to determine both the user&#8217;s PWD, as well as the true location of the script. Based on all the different suggestions found online, I created a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[52,59,10,57,58,7],"class_list":["post-152","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-bash","tag-herebedragons","tag-linux","tag-scripting","tag-symlinks","tag-unix"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2BznB-2s","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=152"}],"version-history":[{"count":8,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions"}],"predecessor-version":[{"id":160,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=\/wp\/v2\/posts\/152\/revisions\/160"}],"wp:attachment":[{"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mbeckler.org\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}