DÍA 2 / 2017

La línea de comandos es el futuro

La llegada al mundo del front de runner tasks como "Grunt" y "Gulp" y de ecosistemas como "NPM" han obligado a mucha gente a usar de manera habitual una Terminal.


La llegada al mundo del front de runner tasks como Grunt y Gulp y de ecosistemas como NPM han obligado a mucha gente a usar de manera habitual una Terminal. Aun así muchos siguen opinando que es fea. Que no es usable(?). Que es para gente de sistemas. Que es para los de Linux. O simplemente me replican diciendo ¡Estas todo el día escribiendo!

Mi relación con la Terminal empezó bastante mal. En un capítulo de Carmen San Diego uno de los personajes introducía un montón de comandos en un ordenador. En aquella época de VHS, en casa intentabamos grabar todos los dibujos que podíamos. Así que volví a ver el capítulo y apunte todos los comandos. Encendí mi AMSTRAD CPC 464 de 64k, hasta entonces mi única interacción con el era introducir cintas de cassette y ver como iban pasando las vueltas hasta que se cargaba el Ikari Warriors/Gauntlet/Commando. Metí el primer comando y nada. El segundo tampoco. Y el tercero lo mismo. La frustración me acompañaría durante décadas.

Voy a intentar aprovechar este artículo para hacer una introducción de todo lo que uso en mi día a día para simplificar el máximo de tareas repetitivas y tediosas. Mi máxima es que si repito algo más de dos veces al día me creo un alias o con un poco de tiempo un script con bash o applescript. Espero quitar los miedos que tiene la gente cuando empieza a usar el Terminal, e intentar acercaros al divertido mundo de escribir comandos en una Terminal.

Terminal

Tenemos varias opciones a nuestra disposición. Podemos usar la aplicación de la Terminal que viene por defecto en macOS. También tenemos a nuestra disposición iTerm2, la desventaja es que solamente esta para macOS. Y últimamente mucha gente se esta pasando a Hyper, esta si que tiene versiones tanto para Windows, Linux y macOS.

iTerm2

Es una Terminal gratuita con muchas más características que las que viene por defecto con macOS. Es un fork del antiguo iTerm. Y el código como se pudo comprobar hace unas semanas esta auditado por la comunidad.

Funcionalidades:

  • Crear múltiples ventanas cada una con una sesión diferente
  • Búsqueda
  • Autocompletado con ⌘ + alt + ;
  • Buscar y pegar. Buscamos un texto, una vez seleccionado presionamos alt + enter, y se copiara el texto seleccionado
  • Paste histoty. Hay que activarlo desde el menu toolbet. Para acceder al menú presionamos ⇧ + ⌘ + H
  • Ocultar y mostrar el Terminal con un atajo de teclado

Hyper

Hyper es una Terminal relativamente joven. Esta desarrollada con Electron. Lo bueno de Hyper es que esta disponible para macOS, Linux y Windows. Hyper es muy configurable y con una comunidad muy activa generando una multitud de plugins.

Shell

Una shell es una interprete de comandos, en este caso de la línea de comandos, seguro que alguno vez has leído su acrónimo en ingles, CLI(Command line interface). Por suerte tenemos variedad donde elegir.

La archiconocida Bash(bourne shell again) es la que viene por defecto en muchas distribuciones de Linux y macOS.

Me voy a centrar en ZSH que es la que uso desde hace un tiempo.

Antes de continuar os muestro mi Terminal con iTerm2 y ZSH:

ZSH

ZSH se podría considerar como una version extendida de Bash. En macOS viene instalada por defecto una version de ZSH aunque no es la última. Si quieres actualizar a la última version(5.4.1) puedes hacerlo a través de Homebrew.

brew install zsh

Para usar la última version vamos a ejecutar el siguiente comando:

sudo dscl . -create /Users/$USER UserShell /usr/local/bin/zsh

Para que surta efecto reiniciamos el Terminal.

