![]() |
Can a Bash script determine where it is?
Just trying to teach myself some more Unix, so what I'm trying to do is simulate this Applescript with a shellscript:
Code:
on adding folder items to this_folder after receiving added_itemsCode:
#!/bin/bash |
Quote:
|
<smacks head!>I had checked $1 through $9 :o
|
Ok, is this the best way to remove the name and extension of the file 'testshell.sh' from $0?
Code:
t="/tmp/t":o :o :o :o EDIT: Never mind: f=`dirname $0` |
#! /bin/bash
f=$(pwd) # 'pwd' is "present working directory" #all of your code here |
Odd that I didn't see your post even when I posted my edit, but you were 8 minutes before me!
Anyway, pwd returned '/etc' instead of the directory the script is located in. |
How about something along the lines of:
Code:
f=`dirname "$0"` |
Quote:
Anyway looks like the $0 method is the best bet. |
Quote:
|
I used f=`dirname $0` without the double quotes. Do those do anything in this case?
|
$0 only has the name of the script as you ran it. So, it only has the full path if that's the way you ran it. If you just used the short name you won't be able to get the full name while the script is running.
|
Quote:
by typing "./scriptname" while inside the parent (or by typing whatever relative path necessary). So, just typing "scriptname" will typically produce the full path (as it gets looked up in the $PATH). -HI- |
Quote:
If it happened (which isn't often, I admit) that the script had a space (or spaces) in its name... the results would be wrong. If this is a script named "two words"... #!/bin/bash - PATH='/bin:/usr/bin' export PATH IFS=$' \t\n' echo `basename $0` echo `dirname $0` exit ...then, here is the result: $ two\ words two usage: dirname path $ The "two" is the unnoticed error from basename. (The other is obvious). Add quotes around "$0" to get it working. -HI- |
in case this helps someone , I use these varibles in all my scripts.
declare -x SCRIPTPATH="${0}"
declare -x RUNDIRECTORY="${0%%/*}" declare -x SCRIPTNAME="${0##*/}" |
How to find and test the full path of the bash script being executed....
How to find and test the full path of the bash script being executed??? ....
I have not seen an answer to this posted anywhere else online and google brings up this page towards the top of a search, so I thought I better add this for prosperity: myfp=`which $0` mydir=`dirname $myfp` Yes, the "which" command holds the key! :) Also, you can test that a string is a full path by testing if the first character is a "/" or not (on unix) with a test like... if [ "/" == "${mydir:0:1}" ]; then echo "full path = $mydir" fi I like working with full paths for all of my filesystem work... makes debugging easier at least! |
The most reliable indicator of this attribute that I have found is to use LSOF. I tend to care about this on Linux and not OSX, but since this is very high in the google rankings for a search on "bash full path to file" I'm posting it here.
Code:
#!/bin/bashCode:
.oO(apokalyptik@apok-mbp-en.lan ~) uname -a |
One Liner
Try this one:
dir=$(dirname $(which $0)); |
Use of the 'which' command in this context is not useful.
The 'which' command merely looks in the PATH and tells you which version of the command (given as an arg) is first in the PATH. If you ran a script via its full pathname (e.g. /Users/Scripts/foo) then the PATH is irrelevant and so the result of using the 'which' command (as some people have suggested above) can be misleading (e.g. if the PATH does not include /User/Scripts in the above example). |
This is the best way
You can't use $0 because that gives only a relative path if the script is run with a command like ./myscript.sh.
The method below works well for both Linux and Mac OS X. It's a bit weird, but works. Code:
#!/bin/bash |
I would change the line from the previous post:
Code:
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})Code:
abspath="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"Personally I prefer this method compared to the ones, that rely on "lsof -p" or "readlink -f", since it will probably work in a bash shell on almost any platform. |
I have a further requirement. The last few scripts suggested do indeed give the location of the script as it runs.
However if you source the script instead of running it, this gives the current working directory from which you called the script, not the directory in which the script itself resides. Here's the scenario: I have a number of slightly different versions of a project in different folders in my home directory, which I want to compile intermittently. Each version contains certain libraries and output folders which have been hard-coded into the build process (not by me) to be located using environment variables. What I want is to be able to have the same script sit in the top level folder of each of these different project versions, set the relevant paths for that version, relative to that top directory, and add them to the environment before I go to build. Ya dig? Given that I need to source the script instead of having it run in its own execution environment, it seems as if the solutions suggested here fall just short of sufficient (although they are as thorough as any I have seen on this topic). Any further ideas would be gratefully received :-) |
New problem, new thread.
|
I think the following should find a scripts directory path:
path=$(cd ${0%/*} && pwd -P) |
Here is a function I regularly use to change the directory to wherever the script resides.
Code:
WorkDir () |
Quote:
However... i found an (admittedly) obscure way to "break" them all. :) If a symlink is created to the script, and we call upon that symlink... then the parent we wind up with turns out to be the symlink's parent. (maybe that's acceptable on occasion, but probably not in most cases). Adding one more line (and one more variable) handles that potential symlinked scenario... Code:
|
I dug a ton of information and found a simple solution:
Code:
#!/bin/bash |
Quote:
$ cd ~/Desktop $ ../bin/pth ../bin # ^ not an absolute pathname, so... not exactly a sufficient solution. [also doesn't pass the symlink test (see previous post).] |
If you aren't allergic to tcsh, there it is simply $0:h
(More such modifiers are listed on the tcsh man page in the "history substitution" section.) Just as a note, the original poster's application (like many others) doesn't care whether it's a full or relative path, and if he is using this approach in several directories, he would actually be wise to use symbolic links to a single updatable, replaceable script, in which case it should indeed use the directory containing the link, not the directory of the final script. The following works on both Linux and OS X, when a script needs to be in its own directory. Code:
#!/bin/tcsh |
Quote:
>>> Can a Bash script determine where it is? Quote:
Quote:
Quote:
|
The real tricky part is that, because of links (both hard and soft), the concept of "THE name of a file" is a flawed concept. A script can no more tell where it "really is" than where any other file "really" is.
The best it can do is ask what path whoever launched it used to find it. If that path is relative, well, that's what you've got. |
I don't have a Mac but I found this page while looking for the same. This works with Linux. Guess it works on a Mac too.
Code:
#! /bin/bash |
Quote:
|
| All times are GMT -5. The time now is 05:42 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.