I have a shell script that exports variables to be used in tool setup for a multiuser environment. As different projects (history of 100+ projects) use different setups, my script sets variables for different shell kinds.
Example:
#!/bin/sh
#some XY_VAR setting happening here
case "$1" in
'-c')
echo "setenv XY $XY_VAR;"
;;
'-b')
echo "export XY=$XY_VAR;"
;;
esac
when used in a project's script, it is evaled like this
eval `set_my_vars -c` #when using (t)c-shell
eval `set_my_vars -b` #when using bash
My question is can I make the script detect the shell it is evaled from and input that to the case statement?
ps -hp $$
doesn't work when the script is evaled, this was my first idea (with awk of course). I have found multiple ways where people wanted to detect in which shell they are running in, but all I have found fail when using eval.
Can anybody help? Maybe I am just to stupid to find the solution on my own.
Thanks and best regards rws
$$
refers to the current process; which in your case is the shell that gets spawned by the backticks. So what you need to do is get the pid of the process that spawned the subshell: the parent process. An example might be:
comm=$(ps -ho comm $(ps -ho ppid $$))
echo "echo \"$comm\""
This first runs ps -ho ppid $$
to get the parent pid, and then runs another ps -ho comm
to get the command name from the parent pid.
And then using:
eval `./sourceme`
Will print the expected value:
[~]% eval `./sourceme`
zsh
$ sh
$ eval `./sourceme`
sh
$ csh
% eval `./sourceme`
csh
% bash
[~]$ eval `./sourceme`
bash
[~]$ osh
osh$ eval `./sourceme`
osh
The fish shell requires slightly different syntax though:
osh$ fish
Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish
martin@e585 ~> eval `./sourceme`
fish: Unknown command: `./sourceme`
martin@e585 ~> eval (./sourceme)
fish
I only tested this on Linux; since your ps
example gives an error on my system ("unsupported SysV option") it looks like you're probably not using Linux(or a Linux with a different ps
?) so you may need to frob with the commands a bit, but this should hopefully point you in the right direction.
Also, if you run this through another script you may need to get the parent of the parent.
If you are using Linux then another option would be using the /proc filesystem:
ppid=$(cat "/proc/$$/status" | grep ^PPid: | awk '{print $2}')
comm=$(cat "/proc/$ppid/status" | grep ^Name: | awk '{print $2}')
echo "echo \"$comm\""
But this will only work on Linux. ps
is a bit messy and difficult to use portable, but it's certainly more portable than Linux's procfs.