Every process on Linux systems has one input (stdin) and two outputs (stdout, stderr) by default. Terminals take input from the keyboard and send it to stdin of the shell that they run, and take stdout and stderr from the process and print it to the screen.
When you run a command in the shell (in a terminal), it links its own stdin to that of the process, so any keys you type are sent to the command. It also links their stdout and stderr to its own (which the terminal then prints to the screen). The same thing happens when you run a command inside a script, stdin, stdout, and stderr are linked to that of the parent process, these eventually propagate up to the terminal.
Also, commands in scripts are blocking by default. They will only execute the next command once the one they are running has finished.
Given these let's look at your script (simplifying to the two lines of interest):
sh script2.sh
echo ".open Simulation\n"
What this does is it run sh (which run script2.sh) and attaches its stdin to that of the script and blocks waiting for it to end. The second line will not run until the first process has ended.
Now, anything you type into the shell, for example .open Simulation\n
will get send to sh which will send it to your script2.sh
. Once (if ever) your script2.sh
has finished it will exit and your main script will echo .open Simulation\n
to the shell and exit.
Now we know what's going on. How can we fix it? Well you can override the default attaching of stdin, stdout and stderr to where ever you want, including files or other processes. To do this the shell has to powerful utilities, input/output redirection and command pipes.
I/O redirections allow you to redirect input/output to any file decipher you wish for example:
echo "contents of a file" > somefile.txt
This will write contents of a file
to somefile.txt
by redirecting stdout of the echo command to somefile.txt
. Input redirection works the same way:
cat < somefile.txt
Will print the contents of the file to the screen by redirecting cats stdin to read from somefile.txt
(note that this is a contrived example, most people will just cat somefile.txt
which causes cat to read somefile.txt itself rather than getting the shell to do it.)
Next there are command pipes, these allow you to connect stdout of one program to stdin of another. This sounds like what you want, send the output of echo into stdin of your script:
echo ".open Simulation" | sh script2.sh
Now this works well for simple input, but if you have more than a couple of lines there is an easier way; Heredocs. For example to pipe multiple lines into your script you can
sh script2.sh <<EOD
.open Simulation
.do something
.end Simulation
EOD
Which will send the three line (not including the EOD) to your script ready for your script to processes. If you need to do anything more advanced you can use subcommand redirection as well, which will allow you to redirect the output of a subshell into your program, here with a sleep 1 between each line:
sh script2.sh <(
echo ".open Simulation"
sleep 1
echo ".do something"
sleep 1
echo ".end Simulation"
)
In this example your script will see .open Simulation
straight away, then after a second it will get .do something
then after another second .end Simulation
before stdin is closed.
script2.sh
do something to allow script1 to continue executing? Otherwise you're never getting to theecho
statement because the script is waiting forscript2.sh
to terminate before moving on to the next step