Comandos seqüenciais do Bash. Chamando funções sem iniciar novos encadeamentos

1

Eu tenho o seguinte script (no final da explicação e pergunta).

Existem duas funções. Na primeira função há uma chamada para o firefox -print extension. Tudo funciona bem se eu executar linha por linha.

O problema é que dentro de um script bash o firefox é chamado várias vezes em poucos segundos, em vez de ser chamado uma vez por vez e aguardar a conclusão.

Eu não gostaria de adicionar um sleep na função porque não sei quanto tempo pode demorar.

Existe alguma maneira de forçar o bash a não iniciar threads? (o que eu suponho que esteja fazendo)

Obrigado.

Este é o meu script (é bash e não sh por causa do comando 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
    
por Marc Riera 02.09.2010 / 18:31

6 respostas

1

Se houver um firefox em execução, a chamada para firefox apenas contata, envia a solicitação de impressão e sai imediatamente. A solicitação de impressão é executada de forma assíncrona na instância em execução. Não sei se existe uma maneira de obter uma notificação quando a impressão estiver concluída.

Uma solução alternativa (não testada) seria criar um novo perfil em seu script (descompacte um zip preparado com um nome aleatório). Você pode executar várias instâncias do firefox, desde que elas usem perfis diferentes. Apague o perfil temporário depois que o firefox sair. Isso pressupõe que a extensão de impressão não deixe a instância do firefox em execução; se isso acontecer, você pode cortá-lo para sair do firefox assim que terminar.

    
por 03.09.2010 / 01:37
1

Eu não estou muito familiarizado com o uso do FireFox para imprimir, mas você já brincou com o comando wait do bash? Você pode alimentar o PID específico para esperar. Então, seguindo um dos seus comandos de impressão do firefox, você poderia fazer apenas wait $! . Ou, se você não especificar nenhum e apenas usar wait , ele simplesmente aguardará a conclusão de todos os processos filhos.

Não posso garantir que o FireFox funcione bem com isso. Mas vale a pena tentar.

    
por 02.09.2010 / 18:40
1

No final da sua rotina do firefoxprint (), adicione:

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

que deve levar a você pelo menos algum atraso - ele aguarda até que haja um arquivo de saída de comprimento diferente de zero antes de continuar. Espero que isso diminua a velocidade o suficiente para que as chamadas subsequentes usem o firefox existente e não pensem que precisem gerar seus próprios.

    
por 02.09.2010 / 21:31
0

Quando você chamar firefox sem especificar um diretório completo, ele executará um script de wrapper que executa exec do executável real. Isso pode estar causando o seu problema ou o executável pode estar fazendo um fork duplo que faz com que ele seja executado em segundo plano sem usar & . Eu não sei como você pode evitar isso.

    
por 02.09.2010 / 21:48
0

Há apenas uma espera para fazê-lo.

a) Crie um perfil dedicado no firefox para impressão:

firefox -no-remote -ProfileManager

b) Inicie o firefox pelo firefox -no-remote -P

c) espere

    
por 16.09.2010 / 11:21
0

Ok, finalmente resolvido. Obrigado por toda sua ajuda.

Houve outro problema: o cron lança o firefox sem variáveis env, então eu tive que definir a exibição onde trabalhar.

Aqui está o código final.

#!/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="[email protected]"   # 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

Ainda estou pronto para melhorias, mas agora ele faz o que eu preciso.

    
por 17.09.2010 / 16:57