How to execute a command in a different shell? - bash

I have a bash script that opens up a shell called salome shell and it should execute a command called as_run in that shell. The thing is that after entering the salome shell it doesn't execute the command until I exit the salome shell. This is the code that i got:
#!/bin/bash
cd /opt/salome/appli_V2018.0.1_public
./salome shell
eval "as_run /home/students/gbroilo/Desktop/Script/Template_1_2/exportSalome"
What should I do in order to execute the command in the salome shell?

Might be this is what you want:
# call salome shell with commands in a specified script file
cd /opt/salome/appli_V2018.0.1_public
./salome shell <"/home/students/gbroilo/Desktop/Script/Template_1_2/exportSalome"
Or might be this is what you want:
# pipe a command as_run... to salome shell
cd /opt/salome/appli_V2018.0.1_public
echo "as_run /home/students/gbroilo/Desktop/Script/Template_1_2/exportSalome" | ./salome shell
Anyway, you have to read the salome guide about how salome shell call it's script.

Most shells implement a way to pass the commands as parameters, e.g.
dash -c 'x=1 ; echo $x'
You'll need to consult your shell's manual to see if it's possible.
You can also try sending the commands to the standard input of the shell:
echo 'set x = 1 ; echo $x' | tcsh
Using a HERE doc might be a bit more readable in case of complex commands:
tcsh << 'TCSH'
set x = 1
echo $x
TCSH

Related

Use echo options when execution shell script

On mac OSX, I have this script:
#!/usr/local/bin/bash
echo -e "\e[41mError: Some error.\e[0m"
When I just run the echo -e ... in a console, it prints the colored text "Error: Some error."
When executed as a script sh myscript.sh, it litterally prints the flag and the escape characters: -e "\e[41mError: Some error.\e[0m".
When I add the script location to ~/.bash_profile and execute it as myscript.sh, it does work. But I need to be able execute it without adding it to my bash profile.
Edit: using printf works: printf "\e[41mError: Some error.\e[0m\n".
when you run the shell with sh it runs in posix compatibility mode (i.e. as the bourne shell does)
bash is a successor to this shell, one of the features it adds is the -e switch to echo
in posix shell you don't need the -e, the escapes will be evaluated anyway
in bash you do, so if you want to run bash do so explicitly

Definitively determine if currently running shell is bash or zsh

