bash script order of execution - bash

Do lines in a bash script execute sequentially? I can't see any reason why not, but I am really new to bash scripting and I have a couple commands that need to execute in order.
For example:
#!/bin/sh
# will this get finished before the next command starts?
./someLongCommand1 arg1
./someLongCommand2 arg1

Yes, they are executed sequentially. However, if you run a program in the background, the next command in your script is executed immediately after the backgrounded command is started.
#!/bin/sh
# will this get finished before the next command starts?
./someLongCommand1 arg1 &
./someLongCommand2 arg1 &
would result in an near-instant completion of the script; however, the commands started in it will not have completed. (You start a command in the background by putting an ampersand (&) behind the name.

Yes... unless you go out of your way to run one of the commands in the background, one will finish before the next one starts.

Related

Bash script is waiting to open second file in gedit until I close the first one [duplicate]

When running commands from a bash script, does bash always wait for the previous command to complete, or does it just start the command then go on to the next one?
ie: If you run the following two commands from a bash script is it possible for things to fail?
cp /tmp/a /tmp/b
cp /tmp/b /tmp/c
Yes, if you do nothing else then commands in a bash script are serialized. You can tell bash to run a bunch of commands in parallel, and then wait for them all to finish, but doing something like this:
command1 &
command2 &
command3 &
wait
The ampersands at the end of each of the first three lines tells bash to run the command in the background. The fourth command, wait, tells bash to wait until all the child processes have exited.
Note that if you do things this way, you'll be unable to get the exit status of the child commands (and set -e won't work), so you won't be able to tell whether they succeeded or failed in the usual way.
The bash manual has more information (search for wait, about two-thirds of the way down).
add '&' at the end of a command to run it parallel.
However, it is strange because in your case the second command depends on the final result of the first one. Either use sequential commands or copy to b and c from a like this:
cp /tmp/a /tmp/b &
cp /tmp/a /tmp/c &
Unless you explicitly tell bash to start a process in the background, it will wait until the process exits. So if you write this:
foo args &
bash will continue without waiting for foo to exit. But if you don't explicitly put the process in the background, bash will wait for it to exit.
Technically, a process can effectively put itself in the background by forking a child and then exiting. But since that technique is used primarily by long-lived processes, this shouldn't affect you.
In general, unless explicitly sent to the background or forking themselves off as a daemon, commands in a shell script are serialized.
They wait until the previous one is finished.
However, you can write 2 scripts and run them in separate processes, so they can be executed simultaneously. It's a wild guess, really, but I think you'll get an access error if a process tries to write in a file that's being read by another process.
I think what you want is the concept of a subshell. Here's one reference I just googled: http://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/subshells.html

How to prevent nohup from "clogging" the command line?

I want to write a bash script that runs two commands in the background. I am using nohup for this:
nohup cmd1 &
nohup cmd2 &
However, only the 1st command runs in the background.
When I run nohup cmd1 & manually in the command line. First, I type nohup cmd1 & then hit enter; this starts the process:
But, then I need to hit enter again to be able to type another command:
I think this is "clogging" up the command line, and is causing my bash script to get stuck at the first nohup ... & command.
Is there a way to prevent this?
Nothing is "clogged". The first command, running in the background, prints some output after your shell prints its next prompt. The shell is waiting for you to type a command, even though the cursor is no longer on the same line as the prompt. That extra Enter is an empty command, causing the shell to print another prompt. It's harmless but unnecessary.
Let me say something to nohup because I'm not sure if you are certain about what it is doing. In short, the nohup command is not necessary to run a process in background. The ampersand at the end of the line is doing it.
nohup prevents the background process from receiving SIGHUP (hup for hang up) if you close the terminal where the starting shell runs it. SIGHUP would effectively terminate the process.
If started with nohup the process will not receive that event and will continue running, owned by the init process (pid 1) if the terminal will being closed.
Furthermore the nohup command will redirect standard output of the controlled process to a file, meaning it will not appear on screen any more. By default this file is called nohup.out.

Call and start in shell

