Empieza todos los comandos con una coma (2009)
(rhodesmill.org)- Cuando un usuario de Unix pone scripts personales en
~/bin/y lo agrega alPATH, los nombres cortos de comandos pueden chocar con nuevos comandos del sistema - En entornos con muchos comandos disponibles, como Debian/Ubuntu, el riesgo aumenta; en una laptop Ubuntu de ejemplo se contabilizaron 21,733 comandos en
/usr/bin - Si a los comandos personales se les antepone una coma (
,), el shell y las herramientas la tratan como un carácter normal de nombre de archivo, pero al mismo tiempo permite distinguirlos fácilmente de los comandos del sistema - La coma puede escribirse sin usar Shift y tiene menos posibilidades de conflicto que paréntesis, barra invertida, dos puntos, acento grave, comilla simple, barra diagonal o punto, que tienen significados fuertes en el shell
- Si presionas Tab después de
,, puedes recorrer de inmediato la lista de comandos personales, lo que facilita mantener ordenados los nombres de comandos en~/bin/
Por qué chocan los nombres de los comandos personales
- Muchos usuarios de Unix crean
~/bin/en su directorio personal y lo agregan alPATHpara usar comandos de conveniencia y scripts de shell propios - El problema es que los nombres de scripts personales suelen ser combinaciones cortas en minúsculas, así que se parecen con facilidad a los comandos básicos del sistema
- Cuando una distribución de Linux agrega un comando nuevo, puede ocurrir que coincida por casualidad con el nombre de un comando personal ya existente
- En entornos de la familia Debian, donde hay una gran cantidad de comandos disponibles, este problema se vuelve más real
- En una laptop Ubuntu de ejemplo, al contar los comandos directamente bajo
/usr/binaparecen21,733 apt-file search -x '^/usr/bin/[^/]*$' | wc -l
- En una laptop Ubuntu de ejemplo, al contar los comandos directamente bajo
Ventajas del prefijo con coma
- La solución es cambiar los nombres de los comandos personales a una forma que sea fácil de escribir, pero que al mismo tiempo sea poco probable como nombre de comando del sistema
- El criterio de facilidad de escritura es no usar la tecla Shift, y aun cumpliendo esa condición no hay muchos caracteres seguros
- Las letras minúsculas ya se usan con frecuencia en comandos del sistema
- Los paréntesis, la barra invertida, los dos puntos, el acento grave y la comilla simple tienen significados especiales en el shell
- La barra diagonal es un separador de directorios, así que no puede ir dentro de un nombre de archivo
- El punto al inicio del nombre indica un archivo oculto y, en otras posiciones, también se usa mucho para separar extensiones
- La opción que queda es la simple coma (
,), y tanto las herramientas del entorno como el shell la tratan como un carácter normal dentro de un nombre de archivo - Si cada comando personal lleva una coma como prefijo, queda claramente diferenciado de los comandos del sistema y se vuelve más fácil evitar choques de nombres
- Usado junto con el autocompletado con Tab, basta escribir
,para ver de inmediato la lista de comandos personales- La lista de ejemplo incluye
,complete-scp,,complete-ssh,,coreoff,,coreon,,find,,go-thpgp,,gr,,hss,,mount-thpgp,,mount-twt,,range,,svn-store-password,,umounty otros
- La lista de ejemplo incluye
- Este método se ha usado durante unos 10 años y se recomienda como una forma de mantener limpios y ordenados los nombres de comandos personales en
~/bin/
2 comentarios
Opiniones de Hacker News
Al ver solo el título pensé que sería una idea terrible, pero en la práctica me gusta bastante. En especial me gustó la parte de listar todas mis herramientas con Tab.
Últimamente no he tenido muchos choques de namespaces y, la verdad, después de pasarme a un puesto de gestión, también se me aflojó un poco el instinto técnico. Siento que mi stack técnico está unos 10 años desactualizado, y me pregunto por dónde convendría empezar para volver a ponerme al día.
Mi enfoque es crear herramientas que me hagan la vida más fácil. Por ejemplo, si en la empresa hay un servicio web que uso a menudo para consultas simples, reviso si tiene API y escribo una CLI para acelerar tareas cotidianas. Después de pulirla a mi gusto, la comparto con el equipo, pero convencer a otros de probarla es difícil. Aun así, como la uso todos los días, no me preocupa demasiado.
El objetivo era ver nuevas perspectivas y poder conversar sobre tendencias, y parte de eso ya terminó llegando al trabajo. Además, me ayudó a entender más a fondo los componentes antiguos.
No termino de entender este problema. Basta con poner mi directorio
binal principio de$PATH, no al final. Para revisar mis comandos, simplemente ejecutols ~/bin.$0esté en una ruta del sistema, eso se rompe y empieza una depuración frustrante.Al final es cuestión de elegir tu veneno.
fzf. Por ejemplo, en fish puedes escribir la primera letra de un comando y presionar Tab para abrirfzf.Así, con solo
,+Tab puedes filtrar rápidamente los comandos personalizados. En cambio,ls ~/binrequiere escribir muchas más letras para algo que haces con frecuencia, o quizá primero tengas que encontrar el autocompletado conls+flecha arriba varias veces.ls ~/bines muchísimo más lento que escribir,.Yo uso nombres cortos de comandos personalizados como
aa,st,di,dp,cm,lepara wrappers delgados alrededor degit.Uno de ellos choca de verdad con una utilidad instalada por defecto en algún sistema. Aun así, como mi directorio
binestá antes que los directorios del sistema en$PATH, el mío gana, y esa herramienta en conflicto no me interesa mucho. Si alguna otra herramienta útil para mí chocara con una de las mías, probablemente le pondría a esa otra herramienta un alias sin conflicto antes que cambiar el nombre de mi herramienta. Estas herramientas de dos letras son demasiado cómodas.apt-get upgradeejecute Dwarf Fortress.https://askubuntu.com/questions/938606/dwarf-fortress-starti...
gitsuelen ser combinaciones de dos letras que empiezan cong. Por ejemplo,gsesgit status.Pero a veces sí necesito GhostScript de verdad. Es excelente para cosas como incrustar fuentes en archivos PDF. Normalmente en esos casos uso
env gs.j. Cuando apareciójava, se puso bastante divertido. Usar una coma es una idea bastante interesante.Aun así, me alegra no haber empezado con
k, por KDE :)Por ejemplo, creo que
mkfsdebería invocarse como algo tiposys::mkfs. La línea entre comandos del sistema y comandos del usuario podría definirse de muchas maneras y habría zonas grises, pero si un usuario puede ejecutar accidentalmente un comando que ni siquiera sabía que existía y que nunca instaló explícitamente, entonces ese comando no debería estar expuesto directamente en el namespace global.Hay una pregunta relacionada
Yo uso Windows la mayor parte del tiempo y, como el autor, hice varios scripts CLI centrados en Python y los puse en el equivalente a
~/bin/. Si configuropython.execomo el programa predeterminado para la extensión.pyy agrego.pya%pathext%, puedo ejecutar~/bin/hello.pydesde cualquier ruta escribiendo solohello, y lo uso cientos de veces al día. Últimamente uso más Linux, pero todavía soy principiante y no logré hacerlo de la misma manera. En Linux no parece existir el concepto de “programa asociado”, así que no puedo simplemente invocar un archivo.pyy hacer que el shell lo ejecute con Python. Claro que puedo darlechmod +xal script, pero entonces tengo que poner un shebang en el propio script, y eso me incomoda porque se siente como hardcodear. Me pregunto qué pasaría si más adelante quisiera ejecutar un script.pycon/usr/bin/nohtypen vez de/usr/bin/python. Además, tampoco encontré una forma de omitir la parte.pyal invocar el script. No intento criticar el diseño de Linux, y sé que tiene muchas ventajas, pero de verdad quiero ejecutar comohellounhello.pyque está en$PATHmy_pythonen alguna ruta y usar/usr/bin/env my_pythoncomo shebangSi quieres un enfoque más principista, mira la herramienta
update-alternatives. Ofrece este tipo de abstracción de forma más general: https://linuxconfig.org/how-to-set-default-programs-using-up...En Linux —y, de hecho, en la mayoría de las plataformas fuera de Windows— el significado de las extensiones de archivo es mucho más débil. La posibilidad de ejecutar cualquier tipo de archivo ejecutable no la determina la extensión, sino cosas como el flag
+x. Gracias a eso, puedes reescribirlo cambiando el lenguaje de implementación sin romper a quien lo invoca. La extensión.pysolo tiene sentido para módulos que se importan y usan; si es un script que se ejecuta, basta con mirar el shebang cuando sea necesario. Los scripts distribuidos externamente suelen usar#!/usr/bin/env python, y los scripts incluidos en paquetes de una distribución se suelen sobrescribir con algo como#!/usr/bin/python. Además, el shebang no admite varios argumentos, pero GNUenvadmite el argumento-S, que puede imitarlo. Aun así, queda el problema de la longitud de los argumentos.pyal nombre del archivo. Llamarlo"hello"está perfectamente bienNo se me ocurren muchas desventajas del shebang. Si de verdad quieres ejecutarlo con otro intérprete, puedes hacerlo explícito, como
"nohtyp hello". Si aun así te molesta demasiado, puedes definir un alias en el archivo de inicio del shell. Por ejemplo, en bash podrías haceralias hello="python3 /path/to/hello.py". Si quisieras, incluso podrías escribir un script corto que genere automáticamente estos alias para el contenido de un directorio determinadoEn scripts de shell, lo usual es agregar un shebang y hacer ejecutable el archivo, declarando el ejecutable dentro del propio script. Puedes pensar en el shebang como una especie de extensión de archivo. Si después de
chmod +x ./malware.pyno funciona./malware.py, revisa la ruta a la que apunta el shebang. Si el intérprete puede ejecutar el script como un argumento normal, también podrías lograr algo parecido conxdg-open malware.py. Sería lo mismo que hacer doble clic en el administrador de archivos predeterminado. Cuando usaba Linux como sistema operativo principal de escritorio, tenía un alias llamadoxop, pero lo usaba solo para archivos de datos como imágenes o documentos, donde el comportamiento predeterminado ya era el correcto. No recomiendo configurar el programa predeterminado de los scripts ejecutables como el intérprete. Quizás por defecto quieras abrir el script en un editor, no ejecutarlo. Creo quexdg-openes una herramienta del entorno Gnome, pero eso no significa que no pueda usarse en otros escritorios; yo también la usé en Xubuntu. Si de verdad quieres que todos los archivos Python se ejecuten por defecto incluso en contexto GUI, se puede configurar ese valor predeterminado, peroman xdg-openpuede ayudar. De nuevo: no es un buen consejo#!/usr/bin/env pythonAsí se ejecuta el primer
pythonque se encuentre en la ruta. Si más adelante quieres ejecutarlo con/usr/bin/nohtypen vez de/usr/bin/python, puedes crear un enlace simbólico llamadopythonque apunte a/usr/bin/nohtypen un directorio que se busque antes que/usr/bin. Por ejemplo, puedes agregar~/myCommandPreferencesal inicio de$PATHOtra forma de evitar conflictos en
$PATHes crear nombres de ejecutables muy largos, con poca probabilidad de que los use otro ejecutable, y poner alias cortos enbashrcLos alias no afectan a los ejecutables invocados dentro de los scripts, y en mis scripts puedo seguir refiriéndome a ellos por el nombre largo. La desventaja es que no se obtiene el mismo nivel de usabilidad con autocompletado por tabulación, y esa parte sí es muy buena. Además, todavía puede haber conflictos con scripts que deben ejecutarse con
sourcey no como subprocesos, como los scripts de activación devenvde Python, pero esos casos son raroszsh, ese autocompletado también funcionaEmpezar con coma es una técnica común también en las comunidades de expansores de texto/sustitución de texto
,Hace poco revisé
~/.local/bin/y descubrí decenas de ejecutables que no recordaba haber puesto ahíLa mayoría estaban relacionados con pyside, pero también había otros scripts. Tuve que abrirlos uno por uno para recordar cuáles había escrito yo y cuáles eran de otros. Si los nombres de mis scripts hubieran empezado con coma, habría sido mucho más rápido, y también me habría ayudado a recordar para qué había creado cada script antes de abrirlo
~/.local/bin/se usa para scripts instalados, y lo que escribes localmente tú mismo va en~/bin/Paso. Basta con poner mi
binpersonal al inicio de$PATHy usar/usr/bino/bincuando quiera hacer referencia a un programa que quedó ocultoLa lista de herramientas personalizadas se puede ver con
~/bin/[Tab]Si no me gusta el
grepdel sistema, por ejemplo elgrepde Solaris, y quiero usar migrepde GNU preferido, ¿por qué no simplemente dejarlo comogrep?Haber conocido esta idea hace 5 años me permitió poner orden en mi colección de trucos de shell. Entre alias y
~/bin, tengo más de 50 comandos con coma, y mi vida en la shell es mucho más fluida que antes, cuando todo estaba mezcladoTambién se discutió en 2020: https://news.ycombinator.com/item?id=22778988 (90 comentarios)
, macroexpandStart all of your commands with a comma (2009) - https://news.ycombinator.com/item?id=31846902 - junio de 2022 (121 comentarios)
Start all of your commands with a comma (2009) - https://news.ycombinator.com/item?id=22778988 - abril de 2020 (89 comentarios)
¿Qué tal usar
'_'?