Ahora vamos a cambiar Bash por ZSH.

Desde la app de Terminal de macOS vamos a las preferencias y en general añadimos:

/bin/zsh

Desde iTerm2 vamos a Preferences > Profiles > General y en Command añadimos:

/bin/zsh

Desde Hyper vamos a preferencias. Aquí las preferencias están en un archivo JavaScript:

// the shell to run when spawning a new session (i.e. /usr/local/bin/fish)
// if left empty, your system's login shell will be used by default
shell: '',

Vamos a ver alguna de las características de ZSH.

  • No tenemos que escribir cd para entrar en un directorio, solo tenemos que escribir el nombre del directorio.
  • Para salir de un directorio tampoco tenemos que escribir cd, escribimos ".."
  • Autocompletado con cd
  • Cargar scripts al iniciar sesión con .zlogin o al salir de la sesión con .zlogout

Oh-my-zsh

Oh my Zsh! es un framework open source para añadir más configuraciones a ZSH. Vamos a poder elegir entre una serie de temas para modificar colores y el PROMPT. También podemos elegir entre más de 200 plugins.

Para instalar ejecutamos el siguiente comando:

$ sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Una vez instalado nos vamos a centrar en la configuración. Para modificar nuestra configuración lo podemos hacer a través de un editor como Sublime, Atom o nano.

#Usando Sublime
sublime ~/.zshrc

#Usando nano
nano ~/.zshrc

#Usando Atom
atom ~/.zshrc

Lo primero que se suele hacer es cambiar el tema de nuestra Terminal. En el repositorio de Oh my Zsh! podéis ver unas cuantas capturas de como queda cada tema y como queda el PROMPT. En mi caso uso ys:

# Set name of the theme to load.
# Look in ~/.oh-my-zsh/themes/
# Optionally, if you set this to "random", it'll load a random theme each
# time that oh-my-zsh is loaded.
ZSH_THEME="ys"

Plugins

Tenemos a nuestra disposición más de 200 plugins. En la propia Wiki podemos ver lo que hace cada plugin. Ahora os voy a enseñar lo que yo uso. El método para ir cargando plugins es sencillo. Después de la plugins escribiremos los nombres de los plugins separados por un espacio.

plugins=(git github osx alias-tips)

Una advertencia que la propia documentación indica, cuantos más plugins menos velocidad al inicio.

# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(git github osx alias-tips)

Git

Si usas git a través del Terminal este es tu plugin. Una infinidad de alias para hacerte la vida más fácil.

Github

Muy parecido al de git pero para controlar tus repositorios de GitHub a través del Terminal. Este plugin te instala la gema de Github

OSX

Añade unos cuantos comandos para controlar OSX desde el Terminal.

Alias tip

Si tu escribes un comando en el Terminal y este tiene un alias el plugin te recordara el alias. Muy útil cuando se te ha ido de las manos la creación de alias.Link

PowerLevel9k

El plugin más completo para customizar el PROMPT del Terminal.Link.

Zplug

Es un plugin para gestionar todos los plugins que tenemos instalados con ZSH. Es perfecto para ir cargando los diferentes plugins que vamos añadiendo y también para mantenerlos actualizados.

Alias

Un alias nos sirve para almacenar comandos largos o repetitivos que usamos a lo largo del día. Por ejemplo para acceder a la configuración de Oh my zsh!

alias zshconfig="sublime ~/.zshrc"

Así que primero escribimos alias, seguido de un nombre (relativamente corto o descriptivo) y entre comillas la acción que se ejecutará.

alias nombredelalias="comando que se ejecuta"

Ahora ya dejo volar a tu imaginación para que te crees los alias que a ti te apetezca. Como por ejemplo, este que utilizo para dejar el mac en reposo:

alias afk="/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend"

O este otro para hacer una actualización de macOS, Brew, NPM y Gem.

