8

How can I get the directory a bash script file is in, when that script file is included from another (which makes it different from this question)?

/script1.sh

. /dir2/script2.sh

/dir2/script2.sh

# echoes "/dir2"
echo whatevergetsthatdir

This is the script I'm trying to "fix"

/etc/init.d/silvercar-gameserver (unique for every instance)

#!/bin/bash
#
#       /etc/rc.d/init.d/silvercar-gameserver
#
#       Initscript for silvercar game server
#
# chkconfig: 2345 20 80
# description: lalalalala

#CONFIG
BIN=/opt/silvercar-gameserver # Want to get rid of this
CONF=/etc/opt/silvercar-gameserver

. /etc/init.d/functions
. $BIN/gameserver.sh.inc

exit 0

/opt/silvercar-gameserver/gameserver.sh.inc (not to be changed for each install. is in svn)

# Meant to be included from a script in init.d
# Required input:
#  CONF (e.g. /etc/opt/silvercarserver)


# -- Installation config (must provide JSVC, JAVA_HOME)
. $BIN/localconf.sh

# -- Instance config (must provide ASUSER, ASWORK)
. $CONF/conf.sh

PIDFILE=$ASWORK/running.pid
LOGDIR=$ASWORK/log
CLASS=tr.silvercar.gameserver.runner.DaemonGameServer
ARGS=$CONF

start() {
    echo "Going to start Gameserver..."

    export JAVA_HOME
    cd $BIN
    $JSVC -jvm server -procname silvercar-gameserver -pidfile $PIDFILE -user $ASUSER -outfile $LOGDIR/stdout -errfile $LOGDIR/stderr \
             -cp `cat classpath` -Dlogroot=$LOGDIR $CLASS $ARGS

    echo "Gameserver started!"
}

stop() {
    echo "Going to stop Gameserver..."
    $JSVC -stop -pidfile $PIDFILE $CLASS
    echo "Gameserver stopped!"
}

case "$1" in
    start)        
        start          
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: /etc/init.d/silvercar-gameserver {start|stop|restart}"
        exit 1
        ;;
esac
2
  • 1
    You already know the directory - it's /dir2.
    – user2100815
    Commented Jun 9, 2011 at 11:12
  • @Neil Apart from the fact that the sample above is, well, just a sample, I know that, but script2 doesn't. Commented Jun 9, 2011 at 11:32

2 Answers 2

6

If you have bash 3.0 or newer, you can use BASH_SOURCE to get exactly what you need without relying on the calling program to set any environment variables for you. See below for an example:

#test.sh
source some_directory/script2.sh

#some_directory/script2.sh
echo $BASH_SOURCE
echo $(dirname $BASH_SOURCE)

The output will be:

$ ./test.sh
some_directory/script2.sh
some_directory
5

In order to source the file, the parent script obviously knows the path where the child script is. Set it as a variable, then in the child script check for that variable. If it is available you know it's been sourced and you can use that path, otherwise use the normal trick in the question you linked.

# script1.sh
RESOURCE_DIR=/dir2
source $RESOURCE_DIR/script2.sh

# script2.sh
if [ -z "$RESOURCE_DIR"]; then
  echo $RESOURCE_DIR
else
  echo $(dirname $0)
fi
3
  • 1
    That's what I do know and it work well enough. I'd just like to remove that variable from script1 if possible, which will cut its size by about 30% :P Commented Jun 9, 2011 at 11:33
  • Get over it :) Actually if that's 30% of your script1 then you're probably not using source appropriately. Why the wrapper script at all?
    – Caleb
    Commented Jun 9, 2011 at 11:35
  • Oh well, I'll just let the $BIN stay. Would've been nice if this was possible though. I admit it's not necessary in this case, but it might come in handy in some. Commented Jun 9, 2011 at 11:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.