Running the shell scripts in Background - linux

I would to give the user the feature to run the shell script in background.
My shell program instantiates a number of other shell scripts.
Here is a small code snippet of my script
./main.sh # Main script
in main.sh
I call preprocessing.sh
create_dir.sh
handle_file.sh
post_processing.sh
report_generation.sh
I would like to know if I have to initiate all the child script as well.. What is the syntax if i have to initiate all the scripts in background and at the end inform the user by displaying message in that test run is complete.
Thanks
Kiran

Start your processes in the background with & and then use bash's builtin wait command:
wait [n ...]
Wait for each specified process and return its termination sta‐
tus. Each n may be a process ID or a job specification; if a
job spec is given, all processes in that job’s pipeline are
waited for.
A couple of example are available here. For instance:
# wait on 2 processes
sleep 10 &
sleep 10 &
wait %1 %2 && echo "Completed!"

add "&" to the end of the commands
I call preprocessing.sh &
create_dir.sh &
...

Related

How to send a message from one shell script to another shell script when both are running?

I have 3 shell scripts running in the background. Shell script 1 prints a message "Hello 1". The shell scripts 2 and 3 are also running in the background. I give the kill command to shell script 1. Now I use pgrep command in shell script 2 to know that script 1 is not running.
How can I notify this to script 3 from script 2 while both of them are already running in the background ? Once script 2 notifies script 3 then it should start printing "Hello 3". This is the entire task which I have to do.
Signals are one of the oldest inter-process communication methods used by Unix /Linux systems. They are used to signal asynchronous events to one or more processes.
You can send a signal to script3 from script2 when pgrep detects the condition you are looking for.
Take a look at
help kill
and
help trap

Csh script wait for multiple pid

Does the wait command work in a csh script to wait for more than 1 PID to finish?
Where the wait command waits for all the PID listed to complete before moving on to the next line
e.g.
wait $job1_pid $job2_pid $job3_pid
nextline
as the documentation online that I usually see only shows the wait command with only 1 PID, although I have read of using wait for multiple PID, like here :
http://www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/HTML/MAN/MAN1/0522____.HTM
which says quote "If one or more pid operands are specified that represent known process IDs,the wait utility waits until all of them have terminated"
No, the builtin wait command in csh can only wait for all jobs to finish. The command in the documentation that you're referencing is a separate executable that is probably located at /usr/bin/wait or similar. This executable cannot be used for what you want to use it for.
I recommend using bash and its more powerful wait builtin, which does allow you to wait for specific jobs or process ids.
From the tcsh man page, wait waits for all background jobs. tcsh is compatible with csh, which is what the university's documentation you linked is referring to.
wait The shell waits for all background jobs. If the shell is interactive, an interrupt will disrupt the wait and cause the shell
to print the names and job numbers of all outstanding jobs.
You can find this exact text on the csh documentation here.
The wait executable described in the documentation is actually a separate command that waits for a list of process ids.
However, the wait executable is not actually capable of waiting for the child processes of the running shell script and has no chance of doing the right thing in a shell script.
For instance, on OS X, /usr/bin/wait is this shell script.
#!/bin/sh
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
# This file is in the public domain.
builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$#"}
Anyway, I can't get the /usr/bin/wait executable to work reliably in a Csh script ... because the the background jobs are not child processes of the /usr/bin/wait process itself.
#!/bin/csh -f
setenv PIDDIR "`mktemp -d`"
sleep 4 &
ps ax | grep 'slee[p]' | awk '{ print $1 }' > $PIDDIR/job
/usr/bin/wait `cat $PIDDIR/job`
I would highly recommend writing this script in bash or similar where the builtin wait does allow you to wait for pids and capturing pids from background jobs is easier.
#!/bin/bash
sleep 4 &
pid_sleep_4="$!"
sleep 7 &
pid_sleep_7="$!"
wait "$pid_sleep_4"
echo "waited for sleep 4"
wait "$pid_sleep_7"
echo "waited for sleep 7"
If you don't want to rewrite the entire csh script you're working on, you can call out to bash from inside a csh script like so.
#!/bin/csh -f
bash <<'EOF'
sleep 4 &
pid_sleep_4="$!"
sleep 7 &
pid_sleep_7="$!"
wait "$pid_sleep_4"
echo "waited for sleep 4"
wait "$pid_sleep_7"
echo "waited for sleep 7"
'EOF'
Note that you must end that heredoc with 'EOF' including the single quotes.

