PowerShell utilities series: ls / Get-ChildItem a color

No se puede entender el día a día de un administrador de sistemas sin scripting y línea de comandos, bien sea en bash desde UNIX y derivados o PowerShell para sistemas Windows; algo que ya nos es muy familiar en Plain Concepts. Con esta entrada inicio una serie de artículos dedicados a contar curiosidades y pequeñas utilidades de PowerShell, que tienen como finalidad hacer nuestra vida más fácil incrementando la experiencia de usuario con ella.

No es ningún secreto que muchos de los potenciales administradores de sistemas Windows vienen o tiene relación también con UNIX, por lo que Microsoft se ha preocupado de facilitar la transición de un sistema a otro. Para ello, PowerShell dispone de alias de muchas de sus funciones que permiten que los cmdlets se presenten en forma de formato UNIX, por ejemplo:

Alias utilizable en PowerShell Cmdlet que en realidad ejecuta
ls Get-ChildItem
cat Get-Content
grep Select-String
wc Measure-Object
time Measure-Command
find Find-ChildItem
man Get-Help
cp Copy-Item
mv Move-Item
rm Remove-Item
cls Clear-Host
echo Write-Output

Sin embargo, una de las cosas que más echo de menos de una consola UNIX es su capacidad de mostrar los archivos de un directorio por colores en función de su tipo, a través de la orden ls –color.  Esto se puede ver en esta salida de ejemplo:

image

En cambio el resultado estándar de imprimir los contenidos de un directorio en PowerShell es el siguiente:

image

¿Verdad que sería estupendo si pudiéramos hacer que la PowerShell también tuviera su propio ls –color? Esto es justo lo que vamos a hacer ahora.

Consiguiendo el LS a color

Indagando por Internet di con un excelente script en GitHub firmado por un tal Tojo2000. Podéis ver y descargar el script desde aquí. El script daba buen resultado, pero había un par de cosas que echaba en falta frente al ls –color  de UNIX:

  • Los colores de los tipos de archivo no coincidían.
  • Los enlaces simbólicos y enlaces duros del sistema de archivos NTFS no se mostraban en el clásico color celeste.

Lo bueno del scripting de PowerShell es que por definicion es Open Source, así que me lancé a hacer unas pequeñas modificaciones para que cumpliera con mis premisas. El resultado lo podéis ver a continuación:

El funcionamiento del script no entraña ningún misterio, aunque debo decir que es ingenioso. Básicamente utiliza expresiones regulares para identificar las extensiones de archivo de los elementos listados, para después llamar a Get-ChildItem cuya salida se procesa a través de un pipe donde se evalúa línea a línea de qué color debe pintarse en pantalla.

Básicamente podéis ver como se han cambiado los colores a la vez que se han agregado nuevas extensiones de archivo y además tenemos la siguiente diferencia:

Este if  nos indicará si el archivo a listar es un ReparsePoint, que nos viene a decir si es un enlace en el sistema de archivos NTFS.

Una vez generado el script sólo tenemos que llamarlo para disponer de la orden Get-ChildItemColor. Sin embargo, eso no bastará para sustituir al ls y además, es engorro tener que estar cargando continuamente el archivo al cargar la consola. Por ello nos vamos a construir un sencillo instalador.

Los Profile de PowerShell

Un Profile de PowerShell no es más que un script que se ejecuta automáticamente cada vez que se arranca la línea de comandos. En función del ámbito de aplicación de dicho script (usuario actual, toda la máquina, etc…) este se puede ubicar en múltiples lugares. Por ejemplo: el $profile de All Users se ejecutará independientemente de quien sea el usuario que ha iniciado la consola de PowerShell.

Hay nada más y nada menos que 6 profile distintos de PowerShell:

Aplicación Ruta
Current User, Current Host – console $Home[My ]DocumentsWindowsPowerShellProfile.ps1
Current User, All Hosts $Home[My ]DocumentsProfile.ps1
All Users, Current Host – console $PsHomeMicrosoft.PowerShell_profile.ps1
All Users, All Hosts $PsHomeProfile.ps1
Current user, Current Host – ISE $Home[My ]DocumentsWindowsPowerShellMicrosoft.P owerShellISE_profile.ps1
All users, Current Host – ISE $PsHomeMicrosoft.PowerShellISE_profile.ps1

Nosotros vamos a trabajar con el perfil de Current User. Hay mucha más información sobre los profiles en este post del blog de Hey, Scripting Guy!

El instalador de scripts de PowerShell

Para que el uso de nuestro nuevo ls a color sea transparente, podemos hacernos un pequeño instalador en la propia PowerShell que nos lo instale en nuestro Profile personal y se autoejecute cada vez que abramos una sesión. El instalador consta de los siguientes archivos:

  • Get-ChildItemColor.ps1. El archivo que contiene el script en cuestión.
  • Get-ChildItemColor_profile.ps1. Contiene el pequeño script que agregaremos a nuestro perfil personal.
  • Install-ChildItemColor.ps1. El script que se encarga de copiar los archivos e iniciar la instalación.

Veamos los dedicados a temas de instalación:

Este script no tiene ningún misterio. En primer lugar hacemos dot sourcing del script en cuestión para que este cargue y después hacermos override de los alias por defecto de ls y la que están incluidos por defecto en PowerShell.

Vayamos al siguiente script:

Este script:

  1. Identifica cuál debería ser la ruta donde se encuentra el profile de CurrentUser, y en caso de no encontrarla creará la carpeta por nosotros.
  2. Copia el archivo Get-ChildItemColor a la carpeta del profile.
  3. Agrega el contenido de Get-ChildItemColor_profile.ps1 a Microsoft.PowerShell_profile.ps1.

Con esto dejamos el script listo para ejecutarse automáticamente cada vez que abramos nuestra PowerShell y el resultado será el siguiente:

image

Os dejo agregados a este post un paquete con los 3 archivos para que lo podáis instalar con sólo ejecutar Install-Get-ChildItemColor.ps1.

Happy scripting!

Descarga: Get-ChildItemColor.zip

0 pensamientos en “PowerShell utilities series: ls / Get-ChildItem a color”

  1. No sé mucho de Power shell, pero me parece que la sintaxis de commandos es mucho peor, o mas fea al menos que la de Unix.

    Comandos básicos de DOS palabras. No hay alguna sintaxis mas Unix friendly?. O corta al menos.

    1. Definitivamente el planteamiento de PowerShell es totalmente opuesto al de la mayoría de shells de UNIX, en especial el bash que es la que conozco. UNIX, al igual que C, vela procura que los comandos sean lo más cortos posible para que puedan ser escritos rápidamente e incrementar la productividad; pero la desventaja de esto es que con frecuencia son bastante crípticos y es complicado saber lo que hacen si no se consulta la ayuda del programa en cuestión.

      PowerShell es opuesta y vela por que los comandos sigan una estructura predefinida (Verbo-Sustantivo) de forma que se comprenden fácilmente con sólo leerlos, sin haber estudiado el comando previamente. La desventaja de esto es que los comandos son muy largos y se tarda más en escribirlos, ¡aunque tenemos autocompletar!

      A pesar de todo la PowerShell tiene definidos un set de alias por defecto para simular comandos de UNIX y MS-DOS, de forma que podemos usar en ella sin problemas el ls, grep, dir, cp, mv, etc… Así que la sintaxis UNIX-friendly la tienes de forma aproximada 🙂

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *