Cygwin: creyéndome un chico Linux en Windows (Parte II)

Demoró un poco, pero aquí voy con la segunda parte de mi experiencia con Cygwin. A esta altura espero que hayan leído la primer parte, y se hayan aventurado un poco más allá de lo que ahí escribí.

Como les prometí, ahora veremos un poco de configuración de la shell – no soy un experto, son cosas que he encontrado navegando -, algo de SSH, la integración de Cygwin en una consola multi-pestaña y como he estado trabajando con Laravel como framework principal, un par de aliases para hacer la vida más fácil en éste.

INSTALANDO CONSOLEZ, UNA MEJOR CONSOLA PARA WINDOWS

consolez

ConsoleZ es remplazo ultra-mega mejorado a la consola por defecto de Windows, entregando ciertas funcionalidades bastante agradables:

  • Soporte para pestañas: puedes tener varias consolas abiertas en una misma ventana, como tu navegador favorito.
  • Puedes separar cada pestaña en ‘vistas’ de manera vertical o horizontal. De este modo, en una misma pestaña puedes tener dos consolas abiertas trabajando a la par.
  • Puedes agrupar estas ‘vistas’, permitiendo que un comando se ejecute en todas éstas.
  • Modificación visual de la ventana a nivel de transparencia, imagen de fondo, modo full-screen.
  • Animación de consola tipo Quake: típico efecto de consola de juego de PC en el cual comúnmente presionan le tecla izquierda del número 1 y aparece una consola desde arriba, y luego la esconden con la misma tecla. Desconozco como activar esta opción hasta el momento.

Deben proceder a descargar ConsoleZ en su última versión. Recomiendo crear una carpeta llamada ‘ConsoleZ’ en la raíz del disco: C:/ConsoleZ. Una vez creado, descomprimir los archivos y moverlos allí, ejecutar el programa y fijarlo a la barra de Windows para un rápido acceso.

Estas con mis configuraciones a nivel visual de la consola, que para mi gusto queda bastante bonita:

  • En Styles desmarqué las casillas: Show menu, Show toolbar, Show status bar. Activé la transparencia en modo Alpha y la dejé la ventana activa en 35 y la inactiva en 30.
  • La fuente que utilizo es Consolas en tamaño 10.

INTEGRANDO CYGWIN EN CONSOLEZ

Se abran dado cuenta que al abrir ConsoleZ lo único que hace es abrir la el prompt por defecto de Windows dentro de él, pero queremos lograr que ConsoleZ abra Cygwin de manera automática. Para ello deben ir a las opciones de ConsoleZ – Control + S – y dirigirse a Tabs. Ahí verán que aparece en la lista solamente una opción llamada Console 2. La deben seleccionar, cambiar el nombre a Cygwin – o lo que deseen – y luego en Shell seleccionar la ruta del archivo de Cygwin.bat:

Configurando Cygwin en ConsoleZ
Configurando Cygwin en ConsoleZ

Finalmente le dan OK, cierran ConsoleZ y vuelven a abrir. Listo, ya deberían ver una consola más pingüinesca.

CONFIGURANDO NUESTRO BASH

Ahora que ya tenemos Cygwin funcionando sobre un terminal mucho más amigable, resta realizar un poco de arreglos para que sea aún más cómodo trabajar.

En primer lugar vamos a eliminar ese molestoso cygdrive que hay que escribir cuando queremos cambiar de carpeta: en vez de escribir cd /cygdrive/c/documentos vamos sólo a escribir cd /c/documentos. Para lograr esto vamos editar el archivo /etc/fstab – dentro de la carpeta de Cygwin -:

# Remplazar esta linea
none /cygdrive cygdrive binary,posix=0,user 0 0
# Por esta otra
none / cygdrive binary,posix=0,user 0 0

Gracias a Thomas Wheeler por esta solución: http://randomartifacts.blogspot.ca/2012/10/a-proper-cygwin-environment.html

Ahora vamos a revisar el archivo .bashrc que está dentro de la carpeta /home/<Usuario>Éste contiene la configuración de nuestra consola. Cada vez que ejecutamos Cygwin y se levanta el bash, se carga este archivo de configuración con funciones, aliases, entre otros. Por defecto Cygwin incluye ciertos aliases y funciones que son de utilidad, pero vienen comentados – con el carácter # -. En mi caso trabajo con los siguientes aliases:

alias ls='ls -hF --color=tty' # classify files in colour
alias dir='ls --color=auto --format=vertical'
alias la='ls -A' # all but . and ..

Es recomendable que si desean crear sus propios aliases, los creen en otro archivo llamado .bash_aliases, y dentro del .bashrc descomenten las siguientes líneas:

