Why does a subshell of an interactive shell run as an interactive shell? - bash

With my Bash session, I run this command:
(echo $$ $BASHPID $-)
and I get
22108 25602 himBH
So, my subshell runs as an interactive shell.
If I try to run the same command in background
(echo $$ $BASHPID $-) &
I get the same output. Why does the subshell run as an interactive shell?

A subshell inherits all the characteristics of the parent, and that includes settings. That's part of the definition of a subshell. It makes no difference if it is running in foreground or background - jobs can be swapped between foreground and background quite easily.
A non-subshell will not be interactive. For example, if I put
(echo $$ $BASHPID $-)
into a script called gash.sh and call it from a non-interactive shell:
$ bash gash.sh
73879 73880 hB
But if I source the file, then it is a subshell of an interactive shell:
$ . ./gash.sh
1130 himBH

Related

Multiple running bash script 1 command line?

how to run multiple bash scripts in 1 bash command ?
i use command
bash script1.sh
how to make it run multiple commands in 1 command ?
for example
bash script1.sh bash script2.sh bash script3.sh bash script4.sh
Please help
If you want to run all bash script in //:
for i in {1..4}; do bash "script${i}.sh" & done
If you put the control operator & at the end of a command, e.g. command &, the shell executes the command in the background in a subshell. The shell does not wait for the command to finish, and the return status is 0. Pid of the last backgrounded command is available via the special variable $!
If instead you want to run sequentially, use
printf '%s\n' script{1..4}.sh | xargs -n1 bash
or
for i in {1..4}; do bash "script${i}.sh"; done

command invoking new shell and script is broken

I have two commands:
/aka/ball/barry/pet elephant/rhino
which invoke new shell and I have command
cleartool setview "/view/epp/lpp/tpp.sh" $VIEW
which also invoke new shell. Is it possible to run both in a single script one by one?
Probably; although it depends. If these shells are designed to be interactive, you can still probably make them work by sending them commands to end the subshells, such as exit 0:
$ /aka/ball/barry/pet elephant/rhino <<< 'exit 0'
If that successfully exits the shell, you can just do it in serial:
#!/bin/bash
##
# Your script?
…stuff
/aka/ball/barry/pet elephant/rhino <<< 'exit 0'
cleartool setview "/view/epp/lpp/tpp.sh" "$VIEW" <<< 'exit 0'
…morestuff
Without knowing more about the nature of the shells these programs invoke, it's hard to say for sure.

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.

What starts new subshell in Bash?

Are there actions in Bash other than pipes and command substitution that start a new subshell?
Putting a command chain in parens (( ... )) also starts a new subshell.
( cd /tmp ; pwd ) ; pwd
Each shell script running is, in effect, a subprocess (child process) of the parent shell.
A shell script can itself launch subprocesses. These subshells let the script do parallel processing, in effect executing multiple subtasks simultaneously.
say you have script test.sh. After you run it if you run the command
ps -ef|grep -i test.sh
you will see the it runs with different PID
In general, an external command in a script forks off a subprocess/subshell

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