How can I definitively determine if the currently running shell is bash or zsh?
(being able to disambiguate between additional shells is a bonus, but only bash & zsh are 100% necessary)
I've seen a few ways to supposedly do this, but they all have problems (see below).
The best I can think of is to run some syntax that will work on one and not the other, and to then check the errors / outputs to see which shell is running. If this is the best solution, what command would be best for this test?
The simplest solution would be if every shell included a read-only parameter of the same name that identified the shell. If this exists, however, I haven't heard of it.
Non-definitive ways to determine the currently running shell:
# default shell, not current shell
basename "${SHELL}"
# current script rather than current shell
basename "${0}"
# BASH_VERSINFO could be defined in any shell, including zsh
if [ -z "${BASH_VERSINFO+x}" ]; then
echo 'zsh'
else
echo 'bash'
fi
# executable could have been renamed; ps isn't a builtin
shell_name="$(ps -o comm= -p $$)"
echo "${shell_name##*[[:cntrl:][:punct:][:space:]]}"
# scripts can be sourced / run by any shell regardless of shebang
# shebang parsing
On $ prompt, run:
echo $0
but you can't use $0 within a script, as $0 will become the script's name itself.
To find the current shell (let's say BASH) if shebang / magic number executable was #!/bin/bash within a script:
#!/bin/bash
echo "Script is: $0 running using $$ PID"
echo "Current shell used within the script is: `readlink /proc/$$/exe`"
script_shell="$(readlink /proc/$$/exe | sed "s/.*\///")"
echo -e "\nSHELL is = ${script_shell}\n"
if [[ "${script_shell}" == "bash" ]]
then
echo -e "\nI'm BASH\n"
fi
Outputs:
Script is: /tmp/2.sh running using 9808 PID
Current shell used within the script is: /usr/bin/bash
SHELL is = bash
I'm BASH
This will work, if shebang was: #!/bin/zsh (as well).
Then, you'll get the output for SHELL:
SHELL is = zsh
While there is no 100% foolproof way to achieve it, it might help to do a
echo $BASH_VERSION
echo $ZSH_VERSION
Both are shell variables (not environment variables), which are set by the respective shell. In the respective other shell, they are empty.
Of course, if someone on purpose creates a variable of this name, or exports such a variable and then creates a subshell of the different kind, i.e.
# We are in bash here
export BASH_VERSION
zsh # the subshell will see BASH_VERSION even though it is zsh
this approach will fail; but I think if someone is really doing such a thing, he wants to sabotage your code on purpose.
This should work for most Linux systems:
cat /proc/$$/comm
Quick and easy.
Working from comments by #ruakh & #oguzismail, I think I have a solution.
\shopt -u lastpipe 2> /dev/null
shell_name='bash'; : | shell_name='zsh'

Saving the result of an echo command in a shell script?

I am attempting to store the result of an echo command as a variable to be used in a shell script. Debian 4.19.0-6-amd64
The command works in terminal: echo $HOSTNAME returns debian-base, the correct hostname.
I attempt to run it in a shell script, such as:
#!/usr/bin/bash
CURRENT_HOSTNAME=`echo $HOSTNAME`
echo $CURRENT_HOSTNAME
I have tried expansion:
CURRENT_HOSTNAME=$(echo $HOSTNAME)
And just to cover some more bases, I tried things like:
CURRENT_HOSTNAME=$HOSTNAME
# or
CURRENT_HOSTNAME="$HOSTNAME"
# also, in case a problem with reserved names:
test=$HOSTNAME
test="$HOSTNAME"
Works great in the terminal! Output is as follows:
root#debian-base:/scripts# echo $HOSTNAME
debian-base
root#debian-base:/scripts# TEST_HOSTNAME=$HOSTNAME
root#debian-base:/scripts# echo $TEST_HOSTNAME
debian-base
root#debian-base:/scripts# TEST_TWO_HOSTNAME=$(echo $HOSTNAME)
root#debian-base:/scripts# echo $TEST_TWO_HOSTNAME
debian-base
As soon as I run the script (as above):
root#debian-base:/scripts# sh test.sh
root#debian-base:/scripts#
What am I doing wrong?
You are using bash as your terminal. Bash has the variable $HOSTNAME set. You run your script with sh. sh does not have a $HOSTNAME.
Options:
bash test.sh
Or run it as a program:
chmod +x test.sh
./test.sh
But I think you need to change your first line to:
#!/bin/bash
As I don't think bash is installed in /usr/bin in most cases. But you need to try. To figure out where bash is installed use which bash
Another option is to use the hostname binary:
CURRENT_HOSTNAME=$(hostname)
echo $CURRENT_HOSTNAME
Which works in both bash and sh.
You can start sh by just running sh. You will see it has a bash-like terminal. You can try to do echo $HOSTNAME. It will not show, because it's not there. You can use set to see all the variables that are there (as sh does not have tab completion it's harder to figure out).

Entering cshell from bash

I have a bash script and need to run some commands in cshell inside it.
#!/bin/bash
echo entering_to_cshell
csh
echo in_cshell
exit
echo exited_from_cshell
Why doesn't this script run as expected? It only prints entering_to_cshell and it doesn't exit from cshell.
By using
csh
you start a new subshell where your script isn't executed. That's why none of your following commands are executed. Your script waits for this subshell to end which, as you noted, never happens.
Try
csh -c "echo in_cshell"
This way you don't create a new subshell which isn't impacted by your script.
By simply calling csh in your script, you're starting an interactive csh subshell. You'll notice that once you quit from the csh session, your script will then continue to with the subsequent echo and quiting on exit.
To pass a series of commands to csh from you bash script, one approach would be to use the Here Document syntax to redirect commands to csh.
#!/bin/bash
echo entering_to_cshell
csh <<EOF
echo in_cshell
exit
EOF
echo exited_from_cshell
The lines between the EOF entries will be treated as a script that is interpreted by csh.

How to change shells in script

The default shell on the the system is csh but I want to write a script in bash. How do I write a script that will run bash and then convert back to csh at the end.
I tried this but it doesn't work:
bash
var=Hello
echo $var
csh
The command you are looking for is exit. When typing at the keyboard use exit instead of csh to get back to csh. When you enteredcsh, that just started a new csh session on top of the csh and bash sessions already running.
%bash
$ var=Hello
$ echo $var
Hello
$ exit
exit
%
As others have said, when using a script:
#! /bin/bash
var=Hello
echo $var
exit # You don't need exit; but it's okay here.
You don't need to change shells back again. When the script is run, it will be run by a sub-shell (which exits at the end of the script), and the parent shell is unchanged. So, as already suggested, the only thing you have to do is ensure the script is run by the correct shell, and the 'shebang' is the way to do that:
#!/bin/bash
var=Hello
echo $var
That's all it takes.
Define it using the sha bang
#!/bin/bash
at the starting of your file.

Resources