# Aliases
#
# Some people use a different file for aliases
if [ -f "${HOME}/.bash_aliases" ]; then
  source "${HOME}/.bash_aliases"
fi

Eso hará que se carguen de manera automática, y cuando actualicen Cygwin se mantengan intactos.

Dentro del .bashrc hay una función que me acomoda bastante cuando me estoy moviendo entre directorios, se llama cd_func y basta que la descomenten por completo, incluyendo la línea del alias que dice alias cd=cd_func. Esta función permite llevar un historial de los directorios en los cuales hemos estado y movernos a uno anterior de manera rápida. Si escribimos cd — veremos algo como esto:

Niko@Niko-PC $ cd --
 0  /c/PerfLogs
 1  /c
 2  /
 3  /home
 4  ~
 5  /d/xampp/htdocs/wws
 6  /d/xampp/htdocs

Entonces, si yo quisiera moverme al directorio /d/xampp/htdocs/wws basta con escribir cd -5. Bastante más cómodo.

Por último respecto a la configuración de nuestra bash, voy a dejar unas funciones que he encontrado en internet que permiten mostrar información interesante en el prompt, como el nombre del usuario, la ruta actual, si estamos dentro de un directorio que es un repositorio de Git muestra la rama actual y por último, cuando ejecutamos la consola como administrador, el nombre de usuario cambia de color, así puedes diferenciar cuando estás trabajando con privilegios y cuando no. Finalmente, el prompt se verá algo parecido a esto:

cygwin-prompt-mejorado

Y cuando estén como administrador, el nombre de usuario pasará de verde a morado. El script es el siguiente:

# get current git branch name
function git_branch {
    export gitbranch=[$(git rev-parse --abbrev-ref HEAD 2>/dev/null)]
    if [ "$?" -ne 0 ]
      then gitbranch=
    fi
    if [[ "${gitbranch}" == "[]" ]]
      then gitbranch=
    fi
}

# set usercolor based on whether we are running with Admin privs
function user_color {
    id | grep "Admin" > /dev/null
    RETVAL=$?
    if [[ $RETVAL == 0 ]]; then
        usercolor="[0;35m";
    else
        usercolor="[0;32m";
    fi
}
# set TTYNAME
function ttyname() { export TTYNAME=$@; }

# Set prompt and window title
inputcolor='[0;37m'
cwdcolor='[1;34m'
gitcolor='[1;31m'
user_color

