Como comentario Goldilocks' y las referencias de la humanidad describen,
shiftvuelve a asignar los parámetros de posición ( $1, $2, etc.) de manera que $1asume el antiguo valor de $2,
$2asume el valor de $3, etc *
El antiguo valor de $1se descarta. ( $0no se cambia). Algunas razones para hacerlo incluyen:
- Le permite acceder al décimo argumento (si hay uno) más fácilmente.
$10no funciona: se interpreta como $1concatenado 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;
fores 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,
$1y $2son cadenas de texto, mientras que $3y todos los demás parámetros son nombres de archivo.
Así es como se desarrolla. Supongamos que su script se llama Patryk_scripty 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 ostren USSR. La primera shiftdeclaració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 nstren Russia. La segunda shiftdeclaración cambia los parámetros posicionales de la siguiente manera:
$1 = Treaty1
$2 = Atlas2
$3 = Pravda3
Y a continuación, los forcambios de bucle USSR( $ostr) a Russia( $nstr) en los archivos Treaty1, Atlas2y 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 Atlas2no es citado, y el forbucle 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 evalpuede 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 sudoo 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.tmpy 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 4hace $5
que se convierta $1,
$6que 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 SHIFTcomando, que básicamente hace lo mismo que el shiftcomando en shells de Unix, con una notable diferencia, que ocultaré para tratar de evitar que la gente se confunda:
- Un comando como
SHIFT 4es un error, produciendo un mensaje de error "Parámetro inválido para comando SHIFT".
SHIFT /n, donde nes 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
pushdypopd).