Go Back   The macosxhints Forums > OS X Help Requests > UNIX - General



Reply
 
Thread Tools Rate Thread Display Modes
Old 06-16-2007, 10:05 AM   #1
cwtnospam
League Commissioner
 
Join Date: Jan 2005
Posts: 8,182
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_items
	tell application "Finder"
		repeat with aItem in added_items
			if modification date of aItem < (current date) then
				set x to POSIX path of aItem
				set y to "touch -m " & x
				do shell script y
			end if
		end repeat
	end tell
end adding folder items to
Here's what I have:

Code:
#!/bin/bash
a=~
f=$a"/desktop/downloads"
c=$f"/.update.txt"
d=$f"/.update2.txt"
g=$f"/.list1"
h=$f"/.list"
touch -m $h
ls $f > $g
diff $h $g | grep ">" > $c
sed -e 's_>\ _'"$f/"'_g' $c > $d
cp $g $h
sed -e 's/\ /\\\ /g' $d | xargs touch -m
I'd like to replace $f with the path of the script, which would be placed in the folder it is watching.
cwtnospam is offline   Reply With Quote
Old 06-16-2007, 10:26 AM   #2
hayne
Moderator
 
Join Date: Jan 2002
Location: Montreal
Posts: 29,279
Quote:
Originally Posted by cwtnospam
I'd like to replace $f with the path of the script, which would be placed in the folder it is watching.

The variable $0 contains the full path of the script being executed.
__________________
hayne.net/macosx.html
hayne is online now   Reply With Quote
Old 06-16-2007, 11:00 AM   #3
cwtnospam
League Commissioner
 
Join Date: Jan 2005
Posts: 8,182
<smacks head!>I had checked $1 through $9
cwtnospam is offline   Reply With Quote
Old 06-16-2007, 11:30 AM   #4
cwtnospam
League Commissioner
 
Join Date: Jan 2005
Posts: 8,182
Ok, is this the best way to remove the name and extension of the file 'testshell.sh' from $0?

Code:
t="/tmp/t"
echo $0 > $t
f=`sed -e 's_testshell.sh__g' $t`
Can I get $f directly from $0 without using a temp file? I tried using "$0" but that didn't work.


EDIT: Never mind:
f=`dirname $0`

Last edited by cwtnospam; 06-16-2007 at 11:39 AM.
cwtnospam is offline   Reply With Quote
Old 06-16-2007, 11:31 AM   #5
acr4
Prospect
 
Join Date: Jun 2007
Posts: 9
#! /bin/bash
f=$(pwd) # 'pwd' is "present working directory"
#all of your code here
acr4 is offline   Reply With Quote
Old 06-16-2007, 11:51 AM   #6
cwtnospam
League Commissioner
 
Join Date: Jan 2005
Posts: 8,182
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.
cwtnospam is offline   Reply With Quote
Old 06-16-2007, 12:09 PM   #7
biovizier
All Star
 
Join Date: May 2004
Location: london on ca
Posts: 881
How about something along the lines of:
Code:
f=`dirname "$0"`
biovizier is offline   Reply With Quote
Old 06-16-2007, 12:57 PM   #8
acr4
Prospect
 
Join Date: Jun 2007
Posts: 9
Quote:
Originally Posted by cwtnospam
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.

Yeah you're right. Looks like 'pwd' returns the calling path. I.e. if you are in /etc, and you call /home/my.script, 'pwd' in the script will return /etc (or so I gather).

Anyway looks like the $0 method is the best bet.
acr4 is offline   Reply With Quote
Old 06-16-2007, 04:49 PM   #9
Hal Itosis
MVP
 
Join Date: Apr 2002
Posts: 2,114
Quote:
Originally Posted by biovizier
How about something along the lines of:
Code:
f=`dirname "$0"`

Those "lines" would be the fewest.
Hal Itosis is offline   Reply With Quote
Old 06-16-2007, 04:53 PM   #10
cwtnospam
League Commissioner
 
Join Date: Jan 2005
Posts: 8,182
I used f=`dirname $0` without the double quotes. Do those do anything in this case?
cwtnospam is offline   Reply With Quote
Old 06-16-2007, 08:24 PM   #11
ataraxia
Major Leaguer
 