# Setup for window title
export TTYNAME=$$
function settitle() {
  p=$(pwd);
  let l=${#p}-25
  if [ "$l" -gt "0" ]; then
    p=..${p:${l}}
  fi
  t="$TTYNAME $p"
  echo -ne "\e]2;$t\a\e]1;$t\a";
}

PROMPT_COMMAND='settitle; git_branch; history -a;'
export PS1='\[\e${usercolor}\][\u]\[\e${gitcolor}\]${gitbranch}\[\e${cwdcolor}\][$PWD]\[\e${inputcolor}\] $ '

Recomendable que esto vaya dentro de .bash_functions y que en .bashrc descomenten las líneas donde se realiza la carga de este archivo, al igual que como lo hicimos con los aliases. Los colores definidos dentro del script son totalmente modificables. Éstos tienen códigos del tipo 0;30 para negro o 1;33 para amarillo, en internet pueden encontrar un listado de colores para el prompt de bash.

Para poder ver reflejados todos estos cambios, deben cerrar la ventana de la consola o ejecutar el siguiente comando:

source ~/.bashrc

TRABAJANDO CON SSH

Les había comentado que se olvidarán de PuTTY, y es que la verdad es que teniendo un ambiente de Linux en Windows, nos facilita mucho las cosas al momento de acceder a servidores remotos.

Para poder empezar a trabajar con SSH, deben instalar el paquete OpenSSH desde el instalador, cosa que vimos en la primera parte de todo esto.

Una vez instalado, vamos a abrir una consola y escribiremos:

cd ~
mkdir .ssh
cd .ssh
touch config

Hemos creado la carpeta .ssh – en el caso de que no exista – y dentro de ella el archivo config. Este archivo nos permitirá llevar un registro de servidores – como las sesiones en PuTTy -, permitiéndonos conectar de forma simple. Por ejemplo, imaginemos que comúnmente nos conectamos el servidor 166.16.1.6 con el usuario pedrito y también al servidor 200.34.56.109:2222 con el usuario juanito, y claro lo más seguro es que tengamos estos datos en algún archivo de texto. Lo que vamos a hacer es llevar esos datos al archivo config y conectarnos de forma tan simple como ssh servidor-x.

Tomando en cuenta los dos ejemplos de arriba, nuestro archivo config debe quedar de la siguiente manera:

Host trabajo
Hostname 166.16.1.6
User juanito

Host casa
Hostname 200.34.56.109
Port 2222
User pedrito

Fíjense en los nombres que puse en Host, hacen referencia a un nombre corto y amigable para identificar a los servidores. Por lo tanto, luego sólo deben hacer ssh casa y se conectará automáticamente al servidor, donde obviamente les solicitará la contraseña. Finalmente ssh casa se convierte en un alias de ssh pedrito@200.34.56.109:2222. ¿Aburrido de recordar contraseñas?, pueden implementar una identificación mediante llaves publicas.

Un problema que tuve en Windows 8 al utilizar el config de SSH en Cygwin, fue un tema con los permisos. Cada vez que editaba el archivo fuera de la consola, recibía el siguiente mensaje:

Bad owner or permissions on /home/Nikolas/.ssh/config

Una rápida solución que encontré en internet – no tengo el link a mano -, fue el siguiente alias:

alias sshfix='chown -R Nikolas:users ~/.ssh/ && chmod -R 600 ~/.ssh/'

Donde en este caso Nikolas debe corresponder al nombre de usuario de ustedes. Entonces, cada vez que edito el archivo config de SSH fuera de la consola – me refiero utilizando Notepad o Sublime Text, etc -, en consola escribo  sshfix. Cabe destacar que en Windows 7 no tuve este problema, pero leí que otros usuarios si lo han tenido, pero la solución es la misma.

TRABAJANDO CON GIT

Es posible instalar en Cygwin a Git como paquete, pero la verdad es que no lo recomiendo y recomiendo trabajar con el binario para Windows que pueden encontrar en la página de Git, ya que está esta mejor pulida para entornos Windows, viene con una bash mucho más amigable con auto-completado y otros. Instalar las dos versiones, tanto el paquete para Cygwin como el instalador para Windows es fatal, ni lo piensen, ya me sucedió. Lo importante, es que cuando instalen Git, permitan que se agregue al PATH, de ese modo, también tendrán acceso a las herramientas desde Cygwin, tan sólo escribiendo git en consola.

Si desean hacer un push en el servidor remoto van a tener que permitir tener acceso a dos llaves, ya que una es la que va a tener Cygwin y la otra es la que tiene Git como programa independiente. Por ejemplo, si actualmente están trabajando con Git sin problema alguno, he intentan hacer un push desde Cygwin, van a recibir un error de acceso denegado. Al ser dos entornos distintos, al utilizar git desde Cygwin, tampoco van a disfrutar de las mismas bondades que tiene ejecutar Git desde el menú contextual en una carpeta – Git Bash -, bondades tales como el auto-completado cuando están escribiendo el nombre de una rama.

Lo que es yo, utilizo el bash que viene con el instalador de Git, pero queda a gusto propio. De igual forma comparto la siguiente función que muestra gran información del repositorio en donde están posicionados:

git-info()
{
	pushd . >/dev/null

	# Find base of git directory
	while [ ! -d .git ] && [ ! `pwd` = "/" ]; do cd ..; done

	# Show various information about this git directory
	if [ -d .git ]; then
		echo "== Remote URL: `git remote -v`"

		echo "== Remote Branches: "
		git branch -r
		echo

		echo "== Local Branches:"
		git branch
		echo

		echo "== Configuration (.git/config)"
		cat .git/config
		echo

		echo "== Most Recent Commit"
		git log --max-count=1
		echo

		echo "Type 'git log' for more commits, or 'git show' for full commit details."
	else
		echo "Not a git repository."
	fi

	popd >/dev/null
}

La función se ejecuta escribiendo en consola git-info, y muestra información sobre el remote, remote y sus ramas, origin, ramas locales, configuración y el commit más reciente. Esta misma función también puede ser incluida al bash de Git, para ello deben ir a C:/Usuarios/<Usuario> y dentro crear un archivo .bashrc – sí, al igual que Cygwin -, y luego pegar la función. Cuando abran una consola de Git se cargará ese archivo automáticamente.

UNOS ÚLTIMOS TIPS

Muchas veces estaba en un directorio en la consola y necesitaba verlo en el explorador, y era lentísimo abrir el explorador yo mismo y seguir la misma ruta hasta encontrar el directorio. Para evitar eso, les comparto la siguiente función:

open()
{
	/c/Windows/explorer.exe /e,`cygpath -w "$1"`
}

Ahora, si están en el directorio /c/mi/carpeta/ y escriben open . se abrirá el explorador con la carpeta actual. Pueden abrir la ruta que deseen: open /c/Usuarios/Juanito.

Para limpiar la consola por completo, pueden presionar Control + L o tener el siguiente alias:

alias clear='echo -e "\033c"'

Para poder copiar texto desde la consola, basta con presionar la tecla Shift y con el mouse seleccionar lo que deseemos. Luego, hacer doble clic sobre el texto seleccionado. Listo, queda copiado en el porta papeles. ¿Y para pegar?. Al igual que PuTTY con el clic del centro del mouse o con Control + Insert.

En el caso de Laravel, muchas veces me daba pereza escribir php artisan, y envidiaba a los usuarios de Unix que podrían sólo escribir artisan en consola con un alias. Bueno, ahora que tenemos Linux dentro de Windows, podemos:

alias artisan='php artisan'

Y así, pueden crear un sin fin de aliases para trabajar con Laravel o cualquier otra herramienta de forma más rápida.

El comando history puede ser de utilidad. Les mostrará un listado con números de los últimos comandos. Luego basta con escribir !N donde N es el número del comando que desean volver a ejecutar.

Por último, no olviden de instalar algún editor de texto en Cygwin. De mi preferencia está nano por su simplicidad, pero si desean algo más completo también pueden encontrar vim.

CONCLUSIONES

Más allá del título, la idea no es que queramos ser «chicos Linux en Windows» – solo fue marketing -, la idea es que podamos mejorar nuestro flujo de trabajo, y hay muchas tareas que se realizan de mejor manera en la consola que en una interfaz, y que por abc motivos ustedes y yo estamos ligados a Windows, pueden ser motivos laborales o personales, da igual.

Los invito a buscar en internet miles de otras funciones que pueden implementar en sus consolas, la verdad es que es un mundo, y la mayoría de lo que yo he puesto aquí lo he encontrado en internet navegando de acuerdo a mis necesidades mientras utilizaba Cygwin.

23 comentarios sobre “Cygwin: creyéndome un chico Linux en Windows (Parte II)

  1. Hola amigo, excelente aporte con esta utilidad de consoleZ, aunque no la uso con tanta profeionalidad como tu, si la estoy usando para el Cygwin para cuando hago una que otra modificacion en alguna Rom de android (apenas soy principiante XD), pero realmente es mas comodo poder tener varias ventanas y poder hacer varias cosas al tiempo ya que compilar lleva tiempo y deja ocupada la instancia, muchas gracias.

    Hiciste un comentario acerca de como poder hacer aparecer una consola de la nada con cierto efecto oprimiendo una tecla, pues con eso en mente me puse a busar informacion al respecto y aca un link con informacion interesante que seguro aprovecharas mejor que yo,

    http://msdn.microsoft.com/es-es/magazine/cc163435.aspx

    Espero te resulte de utilidad, suerte y sigue con el buen trabajo.

    Me gusta

  2. Con este método puedes mostrar el directorio actual en el explorardor de Windows. El punto indica que quieres abrir el directorio actual. Gracias por la publicación.

    alias e=/c/Windows/explorer.exe .

    Me gusta

  3. Hola,
    Muchas gracias por el blog… me ha venido genial… ya conocia el cygwin pero no el consoleZ …. ya casi casi tengo lo mismo que en linux … jejeje

    Una duda…. ¿como el pongo UTF-8 a ConsoleZ? En el cygwin ya lo puse…

    Gracias

    Me gusta

      1. Si usas cygwin a traves de ConsoleZ, pierdes el UTF8 que hasllas configurado en cygwin. Esa configuración se hace a nivel de consola, de ventana, por lo visto,

        Me gusta

          1. hola…
            Esa prueba no vale… porque estas escribiendo el caracter especial con la misma codificación que despues se muestra.
            El problema viene si lees un archivo escrito con utf8, haciendo un cat por ejemplo. En consoleZ no me permite indicar con que codificación trabajo y por eso no puedo leer correctamente esos archivos.

            Prueba con notepad++ a crear un archivo utf8, inserta caracteres especiales como acentos y ñ … y luego prueba un cat de ese archivo dentro de consoleZ.

            Me gusta

          2. Lo has creado con NANO… creo que eso no vale, porque lo creas con la misma consola y estas usando la codificacion de la propia consola… tienes que crearlo externamente, con _Notepad++ o similar. En cualquier caso haz un file -1 hola.txt, esto te indica la codificacion del archivo. Por ejemplo, a me sale » text/plain; charset=utf-8″

            Muy buena la presentación de la prueba… me ha encantado ;)

            Muchas gracias por tu interes :)

            Me gusta

          3. Fíjate que luego de crear el archivo en nano hago un file -bi y se puede ver la codificación en utf8 del archivo. He hecho una misma prueba con Sublime Text, guardando explícitamente como UTF8 (hasta con BOM) y el cat imprime los caracteres sin problema.

            Me gusta

          4. Hoal nikoskip,

            Pues no se… o algo se me escapa o no usamos la misma consola.
            En tu pantalla, veo que pone Console2 … 2 no Z

            Yo uso ConsoleZ 1.13.0.150444, pone que es una modificacion de Console2 de Marko Bozikovic.

            ¿Qué versión usas tu?

            Me gusta

  4. Curioso…..

    Lo que no se ve bien en ConsoleZ son algunos caracteres especiales como los rusos (мы находили отел) …

    He creado un archivo con nano en CYGWIN, y en ConsoleZ aparecen interrogantes en vez de los caracteres rusos.

    Tanto en cygwin como en consoleZ, el archivo es detectado como utf8.

    que me ahorquen si lo entiendo….

    Me gusta

  5. Excelente aporte amigo, utilizo cygwin y me ha caido de perlas pero me gusta utilizar tmux y parece que necesita alguna referencia

    $ tmux
    open terminal failed: not a terminal

    Acaso sabes cual es la razon?

    Me gusta

  6. No he podido configurar el bash con las funciones que tienes. Me sale un erro de sintaxis en la primera función git_branch que dice: bash: /home/CarlosAlberto/.bash_functions: línea 4: error sintáctico cerca del elemento inesperado $'{\r''
    'ash: /home/CarlosAlberto/.bash_functions: línea 4:
    function git_branch {
    Cito: «voy a dejar unas funciones que he encontrado en internet que permiten mostrar información interesante en el prompt, como el nombre del usuario, la ruta actual,[…]»
    No me funciona y no sé si haya otra solución. Trabajo en win 8.1 y tengo instalado cygwin 2.0.4 y ConsoleZ 1.14 por medio de choco

    Me gusta

    1. Hola!

      Es extrañó. Acabo de copiar las mismas funciones dentro de mi .bash_functions y todo anda bien.

      ¿Es posible puedas compartir tu archivo completo?

      PD: Acabo de perder mi .bash_functions original probando esto T_T… que más da, cosas que pasan.

      Me gusta

      1. Sí que es extraño, y te agradezco tu atención. Básicamente es lo mismo, tengo dos líneas antes que están comentadas así que no debe ser eso… además si las quito y abro la consola sale el mismo error pero indica que es en la línea 2 no 4.

        # Custom Prompt
        # PS1="\[33[01;32m\]\u\[33[01;34m\] \w \$\[33[00m\] "
        # get current git branch name
        function git_branch {
          export gitbranch=[$(git rev-parse --abbrev-ref HEAD 2>/dev/null)]
          if [ "$?" -ne 0 ]
            then gitbranch=
          fi
          if [[ "${gitbranch}" == "[]" ]]
            then gitbranch=
          fi
        }
        
        # set usercolor based on whether we are running with Admin privs
        function user_color {
          id | grep "Admin" > /dev/null
          RETVAL=$?
          if [[ $RETVAL == 0 ]]; then
              usercolor="[0;35m";
          else
              usercolor="[0;32m";
          fi
        }
        # set TTYNAME
        function ttyname() { export TTYNAME=$@; }
        
        # Set prompt and window title
        inputcolor='[0;37m'
        cwdcolor='[1;34m'
        gitcolor='[1;31m'
        user_color
        
        # Setup for window title
        export TTYNAME=$$
        function settitle() {
          p=$(pwd);
          let l=${#p}-25
          if [ "$l" -gt "0" ]; then
            p=..${p:${l}}
          fi
          t="$TTYNAME $p"
          echo -ne "\e]2;$t\a\e]1;$t\a";
        }
        
        PROMPT_COMMAND='settitle; git_branch; history -a;'
        export PS1='\[\e${usercolor}\][\u]\[\e${gitcolor}\]${gitbranch}\[\e${cwdcolor}\][$PWD]\[\e${inputcolor}\] $ '
        

        PD: Siento que hayas perdido tu archivo de funciones bash. :(

        Me gusta

        1. Solucionado el problema. El error aparece porque el archivo .bash_functions tiene el formato del salto de línea windows [CR][LF] y no unix [LF]. Probé modificando esto y ya no genera error y me muestra correctamente la configuración del prompt. En sublime text 3 -> Settings user se agrega esta línea: "default_line_ending": "unix"

          Le gusta a 1 persona

Deja un comentario (puedes utilizar Markdown)