$MYTESTVAR line correctly returns hello world.
$PS1 does not show up.
Indeed, you're right. Most variables work fine, but "PS1" in particular fails:
$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 and $TEST1`'
and test1
Why is this?
In Ruby, as you're probably aware, `somestring` executes somestring in a shell, as if you in C had opened a pipe to execl("/bin/sh", "-c", somestring, NULL).
On many systems, /bin/sh is provided by bash. Bash has this snippet in its initialization code:
/* Execute the start-up scripts. */
if (interactive_shell == 0)
{
unbind_variable ("PS1");
unbind_variable ("PS2");
interactive = 0;
In other words, it explicitly removes "PS1" and "PS2" because these variables are only intended for use with interactive shells.
On other systems where /bin/bash is provided by dash, as many modern Debian-based distros default to, you instead get the result you expected:
$ PS1=ps1 TEST1=test1 ruby -e 'puts `echo $PS1 $TEST1`'
ps1 and test1
The reason why your `source ~/.bash_profile` doesn't fix this is that each `backtick command` runs in a separate shell. Variables set in one is not reflected in the other.
If you just want the variable as exported by your shell, you should do what @anujm suggests and get it directly with ENV['PS1']. Not only is this easier and more robust, it's also a thousand times faster.
If you want the variable as set in your .bash_profile, regardless of how you ran your script, you can do both sourcing and printing in the same shell:
puts `bash -c 'source ~/.bash_profile; printf "%s" "$PS1"'`