Quando si esegue uno script di shell, è possibile passare parametri posizionali specifici senza doverli inserire tutti in ordine?


13

Ad esempio, se ho uno script ./foo che accetta 10 parametri e voglio solo passare l'ottavo parametro. L'unico modo per sapere come farlo attualmente è:

./foo '' '' '' '' '' '' '' 'bar'

C'è un modo più semplice / migliore?


1
Questo è il motivo per cui i programmi di solito usano opzioni piuttosto che parametri posizionali se si hanno molti parametri.
Barmar,

Risposte:


4

Un altro modo per eseguire questa operazione è denominare il parametro che si desidera dichiarare e quindi:

{   cat >./foo 
    chmod +x ./foo
    eight=declared ./foo
    eight=declared_and_preferred \
        ./foo 1 2 3 4 5 6 7 8
    ./foo 1 2 3 4 5 6 7 8
    ./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT

PRODUZIONE

$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default

Nell'esempio precedente la variabile di ambiente dichiarata esplicitamente è preferita all'argomento della riga di comando, ma l'argomento della riga di comando viene utilizzato quando la variabile di ambiente è vuota o non impostata. Quando sia l'ottava posizione sia la variabile d'ambiente $eightsono vuote o non impostate, viene assegnato il valore predefinito some_default$eight . In entrambi i casi, è :possibile rimuovere le istruzioni :-o :=se vuoto deve essere un valore accettabile.

Anche la variabile $eightavrebbe potuto essere impostata come:

printf '$eight = %s\n' "${eight:=${8:-some_default}}"

... e la riga precedente è stata omessa del tutto, ma volevo dimostrare che dichiarare una variabile in quel modo si traduce in un valore persistente, e quindi l'ho fatto in due comandi. In entrambi i casi $eightviene impostato il valore finale dell'espansione di quel parametro composto.

getopts- per script robusti - spesso è il modo migliore per gestire le opzioni di comando . I parametri posizionali, d'altra parte, sono quasi sempre il mezzo più semplice per gestire in modo robusto operandi in uno script.

Per esempio:

touch file$(seq -ws\ file 100)
./foo *

PRODUZIONE

$eight = file008

Lì vediamo solo l'ottavo operando, ma ce ne sono 101 rubati dalla mia directory di test.


18

Supponendo che sia possibile modificare lo script, è consigliabile utilizzare parametri opzionali (opzioni) anziché parametri richiesti (argomenti).

Se hai ciascuno dei primi 7 sette parametri come opzioni e li hai di default sulla stringa vuota, allora potresti semplicemente fare:

./foo bar

Se si utilizza una shell compatibile con POSIX è possibile utilizzare l' getoptsutilità o il programma getopt. bash- come la maggior parte delle shell - offre getoptscome built-in. In entrambi i casi è più semplice che eseguire il rollup del proprio parser da riga di comando.

A meno che tu non implementi qualcosa come gli ultimi X argomenti non di opzione, i valori degli ultimi argomenti di Y e gli argomenti di opzione XY devi fornire stringhe di opzioni prima di ciascuna delle 7 (ora vuote) stringhe se vuoi impostare una di queste. Questa tuttavia non è una pratica comune, normalmente un'opzione è sempre un'opzione e un argomento un argomento, e l'ordine di "inserimento" delle opzioni è gratuito.


5
+1per getopt(s). I parametri posizionali sono un momento triste e dovrebbero essere evitati.
HalosGhost
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.