Tenga cuidado al editar scripts de bash

Supongamos que escribí un script bash con el nombre delay.sh. ¿Qué crees que hace?

#!/bin/bash
sleep 30
#rm -rf --no-preserve-root /
echo "Time's up!"

Parece que espera 30 segundos y luego muestra un mensaje en la pantalla. Aquí no hay trucos, él hace exactamente eso. Hay un comando peligroso en el medio, pero está comentado y no se ejecuta.

Imagine que ejecuto este script nuevamente, pero ahora no quiero esperar 30 segundos, esto es demasiado largo. Abro la segunda consola, cambio sleep 30a sleep 3, luego guardo el archivo. ¿Qué crees que pasará ahora?

Bueno, después de 30 segundos, el script eliminará todos mis archivos.

Esto se debe a que bash lee el contenido del script en fragmentos a medida que avanza, rastreando el desplazamiento en bytes. Cuando elimino un carácter de la cadena sleep, el desplazamiento para el inicio del siguiente comando apunta ren su #rmlugar #. Desde el punto de vista del intérprete, se #desplaza a la línea anterior, por lo que ejecuta el comando a partir de rm.

Esto se puede confirmar observando las llamadas del sistema bash en Linux. Aquí está el problema strace bash delay.sh, con comentarios y en abreviatura.

#  
openat(AT_FDCWD, "delay.sh", O_RDONLY)  = 3

#    ( 80 )
read(3, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 80) = 64

#   
lseek(3, 0, SEEK_SET)                   = 0

#      255
dup2(3, 255)                            = 255

#  64-  ,   
read(255, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 64) = 64

#      ,    
# Offset 21 is the `#`
lseek(255, -43, SEEK_CUR)               = 21

#  ,   sleep
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2072

#   wait4    `30`  `3`

#  64-  ,    
#         echo
read(255, "echo \"Don't execute me\"\necho \"Ti"..., 64) = 42

# Bash    echo    
# , -   
write(1, "Don't execute me\n", 17)      = 17
write(1, "Time's up!\n", 11)            = 11

#       
read(255, "", 64)                       = 0

Por lo tanto, tenga cuidado cuando comience a editar el script bash que se está ejecutando actualmente. Puede ejecutar el comando incorrecto o hacer algo muy inesperado.

All Articles