script full name and path $0 not visible when called
Asked Answered
S

4

5

I have a script "task.sh" with the following content:

#!/bin/bash

CUR_DIR=`pwd`
SCRIPTPATH="${CUR_DIR}/`dirname $0`"

when I call it with "bash task.sh" it works as expected but when it is called with ". task.sh"

$ . log/task.sh 
dirname: invalid option -- b
Try `dirname --help' for more information.

When the script is being scheduled in crontab it is not working as well. Can someone tell me what am I doing wrong or a different way in order to get the directory of a script that is not the current directory ?

Schooling answered 18/4, 2011 at 20:13 Comment(1)
Just quick guess: try SCRIPTPATH="${CUR_DIR}/`dirname "$0"`", i.e. quote $0. Besides that, CUR_DIR seems to be redundant here.Brachiate
V
7

When you invoke it as bash task.sh, bash assigns "task.sh" to $0 (from the bash manual: "If Bash is invoked with a file of commands [...] $0 is set to the name of that file.").

When you source the file, bash does not alter $0, it just executes the script in the current environment. What's in $0 in your current enviroment?

$ echo "$0"
-bash

The leading dash will be interpreted by dirname as an option.

If it's in a cron job, why are you sourcing it?

If you need to source your script, this will work if your shell is bash:

SCRIPTPATH="${CUR_DIR}/${BASH_ARGV[0]}"

However, cron's shell is, I believe, /bin/sh. Even if /bin/sh is a symlink to bash, when bash is invoked as sh it will try to behave POSIXly: the BASH_ARGV array probably won't be available to you.

Viridissa answered 18/4, 2011 at 20:28 Comment(1)
Wrote it like this and now working perfect :) CUR_DIR="$PWD" SCRIPTFILE=$0 if [ "${SCRIPTFILE}" = "-bash" ] ; then SCRIPTFILE=${BASH_ARGV[0]} fi SCRIPTPATH="${CUR_DIR}/dirname ${SCRIPTFILE}"Schooling
B
2

I have used this for a long time without issues.

SCRIPTPATH=$(cd `dirname -- $0` && pwd)

The -- disable further processing of parameters.

Bilection answered 5/9, 2018 at 9:15 Comment(0)
C
1

There is no reason to call external binaries such as pwd and dirname when using bash. The functionality of these two binaries can be replicated with pure shell syntax.

Try the following:

#!/bin/bash

CUR_DIR="$PWD"
SCRIPTPATH="${CUR_DIR}/${0#*/}"
Cogan answered 18/4, 2011 at 20:21 Comment(1)
This requires you to be in the same directory as the script when you run it... not ideal.Educatee
S
1

When you type,

bash foo.sh

you are executing script foo.sh, and bash sets the input argument $0 to the name of the script which is being run.

When you type,

. foo.sh

you are sourcing the script and the input argument $0 is not set. In this situation you can use the automatic variable $_ which contains the argument of the last executed command. In your script you could type,

SCRIPTPATH=$(dirname "$_")

to get the path of foo.sh. Notice that, for this to work, this has to be the first command executed in the file. Otherwise $_ will not contain the path of the sourced script.

Kudos to Dennis Williamson for providing this answer to a similar question.

Spacesuit answered 5/3, 2014 at 9:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.