Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have the following script (at the end of the explanation and question).

There is two functions. On the first function there is a call to firefox -print extension. Everything works fine if I run it line by line.

The problem is that inside a bash script firefox is called many times in a few seconds instead of being called once at a time and waiting to finish.

I donnot would like to add a sleep in the funcion because I don't know how long can it take.

There is any way to force bash to do not launch threads? (which I suppose is doing)

Thanks.

This is my script .(it's bash and not sh because of the command let)

#!/bin/bash

####TODO###
####variables
# join files
# send with attachment

## Date, to be used as reference on tmp files
DATE=`date +%Y%m%d`
## File where all webs to report are listed
WEBSFILE="/home/marc.riera/Desktop/reports/websfile.txt"
## Where to store all the files. 
WORKDIR="/home/marc.riera/Desktop/reports"

##################do not edit under this line
TMPDIR=$WORKDIR/$DATE
test -d $TMPDIR || mkdir -p $TMPDIR && echo "Create folder $TMPDIR for temporal usage"
REPORT=$WORKDIR/Report_$DATE.pdf

##firefox -print "http://fbmsgga01/ganglia/?m=cpu_report&r=month&s=descending&c=CPU+cluster&h=&sh=1&hc=4&z=small" -printmode pdf -printdelay 5 -printfile ~/Desktop/reports/test.pdf
firefoxprint (){
     web2Print=$1
     outputFile=$2
     echo -n "printing $1 on $2"
     firefox -print "$web2Print" -printmode pdf -printdelay 5 -printfile $outputFile
}

##gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=dospdf.pdf -dBATCH ganglia.pdf test.pdf
pdfjoin (){
     outputFile=$1
     origA=$2
     origB=$3
     echo -n "Joining $origA and $origB into $outputFile"
     gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=$outputFile -dBATCH $origA $origB
}


###################################### MAIN
#######################################
clear
COUNTER=0
for web in `cat $WEBSFILE|grep -v '^#'`
do
     firefoxprint $web $TMPDIR/$COUNTER.pdf
     let COUNTER+=1
done
echo "--------------------" $COUNTER
while [ $COUNTER -gt 0 ]; do
    let COUNTER=COUNTER-1
    pdfjoin $REPORT $REPORT $TMPDIR/$COUNTER.pdf
done

echo "done"
exit 0
share|improve this question
add comment

6 Answers

up vote 1 down vote accepted

If there is a running firefox, the call to firefox just contacts it, transmits the print request and exits immediately. The print request is executed asynchronously in the running instance. I don't know if there is a way to get a notification when the printing is finished.

A workaround (untested) would be to create a fresh profile in your script (unpack a prepared zip under a random name). You can run multiple instances of firefox as long as they use different profiles. Erase the temporary profile once firefox exits. This assumes that the printing extension doesn't leave the firefox instance running; if it does, you could hack it to exit firefox once it's finished.

share|improve this answer
add comment

I'm not terribly familiar with using FireFox to print, but have you played around with bash's wait command? You can feed it the specific PID to wait for. So by following one of your firefox print commands, you could just do wait $!. Or, if you don't specify any and just use wait, it will simply wait for all child processes to finish.

I can't guarantee that FireFox will play nicely with this. But it's worth a shot.

share|improve this answer
    
Nice try, but still opens as many firefox as lines in the file. And don't wait for the print command to finish. I guess firefox does not play nice with this. –  marc.riera Sep 2 '10 at 17:01
    
the wait builtin can only wait for the shell's own background processes (started with &). marc.riera's script contains no background process, so wait is no use. –  Gilles Sep 2 '10 at 23:31
add comment

At the end of your firefoxprint() routine add:

  while [ ! -s $outputFile ]; do
    sleep 1
  done

which should get you at least some delay - it waits until there's a non-zero-length output file before continuing. Hopefully this will slow it down enough that subsequent calls will use the existing firefox and not think they have to spawn their own.

share|improve this answer
add comment

When you call firefox without specifying a full directory, it will run a wrapper script which does an exec of the actual executable. This may be causing your problem or the executable may be doing a double fork which causes it to run in the background without using &. I don't know how you can prevent this.

share|improve this answer
    
actually, the presence of exec means that there is no double fork. –  Gilles Sep 2 '10 at 23:32
add comment

There is only one wait to make it.

a) Create a dedicated profile at firefox for printing:

firefox -no-remote -ProfileManager

b) Start firefox by firefox -no-remote -P

c) do wait

share|improve this answer
add comment

Ok, finally solved. Thanks for all your help.

There was another issue: the cron launches the firefox without env variables, so I had to define the display where to work.

Here is the final code.

#!/bin/bash

#autor : Joan Marc Riera Duocastella. 
#license : BSD i guess. I just don't care. :)
# firefox -print option depends on http://sites.google.com/site/torisugari/commandlineprint2  
# it's kind of possible that a file inside de .xpi extension must be edited to get bigger pdf . Depends on the html you would like to print. Good html code does not need it. 


####variables

## Date, to be used as reference on tmp files
DATE=`date +%Y%m%d`
## File where all webs to report are listed
WEBSFILE="/home/marc.riera/Desktop/reports/websfile.txt"    # urls to print. lines starting with # will be ignored.
## Where to store all the files. 
WORKDIR="/home/marc.riera/Desktop/reports"
MAILTO="marc.riera@barcelonamedia.org"   # other mails can be added just with a single space between
MAILTEXTFILE=$WEBSFILE         
FFPROFILE="cnm-profile"  #FIREFOX PROFILE - create it with firefox -ProfileManager while no other firefox instances running

##################do not edit under this line
#echo "$DATE - $0"
logger $0
TMPDIR=$WORKDIR/$DATE
test -d $TMPDIR && rm -f $TMPDIR/*.pdf|| mkdir -p $TMPDIR && echo "Create folder $TMPDIR for temporal usage"
REPORT=$WORKDIR/Report_$DATE.pdf

##firefox -print "http://fbmsgga01/ganglia/?m=cpu_report&r=month&s=descending&c=CPU+cluster&h=&sh=1&hc=4&z=small" -printmode pdf -printdelay 5 -printfile ~/Desktop/reports/test.pdf
firefoxprint (){
    web2Print=$1
    outputFile=$2
    #echo "printing $1 on $2"
    env DISPLAY=:0.0 firefox -P $FFPROFILE -no-remote -print "$web2Print" -printmode pdf -printdelay 15 -printfile $outputFile &
    while [ ! -s $outputFile ]; do
          sleep 1
    done
}

##gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=dospdf.pdf -dBATCH ganglia.pdf test.pdf
pdfjoin (){
    outputFile=$1
    tempdir=$2
    cd $tempdir
    gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=$outputFile -dBATCH `ls -tr $tmpdir`
    wait
}

sendmail (){
    #echo "Sending mail"
    mutt -s "Report del dia $DATE" -a $REPORT -- $MAILTO < $MAILTEXTFILE
    wait
}

###################################### MAIN
#######################################
COUNTER=0
for web in `cat $WEBSFILE|grep -v '^#'|grep -v '^$'`
do
    firefoxprint $web $TMPDIR/$COUNTER.pdf
    let COUNTER+=1
done
pdfjoin $REPORT $TMPDIR
sendmail
exit 0

I'm still up for improvements, but by now it does what I need.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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