Comment définir un script shell avec un nombre variable d'arguments?
Je voudrais définir une abréviation simple d'un appel à gs
(ghostscript) via un script shell. Le premier argument(s) donner à tous les fichiers qui doivent être fusionnés, le dernier donne le nom du fichier de sortie. Évidemment, ce qui suit ne fonctionne pas (c'est juste pour montrer le but):
#!/bin/sh
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$last $1 $2 ...
Comment cela peut-il être fait?
On appelle généralement ce script via myscript infile1.pdf infile2.pdf ... outfile.pdf
ou myscript *.pdf outfile.pdf
.
3 réponses
Les variables bash $@
et $*
étendre dans la liste des arguments de ligne de commande. Généralement, vous voudrez utiliser "$@"
(c'est-à-dire $@
entouré de guillemets doubles). Cela fera la bonne chose si quelqu'un transmet à votre script un argument contenant des espaces.
Donc, si vous aviez ceci dans votre script:
outputfile=$1
shift
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=$outputfile "$@"
Et vous avez appelé votre script comme ceci:
myscript out.pdf foo.ps bar.ps "another file.ps"
Cela s'étendrait à:
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOUTPUTFILE=out.pdf foo.ps bar.ps "another file.ps"
Lisez la section "Paramètres Spéciaux" du manuel bash
pour plus d'informations.
Pour passer le fichier de sortie comme dernier argument, utilisez un tableau:
ARGS=("$@")
# Get the last argument
outputfile=${ARGS[-1]}
# Drop it from the array
unset ARGS[${#ARGS[@]}-1]
exec gs ... -sOUTPUTFILE=$outputfile "${ARGS[@]}"
Avant la version 4, bash
n'autorisait pas les indices négatifs dans les tableaux (et produisait l'erreur signalée par Marius dans les commentaires), donc si vous utilisez 3.x vous devez utiliser le beaucoup plus laid
outputfile=${ARGS[${#ARGS[@]}-1]}
Cela fonctionne pour bash 4.x ainsi.
Pour accéder au dernier argument, en plus de la réponse D'Idelic ci-dessus, vous pouvez également faire:
echo "${@: $#}"
Cela lit tous les arguments et les imprime à partir du dernier. De cette façon, vous pouvez également accéder aux N derniers arguments, par exemple pour les trois derniers arguments:
echo "${@: $#-2}"
$ ./script "what does" "this script" "do" "?"
this script do ?