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
Community
  • 1
  • 1
Bart van Heukelom
  • 43,244
  • 59
  • 186
  • 301

2 Answers2

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
Steve Prentice
  • 23,230
  • 11
  • 54
  • 55
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
Caleb
  • 5,084
  • 1
  • 46
  • 65
  • 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 – Bart van Heukelom Jun 09 '11 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 Jun 09 '11 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. – Bart van Heukelom Jun 09 '11 at 11:44