Come commento Goldilocks' e riferimenti dell'umanità descrivono,
shiftriassegna i parametri posizionali ( $1, $2, ecc) in modo che $1assume il vecchio valore di $2,
$2assume il valore di $3, ecc *
Il vecchio valore $1viene scartata. ( $0non è cambiato.) Alcuni motivi per farlo includono:
- Ti consente di accedere più facilmente al decimo argomento (se presente).
$10non funziona - è interpretato come $1concatenato con un 0
(e quindi potrebbe produrre qualcosa di simile Hello0). Dopo un shift, il decimo argomento diventa $9. (Tuttavia, nella maggior parte delle shell moderne, è possibile utilizzare ${10}.)
- Come dimostra la Bash Guide for Beginners , può essere utilizzata per scorrere gli argomenti. IMNSHO, questo è goffo;
forè molto meglio per quello.
- Come nel tuo script di esempio, semplifica l'elaborazione di tutti gli argomenti nello stesso modo, tranne alcuni. Ad esempio, nel tuo script,
$1e $2sono stringhe di testo, mentre $3e tutti gli altri parametri sono nomi di file.
Quindi ecco come si svolge. Supponiamo che il tuo script sia chiamato Patryk_scripte si chiami come
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
La sceneggiatura vede
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
L'istruzione ostr="$1"imposta la variabile ostrsu USSR. La prima shiftistruzione modifica i parametri posizionali come segue:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
L'istruzione nstr="$1"imposta la variabile nstrsu Russia. La seconda shiftistruzione modifica i parametri posizionali come segue:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
E poi le formodifiche del ciclo USSR( $ostr) a Russia( $nstr) nei file Treaty1, Atlas2e Pravda3.
Ci sono alcuni problemi con lo script.
per file in $ @; fare
Se lo script viene invocato come
Patryk_script USSR Russia Treaty1 "World Atlas2" Pravda3
vede
$ 1 = URSS
$ 2 = Russia
$ 3 = Trattato1
$ 4 = Atlante mondiale2
$ 5 = Pravda3
ma, perché $@non è citato, lo spazio in World Atlas2non è citato, e il forciclo pensa che ha quattro file: Treaty1, World, Atlas2, e Pravda3. Questo dovrebbe essere uno dei due
per il file in "$ @"; fare
(per citare eventuali caratteri speciali negli argomenti) o semplicemente
per il file do
(che equivale alla versione più lunga).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ file"
Non è necessario che questo sia un evalpassaggio e l'input dell'utente non controllato a un evalpuò essere pericoloso. Ad esempio, se lo script viene invocato come
Patryk_script "'; rm *;'" Russia Treaty1 Atlas2 Pravda3
verrà eseguito rm *! Questa è una grande preoccupazione se lo script può essere eseguito con privilegi superiori a quelli dell'utente che lo invoca; ad esempio, se può essere eseguito tramite sudoo richiamato da un'interfaccia Web. Probabilmente non è così importante se lo usi come te stesso, nella tua directory. Ma può essere cambiato in
sed "s / $ ostr / $ nstr / g" "$ file"
Ciò comporta ancora alcuni rischi, ma sono molto meno gravi.
if [ -f $file ], > $file.tmpE mv $file.tmp $file
dovrebbe essere if [ -f "$file" ], > "$file.tmp"e mv "$file.tmp" "$file"rispettivamente, per gestire i nomi di file che potrebbero avere spazi (o altri caratteri divertenti) in loro. (Il eval "sed …comando modifica anche i nomi dei file che contengono spazi.)
* shift accetta un argomento facoltativo: un numero intero positivo che specifica quanti parametri spostare. L'impostazione predefinita è one ( 1). Ad esempio, le shift 4cause $5
diventano $1,
$6diventano $2, e così via. (Nota che l'esempio nella Guida di Bash per principianti è sbagliato.) E così il tuo script potrebbe essere modificato per dire
ostr="$1"
nstr="$2"
shift 2
che potrebbe essere considerato più chiaro.
Nota finale / Avvertenza:
Il linguaggio Prompt dei comandi di Windows (file batch) supporta anche un SHIFTcomando, che fa sostanzialmente la stessa cosa del shiftcomando nelle shell Unix, con una notevole differenza, che nasconderò per cercare di evitare che le persone ne vengano confuse:
- Un comando simile
SHIFT 4è un errore, che genera un messaggio di errore "Parametro non valido per il comando SHIFT".
SHIFT /n, dove nè un numero intero compreso tra 0 e 8, è valido, ma non cambia i tempi . Si sposta una volta, partendo con il n ° argomento. Quindi fa sì che il quinto argomento diventi , e così via, lasciando solo gli argomenti da 0 a 3.n SHIFT /4%5%4,
%6%5
pushdepopd).