Comme le commentaire et les références de l' humanité de Goldilocks décrivent,
shift
réaffecte les paramètres de position ( $1
, $2
, etc.) de sorte que $1
prend l'ancienne valeur $2
,
$2
prend la valeur $3
, etc. *
L'ancienne valeur $1
est mis au rebut. ( $0
n'est pas modifié.) Voici quelques raisons pour cela:
- Il vous permet d’accéder plus facilement au dixième argument (s’il en existe un).
$10
ne fonctionne pas - il est interprété comme $1
concaténé avec un 0
(et peut donc produire quelque chose comme Hello0
). Après un shift
, le dixième argument devient $9
. (Cependant, dans la plupart des coquillages modernes, vous pouvez utiliser ${10}
.)
- Comme le montre le Bash Guide for Beginners , il peut être utilisé pour parcourir les arguments. IMNSHO, c'est maladroit;
for
c'est bien mieux pour ça.
- Comme dans votre exemple de script, il est facile de traiter tous les arguments de la même manière, à l'exception de quelques-uns. Par exemple, dans votre script,
$1
et $2
sont des chaînes de texte, alors $3
que tous les autres paramètres sont des noms de fichier.
Alors, voici comment ça se passe. Supposons que votre script s'appelle Patryk_script
et s'appelle comme
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
Le script voit
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
L'instruction ostr="$1"
définit variable ostr
à USSR
. La première shift
instruction modifie les paramètres de position comme suit:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
L'instruction nstr="$1"
définit variable nstr
à Russia
. La deuxième shift
instruction modifie les paramètres de position comme suit:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
Et puis les for
changements en boucle USSR
( $ostr
) à Russia
( $nstr
) dans les fichiers Treaty1
, Atlas2
et Pravda3
.
Il y a quelques problèmes avec le script.
pour le fichier dans $ @; faire
Si le script est appelé en tant que
Patryk_script USSR Russia Treaty1 "World Atlas2" Pravda3
il voit
1 $ = URSS
2 $ = la Russie
3 $ = Traité1
4 $ = World Atlas2
5 $ = Pravda3
mais, parce que $@
n'est pas cité, l'espace World Atlas2
n'est pas cité, et la for
boucle pense qu'il a quatre fichiers: Treaty1
, World
, Atlas2
et Pravda3
. Cela devrait être soit
pour le fichier dans "$ @"; faire
(pour citer des caractères spéciaux dans les arguments) ou simplement
pour le fichier faire
(ce qui équivaut à la version longue).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ fichier"
Il n'est pas nécessaire que cela soit un eval
et il eval
peut être dangereux de passer une entrée utilisateur non contrôlée à un . Par exemple, si le script est appelé en tant que
Patryk_script "'; rm *;'" Traité de Russie1 Atlas2 Pravda3
ça va exécuter rm *
! Cela peut poser un problème si le script peut être exécuté avec des privilèges supérieurs à ceux de l'utilisateur qui l'invoque. Par exemple, s'il peut être exécuté via sudo
ou appelé à partir d'une interface Web. Ce n'est probablement pas si important si vous l'utilisez comme vous-même, dans votre répertoire. Mais cela peut être changé en
sed "s / $ ostr / $ nstr / g" "$ file"
Cela comporte encore certains risques, mais ils sont beaucoup moins graves.
if [ -f $file ]
, > $file.tmp
et mv $file.tmp $file
devraient être if [ -f "$file" ]
, > "$file.tmp"
et mv "$file.tmp" "$file"
, respectivement, pour gérer les noms de fichiers pouvant contenir des espaces (ou d’autres personnages amusants). (La eval "sed …
commande modifie également les noms de fichiers contenant des espaces.)
* shift
prend un argument optionnel: un entier positif spécifiant le nombre de paramètres à décaler. La valeur par défaut est un ( 1
). Par exemple, shift 4
fait $5
devenir $1
,
$6
devenir $2
, etc. (Notez que l'exemple du Guide Bash pour les débutants est erroné.) Ainsi, votre script pourrait être modifié pour indiquer
ostr="$1"
nstr="$2"
shift 2
qui pourrait être considéré comme plus clair.
Note de fin / Avertissement:
Le langage d'invite de commande Windows (fichier de commandes) prend également en charge une SHIFT
commande, qui fait essentiellement la même chose que la shift
commande dans les shells Unix, à une différence frappante, que je vais masquer pour éviter que les utilisateurs ne s'y perdent:
- Une commande similaire à
SHIFT 4
est une erreur, générant un message d'erreur «Paramètre non valide pour la commande SHIFT».
SHIFT /n
, où n
est un entier compris entre 0 et 8, est valide - mais cela ne change pas les temps . Il se déplace une fois, en commençant par le n ième argument. Ainsi , les causes (le cinquième argument) pour devenir à devenir , et ainsi de suite, laissant les arguments 0 à 3 seul.n
SHIFT /4
%5
%4,
%6
%5
pushd
etpopd
).