Me he encontrado con este script:
#! /bin/bash                                                                                                                                                                                           
if (( $# < 3 )); then
  echo "$0 old_string new_string file [file...]"
  exit 0
else
  ostr="$1"; shift
  nstr="$1"; shift  
fi
echo "Replacing \"$ostr\" with \"$nstr\""
for file in $@; do
  if [ -f $file ]; then
    echo "Working with: $file"
    eval "sed 's/"$ostr"/"$nstr"/g' $file" > $file.tmp 
    mv $file.tmp $file
  fi  
done
¿Cuál es el significado de las líneas donde se usan shift? Supongo que el script debe usarse con al menos argumentos, así que ...?
                    
                        shell-script
                                arguments
                                
                    
                    
                        Patryk
fuente
                
                
            fuente

pushdypopd).bash, la pregunta es general para todos los shells, por lo tanto, prevalece el estándar Posix: pubs.opengroup.org/onlinepubs/9699919799/utilities/…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:$10no funciona: se interpreta como$1concatenado con un0(y, por lo tanto, podría producir algo asíHello0). Después de ashift, se convierte en el décimo argumento$9. (Sin embargo, en la mayoría de los proyectiles modernos, puede usar${10}).fores mucho mejor para eso$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 comoEl guión ve
La declaración
ostr="$1"establece la variableostrenUSSR. La primerashiftdeclaración cambia los parámetros posicionales de la siguiente manera:La declaración
nstr="$1"establece la variablenstrenRussia. La segundashiftdeclaración cambia los parámetros posicionales de la siguiente manera:Y a continuación, los
forcambios de bucleUSSR($ostr) aRussia($nstr) en los archivosTreaty1,Atlas2yPravda3.Hay algunos problemas con el script.
Si el script se invoca como
ve
pero, debido a
$@que no es citado, en el espacioWorld Atlas2no es citado, y elforbucle piensa que tiene cuatro archivos:Treaty1,World,Atlas2, yPravda3. Esto debería ser(para citar cualquier carácter especial en los argumentos) o simplemente
(que es equivalente a la versión más larga).
No hay necesidad de que esto sea un
eval, y pasar una entrada de usuario no verificada a unevalpuede ser peligroso. Por ejemplo, si el script se invoca comose 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 ejecutarsudoo invocar desde una interfaz web. Probablemente no sea tan importante si solo lo usa como usted mismo, en su directorio. Pero se puede cambiar aEsto todavía tiene algunos riesgos, pero son mucho menos severos.
if [ -f $file ],> $file.tmpymv $file.tmp $filedebe serif [ -f "$file" ],> "$file.tmp"ymv "$file.tmp" "$file", respectivamente, para manejar nombres de archivos que pueden tener espacios (u otros caracteres divertidos) en ellos. (Eleval "sed …comando también manipula los nombres de archivo que tienen espacios en ellos).*
shifttoma un argumento opcional: un entero positivo que especifica cuántos parámetros cambiar. El valor predeterminado es uno (1). Por ejemplo,shift 4hace$5que 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 decirlo 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 elshiftcomando en shells de Unix, con una notable diferencia, que ocultaré para tratar de evitar que la gente se confunda:fuente
shiftpuede aplicarse awhile,untile inclusoforbucles para manejar matrices de formas mucho más sutiles que unforbucle simple . A menudo lo encuentro útil enforbucles como ...set -f -- $args; IFS=$split; for arg do set -- $arg; shift "${number_of_fields_to_discard}" && fn_that_wants_split_arg "$arg"; doneLa explicación más simple es esta. Considere el comando:
Sin la ayuda de
shiftusted, no puede extraer el valor completo de la ubicación porque este valor podría ser arbitrariamente largo. Cuando cambia dos veces, los argsSETylocationse eliminan de manera que:Mire muy largamente la
$@cosa. Eso significa que puede guardar la ubicación completa en variable axpesar de los espacios y la coma que tiene. En resumen, llamamosshifty luego recuperamos el valor de lo que queda de la variable$@.ACTUALIZACIÓN Estoy agregando a continuación un fragmento muy breve que muestra el concepto y la utilidad de los
shiftcuales, sin lo cual, sería muy, muy difícil extraer los campos correctamente.Explicación : Después de
shift, la variable b contendrá el resto de las cosas que se pasan, sin importar espacios o etc. La[ -n "$b" ] && echo $bprotección es tal que solo imprimimos b si tiene un contenido.fuente
"$*"lugar de"$@". (3) Iba a votar su respuesta, pero no lo hice, porque usted dice "cambiar dos veces" pero en realidad no lo muestra en el código. (4) Si desea que un script pueda tomar un valor de varias palabras de la línea de comando, probablemente sea mejor requerir que el usuario ponga el valor completo entre comillas. … (Continúa)Philippines 6014), espacios iniciales, espacios finales o pestañas. (5) Por cierto, también puedes hacer lo que estás haciendo aquí en golpex="${*:3}".shiftcomando. Tal vez se refiera a las diferencias sutiles de $ @ versus $ *. Pero el hecho sigue siendo que mi fragmento de arriba puede extraer con precisión la ubicación sin importar cuántos espacios tenga detrás o en el frente, no importa. Después del turno, la ubicación contendrá la ubicación correcta.shifttratar los argumentos de la línea de comandos como una cola FIFO, es un elemento popleft cada vez que se invoca.fuente