Pregunta:
Nunca pensé que esto me pasaría a mí, pero ahí lo tienes. ¯\_(ツ)_/¯
Ejecuté un script de compilación desde un repositorio dentro del directorio incorrecto sin mirar primero la fuente. Aquí está el script Scripts/BuildLocalWheelLinux.sh
:
cd ../Dependencies/cpython
mkdir debug
cd debug
../configure --with-pydebug --enable-shared
make
cd ../../..
cd ..
mkdir -p cmake-build-local
cd cmake-build-local
rm -rf *
cmake .. -DMVDIST_ONLY=True -DMVPY_VERSION=0 -DMVDPG_VERSION=local_build
make -j
cd ..
cd Distribution
python3 BuildPythonWheel.py ../cmake-build-local/[redacted]/core.so 0
python3 -m ensurepip
python3 -m pip install --upgrade pip
[more pip install stuff]
python3 -m setup bdist_wheel --plat-name manylinux1_x86_64 --dist-dir ../dist
cd ..
cd Scripts
La parte peligrosa parece ser
mkdir -p cmake-build-local
cd cmake-build-local
rm -rf *
Pero pensándolo bien, en realidad parece que no podría salir mal.
La forma en que se supone que debe ejecutar este script es cd Scripts; ./BuildLocalWheelLinux.sh
. Cuando lo ejecuté por primera vez, mostró un error en la última línea (como aprendí después). Tenía prisa, así que pensé "tal vez los documentos estén desactualizados, intentaré ejecutar desde la raíz del proyecto. Así que ejecuté ./Scripts/BuildLocalWheelLinux.sh
. De repente, el tema de vscodes y el nivel de zoom cambiaron, mi terminal zsh config se restableció, las fuentes de terminal se establecieron por defecto, y presioné Ctrl + C una vez que me di cuenta de lo que estaba sucediendo.
Quedan algunos archivos, pero no tienen un patrón obvio:
$ ls -la
total 216
drwx------ 27 felix felix 4096 May 12 18:08 .
drwxr-xr-x 3 root root 4096 Apr 15 16:39 ..
-rw------- 1 felix felix 12752 Apr 19 11:07 .bash_history
-rw-r--r-- 1 felix felix 3980 Apr 15 13:40 .bashrc
drwxrwxrwx 7 felix felix 4096 May 12 18:25 .cache
drwx------ 8 felix felix 4096 May 12 18:26 .config
drwx------ 3 root root 4096 Apr 13 21:40 .dbus
drwx------ 2 felix felix 4096 Apr 30 12:18 .docker
drwxr-xr-x 8 felix felix 4096 Apr 15 13:40 .dotfiles
-rw------- 1 felix felix 8980 Apr 13 18:10 examples.desktop
-rw-r--r-- 1 felix felix 196 Apr 19 15:19 .gitconfig
-rw-r--r-- 1 felix felix 55 Apr 16 13:56 .gitconfig.old
-rw-r--r-- 1 felix felix 1040 Apr 15 13:40 .gitmodules
drwx------ 3 felix felix 4096 May 6 10:10 .gnupg
-rw-r--r-- 1 felix felix 1848 May 5 14:24 heartbeat.tcl
-rw------- 1 felix felix 1610 Apr 13 20:36 .ICEauthority
drwxr-xr-x 5 felix felix 4096 Apr 21 16:39 .ipython
drwxr-xr-x 2 felix felix 4096 May 4 09:35 .jupyter
-rw------- 1 felix felix 161 Apr 27 14:23 .lesshst
drwx------ 3 felix felix 4096 May 12 18:08 .local
-rw-r--r-- 1 felix felix 140 Apr 29 17:54 minicom.log
drwx------ 5 felix felix 4096 Apr 13 18:25 .mozilla
drwxr-xr-x 2 felix felix 4096 Apr 13 18:10 Music
drwxr-xr-x 6 felix felix 4096 May 12 17:16 Nextcloud
-rw-r--r-- 1 felix felix 52 Apr 16 11:43 .nix-channels
-rw------- 1 felix felix 1681 Apr 20 10:33 nohup.out
drwx------ 3 felix felix 4096 Apr 15 11:16 .pki
-rw------- 1 felix felix 946 Apr 16 11:43 .profile
drwxr-xr-x 2 felix felix 4096 Apr 13 18:10 Public
drwxr-xr-x 2 felix felix 4096 May 12 18:08 .pylint.d
-rw------- 1 felix felix 1984 May 12 18:06 .pythonhist
-rw-r--r-- 1 felix felix 2443 Apr 19 13:40 README.md
drwxr-xr-x 13 felix felix 4096 May 12 18:08 repos
drwxr-xr-x 6 felix felix 4096 Apr 19 11:08 snap
drwx------ 3 felix felix 4096 May 5 15:33 .ssh
drwxr-xr-x 5 felix felix 4096 Apr 26 17:39 .stm32cubeide
drwxr-xr-x 5 felix felix 4096 May 5 15:52 .stm32cubemx
drwxr-xr-x 2 felix felix 4096 Apr 23 11:44 .stmcube
drwxr-xr-x 2 felix felix 4096 Apr 13 18:10 Templates
drwxr-xr-x 3 felix felix 4096 Apr 19 11:57 test
drwxr-xr-x 2 felix felix 4096 Apr 13 18:10 Videos
-rw------- 1 felix felix 14313 May 12 10:45 .viminfo
-rw-r--r-- 1 felix felix 816 Apr 15 13:40 .vimrc
drwxr-xr-x 3 felix felix 4096 Apr 16 12:08 .vscode
-rw-r--r-- 1 felix felix 2321 Apr 19 18:47 weird_bug.txt
-rw-r--r-- 1 felix felix 162 Apr 15 13:40 .xprofile
.config
se ha ido, así como algunos directorios XDG estándar como Imágenes y Escritorio, pero .bashrc todavía está allí. .nix-channels
todavía está allí, pero .nix-defexpr
fue .nix-defexpr
.
Entonces, esto me lleva a dos preguntas:
- ¿Qué salió mal? Me gustaría arreglar este script de compilación y hacer un PR para evitar que esto suceda en el futuro.
- ¿En qué orden se eliminaron los archivos? Obviamente no en orden alfabético, pero
*
expande en orden alfabético, así que parece que algo más está sucediendo aquí.
Respuesta:
Ay. No eres la primera víctima .
¿Qué salió mal?
Comenzando en su directorio personal, por ejemplo, /home/felix
, o incluso en /home/felix/src
o /home/felix/Downloads/src
.
cd ../Dependencies/cpython
Falló porque no hay ../Dependencies
.
mkdir debug cd debug
Ahora se encuentra en el subdirectorio debug
del directorio desde el que comenzó.
../configure --with-pydebug --enable-shared make
No hace nada porque no hay ../configure
o make
.
cd ../../.. cd ..
Si comenzó con no más de tres niveles de directorio, con cd debug
alcanzando un cuarto nivel, el directorio actual es ahora el directorio raíz. Si comenzó con cuatro niveles de directorio, el directorio actual es ahora /home
.
mkdir -p cmake-build-local
Esto falla porque no tienes permiso para escribir en /
o /home
.
cd cmake-build-local
Esto falla porque no hay un directorio cmake-build-local
.
Ahora llegamos a …
¿En qué orden se eliminaron los archivos?
rm -rf *
Esto intenta eliminar de forma recursiva todos los archivos del directorio actual, que es /
o /home
. Los directorios de inicio se enumeran en orden alfabético, pero los archivos que se encuentran debajo se enumeran en el orden arbitrario de recorrido de directorio. Es el mismo orden que ls --sort=none
(a menos que rm
decida usar un orden diferente por alguna razón). Tenga en cuenta que este orden generalmente no se conserva en las copias de seguridad y puede cambiar cuando se crea o elimina un archivo en el directorio.
Cómo arreglar el guión
Primero, casi cualquier script de shell debería tener set -e
cerca de la parte superior. set -e
hace que el script se anule si falla un comando. (Un comando falla si su estado de salida es distinto de cero). set -e
no es una panacea, porque hay circunstancias en las que no entra en vigor. Pero es lo mínimo que puede esperar y habría hecho lo correcto aquí.
(Además, el script debe comenzar con una línea shebang para indicar qué shell usar, por ejemplo, #!/bin/sh
o #!/bin/bash
. Pero eso no ayudaría con este problema).
rm -rf *
, o variantes como rm -rf $foo.*
(¿y si $foo
resulta estar vacío?), son frágiles. Aquí, en lugar de
mkdir -p cmake-build-local
cd cmake-build-local
rm -rf *
Sería más robusto eliminar y volver a crear el directorio. (Esto no preservaría los permisos en el directorio, pero aquí esto no es una preocupación).
rm -rf cmake-build-local
mkdir cmake-build-local
cd cmake-build-local
Otra forma es más robusta contra la eliminación de archivos incorrectos, pero más frágil contra archivos faltantes para eliminar: elimine solo los archivos que se sabe que se han creado, ejecutando make clean
que tiene comandos rm
para objetivos de compilación conocidos y para extensiones conocidas (por ejemplo, rm *.o
está bien).