[![Join the chat at https://gitter.im/jlevy/the-art-of-command-line](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
La fluidez en el terminal es una destreza a menudo abandonada y considerada arcaica, pero esta mejora su flexibilidad y productividad como ingeniero en formas obvia y sutil. Esta es una selección de notas y consejos al usar el terminal que encontré útiles al trabajar en Linux. Algunos consejos son elementales y algunos bastante específicos, sofisticados u oscuros. Esta página no es larga, pero si usa y recuerda todos los puntos aquí mostrados, usted sabrá un montón.
pero debido al interés mostrado, parece que vale la pena usar Github, donde existen personas más talentosas que fácilmente pueden sugerir mejoras. Si ve un error o algo que podría ser mejor, por favor, cree un issue o PR! (Por supuesto revise la sección meta de PRs/issues primero.)
- Esta guía es tanto para el principiante como para el experimentado. Los objetivos son *diversidad* (todo importa), *especificidad* (dar ejemplos concretos del caso más común), y *concisión* (evitar cosas que no son esenciales o insignificantes que pueda buscar en otro lugar fácilmente). Cada consejo es esencial en alguna situación o significativamente ahorra tiempo comparada con otras alternativas.
- Esta escrito para Linux, con excepción de la sección "[Solo para MacOS X](#macos-x-only)". Muchos de los otros puntos aplican o pueden ser instalados en otros Unices o MacOS (o incluso Cygwin).
- Esta incluye tanto comandos "estándar" Unix así como aquellos que requieren la instalación especial de un paquete -- siempre que sea suficientemente importante para ameritar su inclusión.
- Para mantener esto en una página, el contenido está incluido implícitamente por referencia. Usted es suficientemente inteligente para ver profundamente los detalles en otros lugares, cuando conoce la idea o comando en Google. Usar `apt-get`/`yum`/`dnf`/`pacman`/`pip`/`brew` (según proceda) para instalar los nuevos programas.
- Aprenda conocimientos básicos de Bash, de hecho, escriba `man bash` y al menos échele un vistazo a toda la cosa. Es bastante fácil de seguir y no es tan largo. Alternar entre shells puede ser agradable, pero Bash es poderoso y siempre está disponible (conocer *solo* zsh, fish, etc., aunque resulte tentador en tu propia laptop, le restringe en muchas situaciones, tales como el uso de servidores existentes).
- Aprenda bien al menos un editor de texto, idealmente Vim (`vi`), como no hay realmente una competencia para la edición aleatoria en un terminal (incluso si usa Emacs, un gran IDE, o un editor alternativo (hipster) moderno la mayor parte del tiempo).
- Conozca como leer la documentación con `man` (Para curiosos, `man man` lista las secciones enumeradas, ej. 1 es comandos "regulares", 5 son archivos/convenciones, y 8 para administración). Encuentra páginas de man con `apropos`. Sepa que alguno de los comandos no son ejecutables, sino Bash builtins, y que puede obtener ayuda sobre ellos con `help` y `help -d`.
- Aprenda sobre redirección de salida `>`, entrada `<` y pipes `|`. Sepa que `>` sobrescribe el archivo de salida y `>>` añade. Aprenda sobre stdout y stderr.
- Aprenda sobre expansión de archivos glob con `*` (y tal vez `?` y `{`...`}`) y quoting y la diferencia entre dobles `"` y simples `'` quotes. (Ver más en expansión de variables más abajo.)
- Administración de archivos básica: `ls` y `ls -l` (en particular, aprenda el significado de cada columna en `ls -l`), `less`, `head`, `tail` y `tail -f` (o mejor aun, `less +F`), `ln` y `ln -s` (aprenda las diferencias y ventajas entre enlaces hard y soft), `chown`, `chmod`, `du` (para un resumen rápido del uso del disco: `du -hs *`). Para administración de archivos de sistema, `df`, `mount`, `fdisk`, `mkfs`, `lsblk`.
- Conozca bien las expresiones regulares y varias opciones (flags) para `grep`/`egrep`. Las opciones `-i`, `-o`, `-v`, `-A`, y `-B` son dignas de ser recordadas.
- Aprenda el uso de `apt-get`, `yum`, `dnf` o `pacman` (dependiendo de la distribución "distro") para buscar e instalar paquetes. Y asegúrate que tienes `pip` para instalar herramientas para la línea de comandos basadas en Python (un poco más abajo esta explicado como instalar vía `pip`).
- En Bash, se usa **ctrl-w** para borrar la última palabra, y **ctrl-u** para borrar todo el camino hasta el inicio de la línea. Se usa **alt-b** y **alt-f** para moverse entre letras, **ctrl-a** para mover el cursor al principio de la línea, **ctrl-e** para mover el cursor al final de la línea, **ctrl-k** para eliminar hasta el final de la línea, **ctrl-l** para limpiar la pantalla. Vea `man readline` para todos los atajos de teclado por defecto en Bash. Son una gran cantidad. Por ejemplo **alt-.** realiza un ciclo a través de los comandos previos, y **alt-*** expande un glob.
- Para ver los últimos comandos, `history`. También existen abreviaciones, tales como, `!$` (último argumento) y `!!` último comando, aunque son fácilmente remplazados con **ctrl-r** y **alt-.**.
- Si está a mitad de camino de escribir un comando pero cambias de opinión, presiona **alt-#** para agregar un `#` al principio y lo agrega como comentario (o use **ctrl-a**, **#**, **enter**). Asi despues puede regresar al comando vía comando `history`.
- Se usa `xargs` (or `parallel`). Esto es muy poderoso. Nota: puede controlar muchos elementos ejecutados por línea (`-L`), también es conocido como paralelismo (`-P`). Si no está seguro de que este sea el camino correcto, use `xargs echo` primero. También, `-I{}` es cómodo. Ejemplos:
- Conozca varias señales que pueda enviar a los procesos. Por ejemplo, para suspender un proceso, use `kill -STOP [pid]`. Para la lista completa, consultar `man 7 signal`.
- En scripts Bash, use `set -x` para depurar la salida. Use el modo estricto cuando se posible. Use `set -e` para abortar en caso de errores. Use `set -o pipefail` también, para ser estrictos sobre los errores (aunque este tema es un poco delicado). Para scripts más complejos, también se puede utilizar `trap`.
- En scripts Bash, subshells (escritos con paréntesis) son maneras convenientes de agrupar los comandos. Un ejemplo común es para moverse temporalmente hacia un directorio diferente del de trabajo, Ej.
- En Bash, considere que hay muchas formas de expansión de variables. Verificar la existencia de una variable: `${name:?error message}`. Por ejemplo, si un script Bash requiere un único argumento, solo escriba `input_file=${1:?usage: $0 input_file}`. Expansión aritmética: `i=$(( (i + 1) % 5 ))`. Secuencias: `{1..10}`. Reducción de strings: `${var%suffix}` y `${var#prefix}`. Por ejemplo si `var=foo.pdf`, entonces `echo ${var%.pdf}.txt` imprime `foo.txt`.
- En Bash, redireccionar salida estándar y error estándar, vía: `some-command >logfile 2>&1`. Frecuentemente, para garantizar que un comando no haya dejado abierto un archivo para controlar la entrada estándar, vinculada al terminal en el que te encuentras, también es una buena práctica agregar `</dev/null`.
- Use `man ascii` para una buena tabla ASCII, con valores hexadecimal y decimales. Para información de codificación general, `man unicode`, `man utf-8`, y `man latin1` son de utilidad.
- Use `screen` o [`tmux`](https://tmux.github.io/) para multiplexar la pantalla, especialmente útil en sesiones ss remotas y para desconectar y reconectar a una sesión. Una alternativa más minimalista para persistencia de la sesión solo sería `dtach`.
- Puede ser útil hacer algunas optimizaciones a su configuración ssh; por ejemplo, `~/.ssh/config`, contiene la configuración para evitar desconexiones en ciertos entornos de red, utiliza compresión (cual es útil con scp sobre conexiones con un ancho de banda pequeño), y la multiplexión de canales para el mismo servidor con un archivo de control local:
- Unas pocas otras opciones relevantes para ssh son sensibles en cuanto a seguridad y deben ser usadas con cuidado, Ej. por subnet, host o en redes confiables: `StrictHostKeyChecking=no`, `ForwardAgent=yes`.
- Para obtener permiso sobre un archivo en forma octal, el cual es útil para la configuración del sistema pero no disponible con `ls` y fácil de estropear, use algo como
- Para selección interactiva de valores desde la salida de otro comando, use [`percol`](https://github.com/mooz/percol) o [`fzf`](https://github.com/junegunn/fzf).
- Para la interacción con archivos basados en la salida de otro comando (como `git`), use `fpp` ([PathPicker](https://github.com/facebook/PathPicker)).
- Para ejecutar un comando con privilegios, usando `sudo` (para root) o `sudo -u` (para otro usuario). Usar `su` o `sudo bash` para realmente ejecutar un shell como este usuario. Usar `su -` para simular un login fresco como root u otro usuario.
- Para localizar un archivo por nombre en el directorio actual, `find . -iname '*something*'` (o similar). Para encontrar un archivo en cualquier lado por nombre, use `locate something` (pero tenga en mente que `updatedb` quizás no haya indexado recientemente los archivos creados).
- Para Amazon S3, [`s3cmd`](https://github.com/s3tools/s3cmd) es conveniente y [`s4cmd`](https://github.com/bloomreach/s4cmd) es el mas rápido. Hecho por Amazon [`aws`](https://github.com/aws/aws-cli) es esencial para otras tareas relacionadas al AWS.
- Sepa que `locale` afecta muchas herramientas de la línea de comandos en forma delicada, incluyendo el orden del ordenamiento (compaginación) y rendimiento. La mayoría de las instalaciones de Linux configuran `LANG` u otras variables de localización para la configuración local como US English. Pero tenga en cuenta que el ordenamiento va a cambiar si cambia `locale`. Y también las rutinas i18n pueden hacer que `sort` u otros comandos se ejecuten *muchas veces* más lentos. En algunas situaciones (tales como la realización de operaciones u operaciones singulares debajo) puede de forma segura ignorar las lentas rutinas i18n por completo y utilizar el sort tradicional basado en byte, usando `export LC_ALL=C`.
- Conozca aspectos básicos de `awk` y `sed` para manejo de datos. Por ejemplo, sumar todos lo números en la tercera columna de un archivo de texto: `awk '{ x += $3 } END { print x }'`. Esto es probablemente 3 veces más rápido y 3 veces más corto que su equivalente en Python.
- Para renombrar varios archivos a la vez de acuerdo a un patrón, usar `rename`. Para renombramientos complejos, [`repren`](https://github.com/jlevy/repren) puede ayudar.
- Conozca las opciones de `sort`. Para números, use `-n`, o `-h` para manipulación de números humanamente leíbles (Ej. desde `du -h`). Conozca ecomo trabajan `-t` y `-k`. En particular, este atento a que necesitará escribir `-k1,1` para ordenar por solo el primer campo; `-k1` significa ordenar de acuerdo a toda la línea. Orden estable (`sort -s`) puede ser útil. Por ejemplo, para ordenar primero por el campo 2, luego secundariamente hacerlo por el campo 1, Puedes usar `sort -k1,1 | sort -s -k2,2`.
- Si alguna vez necesita escribir un tab literal en una línea de comandos en Bash (Ej. para el argumento -t para 'sort'), presione **ctrl-v****[Tab]** o escriba `$'\t'` (el último es mejor porque puede copiarlo/pegarlo).
- Las herramientas estándar para reparar el código fuente son `diff` y `patch`. Ver también `diffstat` para resumen estadístico de una diff. Note que `diff -r` trabaja completamente con directorios. Usar`diff -r tree1 tree2 | diffstat` para un resumen de cambios.
- Para convertir la codificación del texto, probar `iconv`. O `uconv` para uso más avanzado; este soporta algunos elementos Unicode avanzados. Por ejemplo, este comando coloca en minúsculas y remueve todas los acentos (expandiéndolos y colocándolos):
- Para depuración web, `curl` y `curl -I` son prácticos, o sus equivalentes en `wget`, o el más moderno [`httpie`](https://github.com/jakubroztocil/httpie).
- Para conocer el estado del disco/cpu/red, usar `iostat`, `netstat`, `top` (o el mejor `htop`), y (especialmente) `dstat`. Bueno para recibir una idea rápida de qué está pasando en un sistema.
- Para una visión general en mayor profundidad, usar [`glances`](https://github.com/nicolargo/glances). Este se presenta con varios niveles de estadística en un solo terminal. Muy útil para una verificación rápida de varios subsistemas.
- Para conocer el estado de la memoria, ejecutar y entender la salida de `free` y `vmstat`. En particular, tener en cuenta el valor "en caché" es mantenido en memoria por el kernel Linux como un archivo de cache, por lo que efectivamente cuenta como valor para "free".
- El sistema de depuración de Java es harina de otro costal, pero un truco simple en las JSM de Oracle y otros consta en que puedes ejecutar `kill -3 <pid>` y una traza completa y un resumen del montículo "heap summary" (incluyendo del detalle de la colección de basura generacional, la cual puede ser altamente informativa) serán descargados al stderr/logs. Las herramientas `jps`, `jstat`, `jstack`, `jmap` del JDK son útiles. [SJK tools](https://github.com/aragozin/jvm-tools) son más avanzadas.
- La herramienta `ab` (viene con Apache) es útil para una verificación "rápida y sucia" del rendimiento del servidor web. Para pruebas de carga más complejas, pruebe `siege`.
- Conozca acerca de `strace` y `ltrace`. Estas puede ser de utilidad si un programa está fallando, está suspendido, o está "congelado/colgado/crasheado", y no sabe por qué, o si quieres tener una idea general del rendimiento. Note la opción de elaboración de perfiles, o "profiling", (`-c`), y la habilidad de adjuntar a un proceso en ejecución (`-p`).
- Usar `/proc`. Es extraordinariamente útil algunas veces cuando se depuran problemas en vivo. Ejemplos: `/proc/cpuinfo`, `/proc/xxx/cwd`, `/proc/xxx/exe`, `/proc/xxx/fd/`, `/proc/xxx/smaps`.
- Para analisis de sistemas y de rendimiento mas profundos, vea `stap` ([SystemTap](https://sourceware.org/systemtap/wiki)), [`perf`](http://en.wikipedia.org/wiki/Perf_(Linux)), y [`sysdig`](https://github.com/draios/sysdig).
- Es notablemente útil en ocasiones que pueda realizar intersección, unión, y diferencia de conjuntos de archivos de texto vía `sort`/`uniq`. Suponga `a` y `b` como archivos de texto que son únicos. Esto es rápido, y trabaja con archivos de tamaño arbitrario, hasta varios gigabytes. (Sort no está limitado por la memoria, aunque quizás necesite utilizar la opción `-T` si `/tmp` está en una pequeña partición de raíz.) Vea también la nota acerca de `LC_ALL` y las opciones de `sort`, `-u` (dejado de lado para clarificar más abajo).
- Usar `grep . *` para examinar visualmente todos los contenidos de todos los archivos en un directorio, por ejemplo, para directorios llenos con parámetros de configuración, como `/sys`, `/proc`, `/etc`.
- Sumar todos los números en la tercera columna de un archivo de texto (esto es probablemente 3 veces más rápido y 3 veces menos código que el equivalente en Python):
- Digamos que tiene un archivo de texto, como un log de un servidor web, y un cierto valor comienza a aparecer en algunas líneas, tales como un parámetro `acct_id` que está presente en la URL. Si quieres un recuento de cuantas peticiones ("request") hay por cada `acct_id`:
-`sponge`: lee todas las entradas antes de escribirlo, útil para vista previa y posterior escritura sobre el mismo archivo, Ej., `grep -v something some-file | sponge some-file`
- Administración de paquetes con `brew` (Homebrew) y/o `port` (MacPorts). Estos pueden ser utilizados para instalar en MacOS muchos de los comandos de arriba.
- Tenga en cuenta que MacOS está basado en BSD Unix, y muchos comandos (por ejemplo `ps`, `ls`, `tail`, `awk`, `sed`) tienen muchas variaciones discretas respecto de Linux, que está en gran parte influenciado por el sistema Unix V-style y herramientas GNU. Comunmente puede diferenciar al notar que una página man tienen el encabezado "BSD General Commands Manual." En algunos casos versiones GNU pueden ser instaladas también (tales como `gawk` y `gsed` para GNU awk y sed). Si escribe scripts Bash multiplataforma, evite tales comandos (por ejemplo, considere Python o `perl`) o probar cuidadosamente.
Con la excepción de tareas muy pequeñas, el código está escrito para que otros puedan leerlo. Con el poder llega la responsabilidad. El hecho de que usted *puede* hacer algo en Bash no necesariamente significa que deba hacerlo! ;)