#Update masivo actualizaciones OSX, Brew, **NPM** y GEM.
alias update="
sudo softwareupdate -i -a;
brew update;
brew upgrade;
brew cleanup;
**NPM** install **NPM** -g;
**NPM** update -g;
sudo gem update --system;
sudo gem update;
sudo gem cleanup"

Un consejo es ir ordenando los alias e ir incluyendo comentarios descriptivos.

Aquí podéis consultar todos los que me he ido creando.

Otros alias

ZSH tiene otros dos tipos de alias bastante útiles. El primero de ellos son los alias Suffix.

Vamos a ver un ejemplo y lo explico a continuación:

alias -s git='git clone'

La diferencia con los alias normales es que llevan el flag o bandera -s. Y que lo que sigue al flag corresponde a la extensión de un archivo. En este a caso a un archivo .git, por último, lo que esta entre las comillas es la acción que se ejecutara.

Algo que hacemos a menudo, clonar un repositorio de git. Con este alias cuando copiamos en nuestro Terminal un archivo con la extensión .git y presionamos el enter siempre se ejecutara un git clone. Así nos ahorramos escribir git clone https://github.com/perico/delospalotes.git

Otro ejemplo:

alias -s css='subl'

Cada vez que escribimos o copiamos en nuestra Terminal un archivo con la extensión .css este archivo se abrirá con Sublime.

El siguiente alias es el de tipo global. El cual he de decir que no suelo utilizar. Este tipo de alias puede aparecer en cualquier parte del comando que introducimos. Vamos a ver un ejemplo.

alias -g HL="--help"

Si vamos a nuestro Terminal y escribimos:

g HL

Nos mostrará toda la ayuda de Git.

Automatización con Bash

Con un mínimo conocimiento de Bash y un poco de locura se pueden hacer scripts que nos faciliten la vida. A continuación os muestro el script que he creado con bash para iniciar la estructura de un proyecto.

#Creamos la estructura de carpeta con el comando mkdir
mkdir css src js img &&

#Descargamos desde GitHub varios archivos
curl -O "https://raw.githubusercontent.com/jorgeatgu/base/master/{.stylelintrc,.gitignore,.stylelintignore,package.json,gulpfile.js,index.html,_variables.css,styles.css}" &&

#Entramos en la carpeta SRC
cd src &&

#Creamos la estructura de la carpeta SRC
mkdir css img js &&

#Entramos en la carpeta de CSS
cd css &&

#Descargamos el la versión más actualizada de normalize
curl -O https://raw.githubusercontent.com/necolas/normalize.css/master/normalize.css &&

#Renombramos normalize a reset con el comando mv
mv normalize.css _reset.css &&

#Salimos a la carpeta de js
cd ../js &&

#Creamos el archivo index.js
touch index.js &&

#Salimos un nivel
cd ..

#Salimos un nivel
cd ..

#Iniciamos GIT
git init

#Añadimos todos los archivos que hemos creado
git add . &&

#Lanzamos un commit con todo lo que hemos creado
git commit -m 'estructura creada' &&

#Aviso
echo -e '\e[94m\e[1mEsto va a costar un poco' &&

#Instalamos todas las dependencias de **NPM**, y nos hacemos un cafe.
**NPM** i &&

#Escribimos con echo un mensaje para avisar de que el script ha terminado
echo -e '\e[94m\e[1mEl script ha terminado. Es hora de picar código! \U0001f913\n' &&

#Aviso sonoro(solo para macOS)
afplay /System/Library/Sounds/Submarine.aiff &&

#Otro aviso! Esta vez con la voz de Siri(solo para macOS)
say El script ha terminado. Es hora de picar código!

Aquí os dejo un repositorio con unos cuantos scripts que he creado para automatizar tareas. Algunos con Bash y AppleScript.

Bibliografía

Unos cuantos dotfiles en GitHub
Guia del Terminal 1 2 3
Manual de scripting en Bash
Bash Handbook
Iniciando proyectos desde cero