Join Date: Aug 2004
Location: Pittsburgh
Posts: 349
$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.
ataraxia is offline   Reply With Quote
Old 06-17-2007, 04:40 PM   #12
Hal Itosis
MVP
 
Join Date: Apr 2002
Posts: 2,114
Quote:
Originally Posted by ataraxia
$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.

You would need to bypass the $PATH mechanism
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-

Last edited by Hal Itosis; 06-17-2007 at 05:13 PM.
Hal Itosis is offline   Reply With Quote
Old 06-17-2007, 05:02 PM   #13
Hal Itosis
MVP
 
Join Date: Apr 2002
Posts: 2,114
Quote:
Originally Posted by cwtnospam
I used f=`dirname $0` without the double quotes. Do those do anything in this case?


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-

Last edited by Hal Itosis; 06-17-2007 at 05:07 PM.
Hal Itosis is offline   Reply With Quote
Old 07-08-2007, 04:38 PM   #14
Acidprime
Prospect
 
Join Date: Nov 2005
Posts: 5
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##*/}"

Last edited by Acidprime; 07-08-2007 at 04:45 PM.
Acidprime is offline   Reply With Quote
Old 11-28-2007, 09:43 AM   #15
bwiese
Registered User
 
Join Date: Nov 2007
Posts: 1
Thumbs up 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!
bwiese is offline   Reply With Quote
Old 03-02-2008, 10:59 PM   #16
apokalyptik
Registered User
 
Join Date: Mar 2008
Posts: 1
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/bash
## Linux
LSOF=$(lsof -p $$ | grep -E "/"$(basename $0)"$")
MY_PATH=$(echo $LSOF | sed -r s/'^([^\/]+)\/'/'\/'/1 2>/dev/null)
if [ $? -ne 0 ]; then
## OSX
  MY_PATH=$(echo $LSOF | sed -E s/'^([^\/]+)\/'/'\/'/1 2>/dev/null)
fi

MY_PID=$$
MY_ROOT=$(dirname $MY_PATH)
MY_NAME=$(basename $0)

echo -e "PATH\t$MY_PATH"
echo -e "FILE\t$MY_NAME"
echo -e "CWD \t$MY_ROOT"
echo -e "PID \t$MY_PID"
Code:
.oO(apokalyptik@apok-mbp-en.lan ~) uname -a
Darwin apok-mbp-en.lan 9.2.0 Darwin Kernel Version 9.2.0: Tue Feb  5 16:13:22 PST 2008; root:xnu-1228.3.13~1/RELEASE_I386 i386 i386
.oO(apokalyptik@apok-mbp-en.lan ~) ./foo.sh 
PATH    /Users/apokalyptik/foo.sh
FILE    foo.sh
CWD     /Users/apokalyptik
PID     16347
apokalyptik is offline   Reply With Quote
Old 09-10-2008, 02:58 PM   #17
Abu
Registered User
 
Join Date: Sep 2008
Posts: 1
One Liner

Try this one:

dir=$(dirname $(which $0));
Abu is offline   Reply With Quote
Old 09-20-2008, 11:35 AM   #18
hayne
Moderator
 
Join Date: Jan 2002
Location: Montreal
Posts: 29,279
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).
__________________
hayne.net/macosx.html
hayne is online now   Reply With Quote
Old 11-14-2008, 09:57 AM   #19
chriswaco
Prospect
 
Join Date: Nov 2008
Posts: 1
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
#==========================
# bash - find path to script
#==========================
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})

# to get the path only - not the script name - add
path_only=`dirname "$abspath"`

#display the paths to prove it works
echo $abspath
echo $path_only
chriswaco is offline   Reply With Quote
Old 03-13-2009, 12:44 AM   #20
LN2
Registered User
 
Join Date: Mar 2009
Posts: 1
I would change the line from the previous post:
Code:
abspath=$(cd ${0%/*} && echo $PWD/${0##*/})
to

Code:
abspath="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"
This covers the case if the script was started with something like "bash yourscript.sh", which otherwise gives an error. It also adds some Quotes just to be on the save side if your $PWD contains /newlines or other 'ugly' characters.

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.
LN2 is offline   Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 03:56 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Site design © Mac Publishing LLC; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of Mac Publishing LLC.
You Rated this Thread: