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

5

12

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?

Conlan answered 15/2, 2014 at 1:13 Comment(5)
You could do something like ps -o "%a" -p "$$" rather than echo $0 and parse output, but not really sure why you're trying to have the same behavior while sourcing the file.Broadcast
What is the purpose of sourcing when you're invoking an entirely new shell?Dneprodzerzhinsk
I'm exporting environment variables in my script. I want to source it from csh terminal so I run: bash -c 'source test.sh; exec csh'Conlan
That won't work -- when you use the bash command, that creates a subprocess, so any environment variables it defines will not be part of the calling script's environment. (BTW, the bash -c 'test.sh' version actually creates two subprocesses.) There is inherently no way to source a bash script from csh -- the point of source is that it runs the script in the same shell (rather than a subshell), and bash just isn't the same shell as csh.Urial
So the only way to reach this is to rewrite the script in c-shell?Conlan
D
10
#!/bin/bash
declare -r SCRIPT_NAME=$(readlink -f ${BASH_SOURCE[0]})
Desiree answered 15/2, 2014 at 12:35 Comment(0)
D
8

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
Domitiladomonic answered 15/2, 2014 at 12:36 Comment(0)
A
3

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.

Ascomycete answered 15/2, 2014 at 5:26 Comment(0)
D
2

If, from csh, youre trying to reach session variables defined in a bash shell script, you must call the bash script prior to starting up the csh.

A session gets inherited into subprocesses, like so, where the csh.SESSION and csh.SESSION_INHERITED are merged once the csh 'boots':

bash/
├── csh
│   ├── SESSION
│   └── SESSION_INHERITED
└── SESSION

The bash.SESSION is NOT accessible from within csh shell as this would expose the init runlevel to any subprocesses.. Its is a fork, which during spawn duplicates the environment.

So, you can run from bash: source test.sh; csh. This will expose the exports from test.sh to csh - but its a static export which cannot be modified programatically in the csh.

Haven't 100% understood your question since its very abstract.. But this hopefully helps :)

Doubledealing answered 15/2, 2014 at 12:29 Comment(0)
C
0

when you use source or . , you run the script in this Shell. Your script share variables with the Shell, including the $0. When you run the Shell, you typed in 'bash', so the $0 is bash, and the script use it. That's why it shows bashstrong text. If you want a new $0, use './script_name.sh' instead!

Calamanco answered 27/9, 2020 at 14:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.