Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$0 doesn't work when I source a bash script

Tags:

bash

csh

I have a simple script test.sh

#!/bin/bash
echo $0

When I run the following from csh terminal:

bash -c 'test.sh'

Then the output is test.sh

But when I run:

bash -c 'source test.sh'

The output is bash

Does anybody know how to print the script name in this case?

like image 651
Morad Avatar asked Feb 15 '14 01:02

Morad


3 Answers

#!/bin/bash
declare -r SCRIPT_NAME=$(readlink -f ${BASH_SOURCE[0]})
like image 69
bobah Avatar answered Oct 19 '22 15:10

bobah


Use $BASH_SOURCE. From the man-page:

BASH_SOURCE
       An  array  variable whose members are the source filenames where
       the corresponding shell function names  in  the  FUNCNAME  array  
       variable  are  defined.   The  shell function ${FUNCNAME[$i]} is
       defined  in  the  file  ${BASH_SOURCE[$i]}   and   called   from   
       ${BASH_SOURCE[$i+1]}.

You can simply refer to $BASH_SOURCE instead of ${BASH_SOURCE[0]} since dereferencing an array variable in bash without an index will give you the first element.

This is a common pattern in my scripts to allow different behavior for sourcing versus executing a script:

foo() {
    some cool function
}

if [[ "$BASH_SOURCE" == "$0" ]]; then
    # actually run it
    foo "$@"
fi
like image 8
Aron Griffis Avatar answered Oct 19 '22 13:10

Aron Griffis


When a script is run using source it runs within the existing shell, any variables created or modified by the script will remain available after the script completes. In contrast if the script is run just as filename, then a separate subshell (with a completely separate set of variables) would be spawned to run the script.

Also you want to modify the shell scripts

This can not work for the same reason that you can not use a child shell to modify the enviroment of the parent shell. The environment of the child process is private and cannot affect the environment of its parent.

The only way to accomplish what you are attempting might be to have make compose a standard output stream that contains a list of shell variable assignments. The standard output could then be used as the input to the parent 'source' or '.' command. Using a 'noisy' program such as make to do this will be significantly challenging.

like image 3
Jayesh Bhoi Avatar answered Oct 19 '22 15:10

Jayesh Bhoi