Say we have bash file like so:

cd $(dirname "$0");

instead of executing the file directly, what happens when we read the file and then pipe it through bash? How does the "$0" get interpreted?

echo "$(cat <file>)" | bash

The reason I ask is because it seems unclear what the $0 would mean since the file is no longer necessarily running where it once was located. Perhaps somehow bash remembers where it was located and the $0 still refers to the original file location? Seems highly unlikely.

  • Aside: cd $(dirname "$0") should be cd "$(dirname "$0")". But you shouldn't need to do either. If you want to point to other files in the path, try something like mydir="$(dirname "$0")" and then check for existence of "$mydir"/file-i-need. – Wildcard Jun 28 '17 at 2:42
  • well...not really, if there are 4 commands in your shell script that need $0 as their pwd/cwd, then it's just most convenient to cd "$(dirname "$0")"...right? I find it to be a good way to enforce the expected/correct cwd for commands in the script. – Alexander Mills Jun 28 '17 at 2:44
  • 1
    I guess the quotes are important around "$(dirname "$0")" in case there is whitespace in the filepath, is that correct? – Alexander Mills Jun 28 '17 at 2:46
  • how does one downvote such a beautiful question lol – Alexander Mills Jun 28 '17 at 20:07
  • Man pages are not always clear, but on this particular topic, I find the description of $0 quite clear. – Gilles Jun 29 '17 at 22:50

$0 would then be the name by which bash was invoked:

$ printf '%s\n' 'echo $0' | bash
$ printf '%s\n' 'echo $0' | ARGV0=sh bash
$ printf '%s\n' 'echo $0' | ARGV0='blah blah' bash
blah blah

The second and third commands were run in zsh, which lets you set the 0th argument using the special variable ARGV0. But you can simulate that by using symbolic links:

$ ln -s "$(command -v bash)" foo
$ printf '%s\n' 'echo $0' | ./foo

From the bash manual:

($0) Expands to the name of the shell or shell script. This is set at shell initialization. If Bash is invoked with a file of commands (see Shell Scripts), $0 is set to the name of that file. If Bash is started with the -c option (see Invoking Bash), then $0 is set to the first argument after the string to be executed, if one is present. Otherwise, it is set to the filename used to invoke Bash, as given by argument zero.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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