Detaching a background process in zsh so that I can close the terminal

I have a terminal process running zsh in the Cygwin environment. I want to start a background process and then close the terminal process and have the background process running. However, when I exit the terminal, I get the error message that it can't exit, because a background process is still running. Example:
sleep 300 &
exit
I get the message zsh: you have running jobs.
The same with
nohup sleep 300 &
From the man page of zsh, I see that there is a command called disown which, from the description, might do what I want, but I don't know how to use it. According to the man page, it expects an argument job, but doesn't say what this argument actually is. I tried
sleep 300 &
disown $!
but get the message disown: job not found: 3964, so a job is obviously not a PID.
How can I do this correctly?
You need to refer to the job by it's job number
sleep 3000
control-z
bg
jobs
disown %3 (or whatever job number)
Hope this still helps at lest other readers: disown without any parameter disconnects the job with job number %1.
In addition you might want to check out the AUTO_CONTINUE on Ctrl-Z function.
alias bg='bg && disown'
in .zshrc to get bash-style behavior exiting terminal that launched process with keystrokes: Ctrl + Z, bg, exit

linux + how to Kill stuck program after few seconds

I execute the following binary file on my linux/Solaris system ( in order to get system info )
/usr/sbin/diag
After diag command running,I get some lines on screen , but its stuck , and I not get the Linux/Solaris prompt (diag program not return exe code 0 or 1 because its stuck -:( )
( the only way to exit prom diag is to perform CNTL – C )
my question: if there are some ways to kill the diag binary program after ~5 second
For example
/usr/sbin/diag & ( the lines runs on screen but diag stuck , need to CNTRL-C )
Wait ~5
Kill the /usr/sbin/diag process (&!)
/usr/sbin/diag & # run diag in background
pid=$! # set last run command's process id into pid var
sleep 5s # wait 5 seconds
kill -9 $pid # kill that pid
your shell has job control disabled.
Check that you
are running on a terminal
are starting the shell in interactive mode
See
Shells offer features geared specifically for interactive use rather than to augment the programming language. These interactive features include job control, command line editing, command history and aliases. Each of these features is described in this manual.
And
Job Control
See the timeout command, you should install it, then run
timeout 60 command_line
for a 60 secondes timeout. It's safe and smart.
One possible approach:
/usr/sbin/diag &
sleep 5 ; kill $!
The bash(1) variable $! refers to the pid of the most recently executed backgrounded command. So, if you cannot place diag into the background, then this won't work for you.
timelimit 60 command_line args
Is also a way to do this. It is part of the netpipes package.

What does &| mean in shell?

Put &| on the end of a command seems to detach the process from the shell. But where does it come from? and what's the right way to use it?
& will cause the process to be detached from the parent process (which in this case is the shell), but won't be disowned from it, which means when you'll close the shell, the process you started will be closed as well.
For disown it completely from the shell you need to do: my_process & and then disown %1
UPDATE
According to the information that the command &| ran on zsh the &| means:
&| - backgrounds the final command of the pipeline.
disown [ job ... ]
job ... &|
job ... &!
Remove the specified jobs from the job table; the shell will no longer report their status, and will not complain if you try to exit an interactive shell with them running or stopped. If no job is specified, disown the current job.
http://linux.die.net/man/1/zshbuiltins
Exit zsh, but leave running jobs open?
& will run the process in background. It will not occupy the terminal no more and wait it until finish.

Resources