If I want to call another batch script from within a batch script I could use
CALL File.bat
to pause the execution of the current batch file and wait for the CALLed script to complete.
I can use
START File.bat
if I want them to run simultaneously.
How do I achieve this behavior in a shell script??
If you want to wait:
#!/bin/bash
# do some stuff
/path/to/other/script
# do other stuff
To run it simultaneously (i.e. "in the background"):
#!/bin/bash
# do some stuff
/path/to/other/script &
# do other stuff, then optionally:
wait
# this will wait for all background jobs to finish
There are other ways, and certain things you should consider about input and output redirection for the background process if you want to provide specific input and/or capture output or errors, but that's the basics.
By “shell“, I assume you mean *NIX sh.
To execute another script and wait for it to complete, do
sh file.sh
To start it in background, do
(sh file.sh) &
For bash (and other Bourne shell-compatible shells):
you don't need CALL; invoking another script or program executes it synchronously. someprog.sh
you append & to a command to run it asynchronously; note that the program will halt if it attempts to read from stdin if it's in the background. someprog.sh &

How do I launch a program inside a shell script and have the shell script continue, even though the program remains open

I am using bash on Ubuntu. I would like to have a shell script open a program and continue on to the next line of the shell script, even though the program has not terminated.
Adding an & to a command places it in background.
example:
/path/to/foo
/path/to/bar # not executed untill foo is done
/path/to/foo & # in background
/path/to/bar & # executes as soon as foo is started
Read more about job-control here and here
Use something like this (my-long-running-process &) . This will launch your script as a separate process in the background.
You must run the process in the background, but you must enable job-control first. Otherwise, you cannot kill or bring the process to foreground if desired.
To enable job-control, execute:
set -m
To run some task in the background, execute:
task &
To manipulate the background task, use the jobspec syntax (%[n]). For example, to kill the last launched process, execute:
kill %
Note that enabling job-control is required only if you're actually running a script (as stated in the question). If running interactively, job-control is already enabled by default.
The manpage for bash has much more information in the JOB CONTROL section.
http://ubuntuforums.org/showthread.php?t=1657602
It looks like all you have to do is add a & at the end of the line.

Is it possible for bash commands to continue before the result of the previous command?

When running commands from a bash script, does bash always wait for the previous command to complete, or does it just start the command then go on to the next one?
ie: If you run the following two commands from a bash script is it possible for things to fail?
cp /tmp/a /tmp/b
cp /tmp/b /tmp/c
Yes, if you do nothing else then commands in a bash script are serialized. You can tell bash to run a bunch of commands in parallel, and then wait for them all to finish, but doing something like this:
command1 &
command2 &
command3 &
wait
The ampersands at the end of each of the first three lines tells bash to run the command in the background. The fourth command, wait, tells bash to wait until all the child processes have exited.
Note that if you do things this way, you'll be unable to get the exit status of the child commands (and set -e won't work), so you won't be able to tell whether they succeeded or failed in the usual way.
The bash manual has more information (search for wait, about two-thirds of the way down).
add '&' at the end of a command to run it parallel.
However, it is strange because in your case the second command depends on the final result of the first one. Either use sequential commands or copy to b and c from a like this:
cp /tmp/a /tmp/b &
cp /tmp/a /tmp/c &
Unless you explicitly tell bash to start a process in the background, it will wait until the process exits. So if you write this:
foo args &
bash will continue without waiting for foo to exit. But if you don't explicitly put the process in the background, bash will wait for it to exit.
Technically, a process can effectively put itself in the background by forking a child and then exiting. But since that technique is used primarily by long-lived processes, this shouldn't affect you.
In general, unless explicitly sent to the background or forking themselves off as a daemon, commands in a shell script are serialized.
They wait until the previous one is finished.
However, you can write 2 scripts and run them in separate processes, so they can be executed simultaneously. It's a wild guess, really, but I think you'll get an access error if a process tries to write in a file that's being read by another process.
I think what you want is the concept of a subshell. Here's one reference I just googled: http://www.linuxtopia.org/online_books/advanced_bash_scripting_guide/subshells.html

Resources