ifdef inclusões condicionais de estilo para shell

3

Considere o seguinte script.

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf
cp blank.pdf blank2.pdf

pdftk \
    A=blank.pdf '#first file' \
    B=blank2.pdf '#second file' \
    cat A B \
    output b.pdf

Mas suponha que eu queira uma variante:

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - newblank.pdf
cp newblank.pdf newblank2.pdf

pdftk \
    A=newblank.pdf '#first file revised' \
    B=newblank2.pdf '#second file revised' \
    cat A B \
    output b.pdf

Agora, suponha que eu os queira juntos. Eu posso fazer

#!/bin/sh                                                                                                                                                   

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf
cp blank.pdf blank2.pdf
cp blank.pdf newblank.pdf
cp blank.pdf newblank2.pdf

pdftk \
    A=blank.pdf '#first file' \
    '#A=newblank.pdf' '#first file revised' \
    B=blank2.pdf '#second file' \
    '#B=newblank2.pdf' '#second file revised' \
    cat A B \
    output b.pdf

Mas se eu quiser alternar entre versões, tenho que comentar e descomentar coisas. Existe alguma maneira eu posso fazer um condicional inclusão, para que eu possa (digamos) obter uma versão dependendo se uma variável está definida ou não, no estilo da macro #ifdef C?

Seria bom ter uma solução de shell portátil, mas se não, um bash específico também funcionaria.

Por último, apenas uso dois arquivos neste exemplo ( blank.pdf . blank2.pdf ), mas preciso de uma solução que funcione com um número arbitrário de arquivos. Além disso, uma versão que tenha as versões antiga e nova de cada arquivo próximas uma da outra para fins de comparação seria preferível. Além disso, alguns dos arquivos podem ser os mesmos nas versões original e nova, por isso seria bom não ter que repetir os arquivos nesse caso.

    
por Faheem Mitha 07.01.2016 / 10:13

2 respostas

4

A diferença entre as versões que você deu são apenas nomes de arquivos / argumentos diferentes.

Diferenciar variantes de mais ou menos o mesmo código com " ifdef " - estruturas semelhantes geralmente não é o melhor caminho, pois leva a código dificilmente sustentável e duplicado.

Em seu exemplo, você pode, por exemplo, usar variáveis de shell (e uma pequena cláusula if ... ; then ) para alternar entre duas variantes:

 #call the script with -2 to switch to the second version.
 if [ "$1" = "-2" ]; then
           firstfile="newblank.pdf"
           secondfile="newblank2.pdf"   
 else
           firstfile="blank.pdf"
           secondfile="blank2.pdf"   
fi

echo "" | ps2pdf -sPAPERSIZE=a4 - "$infile"
cp "$firstfile" "$secondfile"

pdftk \
    "A=$firstfile" '#first file' \
    "B=$secondfile" '#second file' \
    cat A B \
    output b.pdf

Se você quiser ter várias chamadas do mesmo código com apenas pequenas alterações, considere definir functions e chame-os com argumentos diferentes.

    
por 07.01.2016 / 10:32
2

Para obter um argumento como uma condição de definição de valor, você pode simplesmente expandir o valor condicionalmente.

unset var
echo  ${var+" nothing because this is unset "}
var=
echo  ${var-" nothing because the value is null but the var is set "}
var=value
echo  ${var:+" this will expand    -    to my optionally provided word "} 

O formulário :+ expandirá para palavra quando uma variável for definida e não nula. :- será expandido para palavra quando não estiver definido ou será nulo - caso contrário, ele será expandido para seu valor. As formas de [+-] sem os dois pontos são semelhantes, mas descartar qualquer condição em valores nulos e apenas tesr um parâmetro para saber se ele está definido.

Se você tivesse uma lista de argumentos como:

pdftk \
    arg arg ${first+"'#first file ${rev+revised}'"} \
    ${blank+"blankfile"} ${second+"'#second file ${rev+revised}'"}

... você poderia fazer isso funcionar ...

echo "" | ps2pdf -sPAPERSIZE=a4 - "${pre+${age:=new}}blank.pdf"
cp "${pre+$age}blank.pdf" "${pre+$age}blank2.pdf"

pdftk \
    "A=${pre+$age}blank.pdf" "'#first file${rev:+ revised: $rev}'" \
    "B=${pre+$age}blank2.pdf" "'#second file${rev:+ revised: $rev}'" \
    cat A B \
    output b.pdf

Como eles aninham, você pode, opcionalmente, expandir um valor dentro de um valor. Então ...

pre=+ rev=$(date) age=old your_script

... funcionaria muito diferente do que ...

unset pre rev age; your_script
    
por 07.01.2016 / 10:30