Come commento Goldilocks' e riferimenti dell'umanità descrivono,
shift
riassegna i parametri posizionali ( $1
, $2
, ecc) in modo che $1
assume il vecchio valore di $2
,
$2
assume il valore di $3
, ecc *
Il vecchio valore $1
viene scartata. ( $0
non è cambiato.) Alcuni motivi per farlo includono:
- Ti consente di accedere più facilmente al decimo argomento (se presente).
$10
non funziona - è interpretato come $1
concatenato 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,
$1
e $2
sono stringhe di testo, mentre $3
e tutti gli altri parametri sono nomi di file.
Quindi ecco come si svolge. Supponiamo che il tuo script sia chiamato Patryk_script
e 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 ostr
su USSR
. La prima shift
istruzione modifica i parametri posizionali come segue:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
L'istruzione nstr="$1"
imposta la variabile nstr
su Russia
. La seconda shift
istruzione modifica i parametri posizionali come segue:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
E poi le for
modifiche del ciclo USSR
( $ostr
) a Russia
( $nstr
) nei file Treaty1
, Atlas2
e 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 Atlas2
non è citato, e il for
ciclo 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 eval
passaggio e l'input dell'utente non controllato a un eval
può 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 sudo
o 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.tmp
E 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 4
cause $5
diventano $1
,
$6
diventano $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 SHIFT
comando, che fa sostanzialmente la stessa cosa del shift
comando 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
pushd
epopd
).