What is the difference between & and | in linux? - linux

I understand | pipes the output of the first command into the stdin of the second command. How does & relate two processes?

Probably you want to know about && not & (which is for executing a command in background)
This command:
command1 | command2
Means pass output of command1 as input (stdin) of command2
But in this command:
command1 && command2
Means execute command2 ONLY if command1 is successful

Single amperstand (&) is used for backgrounding. It makes the command run in the background.
Also from man bash :
If a command is terminated by the control operator &, 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.
So if you write something like this:
find -name hello &
This will make the find command to be forked and run in the background
In your case single amperstand & does not relate to the two process in any way.
You are probably looking for
command1 && command2

& does not relate two processes in any way; it starts a process in the "background" so that the shell you are running continues its work without waiting for the process to terminate like it normally would.
You are probably thinking of &&. The command line
command 1 && command 2
executes first command 1, and if it is successful (exits with status code 0) it executes command 2. The exit status of the compound is the exit status of the first command if unsuccessful, otherwise the exit status of 2.
For example, the following command line can be used to install Unix software from source, but only if it is successfully configured, compiled, and all tests run.
./configure && make && make test && make install

Related

Bash script to schedule multiple jobs

I wonder if it is possible to write a bash script that would do the following:
make firstprogram
which compiles and executes the first program. Than it would wait until this program is done and then execute:
make secondprogram
How can I write the bash script so that it is run in the terminal?
Is this what you intend? It will finish the first command before running the next. If you only want to run the second if the first runs successfully (exits with exit code 0), use && instead of ;
#!/bin/bash
make firstprogram; make secondprogram
You need to utilize the wait command
#!/bin/bash
make firstprogram
firstprogram &
wait
echo "First program done!"
make secondprogram
secondprogram &
echo "Second program done!"
exit 0

How to run a command in bash which captures the output and waits until the command has finished?

I am using the following in a bash script:
command >> /var/log/somelog.log 2>&1&
The reason I'm doing this is because I want to capture all output in /var/log/somelog.log.
This works fine. However it does not wait until the command has finished. So that brings me to the question, how can I capture all output from command in /var/log/somelog.log and not have the bash script continue before command has finished?
Just leave out the final ampersand &, e.g.
command >> /var/log/somelog.log 2>&1
From Bash - Lists of Commands
If a command is terminated by the control operator ‘&’, the shell executes the command asynchronously in a subshell. This is known as executing the command in the background. The shell does not wait for the command to finish, and the return status is 0 (true).
Don't put the command in the background.
The last & character means "run this command in the background, while giving me a new shell prompt immediately."
command >> /var/log/somelog.log 2>&1&
^ this one
Just take that last character off the command, and the command will run in the foreground until it finishes.
This is frankly pretty introductory stuff. Have you considered reading any documentation about using the shell?

Can't get BASH script to wait for PID

I am building a script to make my life easier when setting up servers.
I am having a issue with this line:
# Code to MV/CP/CHOWN files (working as intended)
sudo su $INSTALL_USER -c \
"sh $SOFTWARE_DIR/soa/Disk1/runInstaller \
-silent -response $REPONSE_LOC/response_wls.rsp \
-invPtrLoc $ORA_LOC/oraInsta.loc \
-jreLoc /usr/java/latest" >&3
SOA_PID = pgrep java
wait $SOA_PID
# Code below this which requires this be completed before execution.
I am trying to get my script to wait for the process to complete before it continues on.
The script executes, but instead of waiting, it continues on, and the execution of the installer runs after the script finishes. I have other installer pieces that need this part installed before they start their own process, hence the wait.
I've tried using $! etc, but since this piece get executing by a separate user, I don't know if that would work.
Thanks for any assistance.
The command SOA_PID = pgrep java should result in an error.
Try to capture the PID like this:
SOA_PID=$( pgrep java ) || exit
The || exit forces an exit if pgrep does not return a value,
preventing nonsense happening further on.
An alternative would be to rely on wait to return immediately,
but it's better to be explicit.
When using this in a function you'd use || return instead, depending
on circumstances.

Does '&' perform parallel or linear jobs in linux shell scripting?

I was trying to search online but didn't get a definite answer for this. Does the symbol & in linux perform two jobs in parallel or in a linear way?
for example:
command1 & command2
Here, will command1 and command2 be performed in parallel or will command2 be performed AFTER command1 finishes? What is exactly happening here?
The reason I'm asking this is because in my command1 and command2 I am calling scripts with different arguments which write some data to the same text file. After running the aforementioned script, I see that the output of command2 is being appended to command1. Is this the expected behaviour if they are truly working in parallel?
Try this on for size:
$ ls & pwd
[1] 7592 <---"ls" being put in the background as job #1, with pid 7592
/home/marc <--- output of "pwd"
$ stuff
^---------------- shell waiting for next input
^^^^^---------- output of "ls" command
a & b places the a program in the background, and immediately starts executing the b command as well. It's not exactly parallel, but it is two completely separate processes that happen to be sharing a common output: your terminal

question on linux command

What do the two ampersands in the following command do:
(make foo&)&
The ( and ) run the command in a subshell. This means that a separate shell is spawned off and the command is run. This is probably because they wanted to use shell specific operation (backgrounding - other examples are redirection etc.). The first & in the command backgrounds the command run in the subshell (ie. make foo). The second ampersand backgrounds the subshell itself so that you get back your command prompt immediately.
You can see the effects here
Foreground on the current shell
(bb-python2.6)noufal#NibrahimT61% ls # shell waits for process to complete
a b c d e
Background on the current shell
(bb-python2.6)noufal#NibrahimT61% ls& #Shell returns immediately.
[1] 3801
a b c d e
[1] + done /bin/ls -h -p --color=auto -X
Using a subshell (Foreground)
(bb-python2.6)noufal#NibrahimT61% (ls&) # Current shell waits for subshell to finish.
a b c d e
In this case, the current shell waits for the subshell to finish even though the job in the subshell itself is backgrounded.
Using a subshell (BAckground)
(bb-python2.6)-130- noufal#NibrahimT61% (ls &)&
[1] 3829
a b c d e
[1] + exit 130 (; /bin/ls -h -p --color=auto -X &; )
The foreground shell returns immediately (Doesn't wait for the subshell which itself doesn't wait for the ls to finish). Observe the difference the command executed.
A sidenote on the need to run some commands in a subshell. Suppose you wanted to run a "shell command" (ie. One that uses shell specific stuff like redirects, job ids etc.), you'd have to either run that command in a subshell (using (, )) or using the -c option to shells like bash. You can't just directly exec such things because the shell is necessary to process the job id or whatever. Ampersanding that will have the subshell return immediately. The second ampersand in your code looks (like the other answer suggests) redundant. A case of "make sure that it's backgrounded".
It's difficult to say without context, but & in shell commands runs the command in the background and immediately continues, without waiting for the command to finish. Maybe the Makefile author wanted to run several commands in parallel. The second ampersand would be redundant though, as are the parentheses.
Ampersand is used as a line continuation character in makefiles.
Hard to say for sure since there isn't enough context in your question.

Resources