1

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`
    do
        ssh -q -o "StrictHostKeyChecking no" -o "NumberOfPasswordPrompts 0" -o ConnectTimeout=2 $i "echo -n $i;echo -n ",";$command3" 2>>/dev/null &
    done >> $file_save &
    PROC_ID=$!
    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"
        else
            mailx -s "Servers Command Output" -a $file_save  <my mail_id@abc.com>
            break;
        fi
done &
exit 0;
fi
  • 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 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? – user1794469 Jan 18 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 at 8:43
0

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:

#!/bin/bash

# Set to real file if you want "log output"
log_file=/dev/null

file_save=/whatever

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
    wait
    mailx -s "Servers Command Output" -a $file_save  <my mail_id@abc.com>
}

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

# clear file_save
>$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.

0

Alternatively

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 mail_id@abc.com>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.