I have written a script that takes commands from user and runs through a huge list of servers and writes to a single file. Once writing has completed it triggers an email. My requirement is: the script should run in background and when it has finished, send an email.

I have tried wait $PROC_ID & - but writing is happening in background and the email is sent immediately with blank data. Is there any possibility to wait in background and trigger mail once data writing in file completed?

Output of code:

The output can be monitored in /tmp/Servers_Output_list.csv .....................Please Be Patient
Mail will get triggered once completed

Code is below and I mention one function of my script

for i in `cat $file_name`
        ssh -q -o "StrictHostKeyChecking no" -o "NumberOfPasswordPrompts 0" -o ConnectTimeout=2 $i "echo -n $i;echo -n ",";$command3" 2>>/dev/null &
    done >> $file_save &
    echo "                                                "
    echo " The output can be monitored in $file_save....................Please Be Patient"
    echo "Mail will get triggered once completed"
    echo "                                    "
    wait $PROC_ID
    while true; do
        if [ -s $PROC_ID ];then
            echo "$PROC_ID process running Please check"
            mailx -s "Servers Command Output" -a $file_save  <my [email protected]>
done &
exit 0;
  • For ssh connections I do suggest you to use a local .ssh/config and a remote .ssh/authorized_keys with your id_rsa.pub file. About your background task, you are using wait $PROC_ID &. try to do just wait with no arguments and with no & background-task symbol.
    – ton
    Jan 18, 2019 at 16:39
  • It looks like you may have some extra code at the end of your script; is that just a typo or it is part of your script that runs? Jan 18, 2019 at 17:04
  • Your code has one fi too many. Also, the indentations of do's and done's, although not syntactically invalid, are not balanced.
    – Niko Gambt
    Jan 19, 2019 at 8:43

2 Answers 2


If I understand correctly you want to run the ssh commands, the wait for completion and sending the mail in the background. That means, that the script might finish before ssh & mail is done.

So I would propose the following solution:


# Set to real file if you want "log output"


command3=<some command here>

function exec_ssh
    for i in $(cat $file_name); do
        ssh -q -o "StrictHostKeyChecking no" -o "NumberOfPasswordPrompts 0" -o ConnectTimeout=2 $i "echo -n $i;echo -n ',';$1" 2>/dev/null &
    done >> $file_save
    mailx -s "Servers Command Output" -a $file_save  <my [email protected]>

# export function, so it is callable via nohup
export -f exec_ssh $command3

# clear file_save

# run exec_ssh in the background. 
# nohup keeps it running, even when this script terminates.
nohup exec_ssh &>$logfile &

# Inform user
echo " The output can be monitored in $file_save....................Please Be Patient"
echo "Mail will get triggered once completed"

exit 0

The function exec_ssh does all the work and is run in the background with nohup. That way the background job continues running when the script is finished or even when the terminal is closed.

I'm not sure what happens, when the user logs off from the system.



function doit () {
    ssh -q -o "StrictHostKeyChecking no" -o "NumberOfPasswordPrompts 0" -o ConnectTimeout=2 $1 "echo -n $1;echo -n ",";$command3" 2>>/dev/null &
export -f doit
C=$(cat $file_name | wc -l)    
cat $file_name | xargs -I {} -P $C bash -c "doit \"{}\"" >> $file_save
mailx -s "Servers Command Output" -a $file_save  <my [email protected]>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .