Como comentario Goldilocks' y las referencias de la humanidad describen,
shift
vuelve a asignar los parámetros de posición ( $1
, $2
, etc.) de manera que $1
asume el antiguo valor de $2
,
$2
asume el valor de $3
, etc *
El antiguo valor de $1
se descarta. ( $0
no se cambia). Algunas razones para hacerlo incluyen:
- Le permite acceder al décimo argumento (si hay uno) más fácilmente.
$10
no funciona: se interpreta como $1
concatenado con un 0
(y, por lo tanto, podría producir algo así Hello0
). Después de a shift
, se convierte en el décimo argumento $9
. (Sin embargo, en la mayoría de los proyectiles modernos, puede usar ${10}
).
- Como lo demuestra la Guía Bash para principiantes , se puede usar para recorrer los argumentos. IMNSHO, esto es torpe;
for
es mucho mejor para eso
- Como en su secuencia de comandos de ejemplo, facilita el procesamiento de todos los argumentos de la misma manera, excepto algunos. Por ejemplo, en su secuencia de comandos,
$1
y $2
son cadenas de texto, mientras que $3
y todos los demás parámetros son nombres de archivo.
Así es como se desarrolla. Supongamos que su script se llama Patryk_script
y se llama como
Patryk_script USSR Russia Treaty1 Atlas2 Pravda3
El guión ve
$1 = USSR
$2 = Russia
$3 = Treaty1
$4 = Atlas2
$5 = Pravda3
La declaración ostr="$1"
establece la variable ostr
en USSR
. La primera shift
declaración cambia los parámetros posicionales de la siguiente manera:
$1 = Russia
$2 = Treaty1
$3 = Atlas2
$4 = Pravda3
La declaración nstr="$1"
establece la variable nstr
en Russia
. La segunda shift
declaración cambia los parámetros posicionales de la siguiente manera:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
Y a continuación, los for
cambios de bucle USSR
( $ostr
) a Russia
( $nstr
) en los archivos Treaty1
, Atlas2
y Pravda3
.
Hay algunos problemas con el script.
para archivo en $ @; hacer
Si el script se invoca como
Patryk_script URSS Rusia Tratado1 "Atlas mundial2" Pravda3
ve
$ 1 = URSS
$ 2 = Rusia
$ 3 = Tratado1
$ 4 = Atlas mundial2
$ 5 = Pravda3
pero, debido a $@
que no es citado, en el espacio World Atlas2
no es citado, y el for
bucle piensa que tiene cuatro archivos: Treaty1
, World
, Atlas2
, y Pravda3
. Esto debería ser
para el archivo en "$ @"; hacer
(para citar cualquier carácter especial en los argumentos) o simplemente
para archivo hacer
(que es equivalente a la versión más larga).
eval "sed 's /" $ ostr "/" $ nstr "/ g' $ archivo"
No hay necesidad de que esto sea un eval
, y pasar una entrada de usuario no verificada a un eval
puede ser peligroso. Por ejemplo, si el script se invoca como
Patryk_script "'; rm *;'" Tratado de Rusia1 Atlas2 Pravda3
se ejecutará rm *
! Esto es una gran preocupación si el script se puede ejecutar con privilegios superiores a los del usuario que lo invoca; por ejemplo, si se puede ejecutar sudo
o invocar desde una interfaz web. Probablemente no sea tan importante si solo lo usa como usted mismo, en su directorio. Pero se puede cambiar a
sed "s / $ ostr / $ nstr / g" "$ archivo"
Esto todavía tiene algunos riesgos, pero son mucho menos severos.
if [ -f $file ]
, > $file.tmp
y mv $file.tmp $file
debe ser if [ -f "$file" ]
, > "$file.tmp"
y mv "$file.tmp" "$file"
, respectivamente, para manejar nombres de archivos que pueden tener espacios (u otros caracteres divertidos) en ellos. (El eval "sed …
comando también manipula los nombres de archivo que tienen espacios en ellos).
* shift
toma un argumento opcional: un entero positivo que especifica cuántos parámetros cambiar. El valor predeterminado es uno ( 1
). Por ejemplo, shift 4
hace $5
que se convierta $1
,
$6
que se convierta $2
, etc. (Tenga en cuenta que el ejemplo en la Guía Bash para principiantes es incorrecto). Por lo tanto, su secuencia de comandos podría modificarse para decir
ostr="$1"
nstr="$2"
shift 2
lo que podría considerarse más claro.
Nota final / Advertencia:
El lenguaje de símbolo del sistema de Windows (archivo por lotes) también admite un SHIFT
comando, que básicamente hace lo mismo que el shift
comando en shells de Unix, con una notable diferencia, que ocultaré para tratar de evitar que la gente se confunda:
- Un comando como
SHIFT 4
es un error, produciendo un mensaje de error "Parámetro inválido para comando SHIFT".
SHIFT /n
, donde n
es un número entero entre 0 y 8, es válido, pero no cambia los tiempos . Se desplaza una vez, comenzando con el n º argumento. Por lo tanto , (el quinto argumento) se convierte en , y así sucesivamente, dejando solo los argumentos del 0 al 3.n
SHIFT /4
%5
%4,
%6
%5
pushd
ypopd
).