Supongamos que escribí un script bash con el nombre delay.sh
. ¿Qué crees que hace?#!/bin/bash
sleep 30
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 30
a 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 r
en su #rm
lugar #
. 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
read(3, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 80) = 64
lseek(3, 0, SEEK_SET) = 0
dup2(3, 255) = 255
read(255, "#!/bin/bash\nsleep 30\n#echo \"Don'"..., 64) = 64
lseek(255, -43, SEEK_CUR) = 21
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 2072
read(255, "echo \"Don't execute me\"\necho \"Ti"..., 64) = 42
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.