Windows para desarrollo
En este apunte describo los pasos para preparar un Windows 11 como equipo de desarrollo para un entorno multiplataforma, Linux, MacOS y Windows, es decir que no estará orientado a desarrollo de software solo-microsoft/windows, sino a los que les gusta desarrollar en y para múltiples plataformas y/o entornos.
Parto de una instalación de Windows (en inglés), sin nada instalado, aproveché que necesitaba hacer dualboot y parametricé el sistema operativo de forma ligera. El apunte empieza por el CLI y WSL2 y en la segunda parte entro en las herramientas y los lenguajes de programación.
Este apunte pertenece a una serie: • Preparo un PC para Dualboot Linux Windows e instalo Windows 11 Pro. • Configuro un Windows 11 decente, en su esencia, le quito morralla. • Preparo el Windows para desarrollo de software, CLI, WSL2, herramientas y lenguajes de programación. |
Preparar el equipo
Como todos mis apuntes, se trata de la bitácora de mi instalación, es decir, voy ejecutando y documentando a la vez, así me sirve para tener una referencia en el futuro.
Nota sobre el PATH
En Linux y MacOS es inmediato, pero en Windows modificar el PATH es distinto, hay un PATH de Usuario y uno de Sistema, que combinados nos dan el PATH completo. Durante el apunte verás que indico que hay que modificar el PATH. Dejo aquí el cómo:
- Para modificar el PATH Global
Start
>Settings > System > About > Advance System Settings
- o bien
Search
> “Advance System Settings
” o “Environment Variables
”
- Modificar en
System variables
y/oUser variables
- Dejo un ejemplo de mi PATH final en un Gist.
CLI
Es imprescindible hablar de la Consola que vas a usar, tanto si estás acostumbrado a trabajar desde la línea de comandos como si no, los desarrolladores multiplataforma lo valoramos mucho.
Anticipo que voy a usar mucho WSL2, la Shell de Unix (zsh o bash
), junto con las herramientas de línea de comandos Open Source existentes para Linux (ls, cd, mkdir, cp, tar, sed, awk, nano, vi, etc.
), pero tambien usaré el CMD (con retoques para mejorarlo) y PowerShell.
CMD (cmd.exe
)): La línea de comandos tradicional de Windows. Es uno de los entornos más antiguos y básicos para ejecutar comandos en Windows, sus scripts son los famosos *.BAT, *.CMD
.
C:\> echo Bye bye, World!
Es lo que es, no necesita mucha explicación, bastante austero; pero si realmente te gusta, he añadido una sección sobre cómo mejorarlo considerablente !
PowerShell: Entorno de scripting y línea de comandos avanzada desarrollada por Microsoft. Es más potente que CMD, permite el uso de comandos más complejos, scripts, y el acceso al framework .NET. Los scripts terminan en *.PS1
.
- Windows 11 trae la PowerShell 5.x - (powershell.exe), conocido como “Desktop”. Funciona exclusivamente en Windows.
- Basado en el motor PowerShell 5.1.
- Totalmente integrado con Windows, soportando todas las características, módulos y cmdlets específicos de Windows.
- Corre sobre el .NET Framework.
- Ideal para gestionar entornos Windows, incluyendo Active Directory, Exchange y otros servicios específicos de Windows.
- Powershell 7: (pwsh.exe), conocido como “Core”. Multiplataforma (Windows, macOS, Linux).
- Basado en el motor de PowerShell 6.0+.
- Diseñado para ser más modular y liviano, pero puede carecer de algunas características y módulos específicos de Windows.
- Corre sobre .NET Core (ahora .NET 5+).
- Adecuado para gestionar entornos diversos, incluyendo servicios en la nube y sistemas no Windows.
Ahora es buen momento para instalarla,
- Instalo PowerShell 7 > “Downloads”.
PS C:\> $PSVersionTable
:
- Modifico el script que se ejecuta al iniciar una sesión de PS7
- Añado lo siguiente al final de
C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1
(PS7)
- Añado lo siguiente al final de
# Quito el alias de por defecto 'where' para evitar conflictos con el 'where.exe' que instalo desde Git para Windows
Remove-Item alias:\where -Force
PowerShell es muy útil para desarrolladores que trabajan exclusivamente en .NET, con C#, en entornos solo Microsoft, para automatizaciones, para el mundo DevOps CI en entornos Windows/Azure.
Windows Subsystem for Linux (WSL 2): permite ejecutar un entorno Linux directamente en Windows sin la necesidad de una máquina virtual. Puedes instalar distribuciones de Linux (como Ubuntu, Debian, etc.) y usar la Shell que quieras de forma nativa, con altísimo rendimiento, completamente integrado con el File System de Windows (excepto los permisos).
luis@kymeraw:/mnt/c/Users/luis$ ls -al
Windows Terminal: Una aplicación moderna que permite utilizar múltiples pestañas con diferentes consolas, como CMD
, PowerShell
, WSL
, Git Bash
, … Es muy personalizable y soporta características avanzadas como temas y configuraciones de fuentes. Entro en detalle más adelante.
Git for Windows: Se trata del importantísimo git.exe
para trabajar desde la línea de comandos que además incluye Git Bash, una herramienta que proporciona un emulador de Bash para Windows. Otro terminal más, algo parecido a lo que vemos en un terminal WSL2 de Ubuntu, pero usando un emulador de terminal y ejecutables nativos de Windows. Lo veremos.
Visual Studio Code - Terminal Integrado: Visual Studio Code (VS Code) es un editor de código fuente que incluye un terminal integrado. Puedo abrir diferentes terminales dentro de la misma ventana de VS Code, como CMD, PowerShell, Git Bash o WSL.
Mi estrategia
Mi estrategia consiste en usar lo que mejor encaje en cada momento. Instalo y configuro todas las opciones anteriores, mejoro el cmd e instalo Windows Terminal como “lanzador unificado” del CLI que necesite en cada momento.
CMD Mejorado
Hoy en día, sobre todo para los que venimos de Unix/Linux/MacOS, se puede mejorar muchísimo, tanto he acabado usándolo bastante.
Clink: Lo primero que hay que hacer es instalar Clink. Súper recomendado; le añade todo lo que le falta, la readline (de linux), múltiples funcionalidades, colores, historia, Scriptable Prompt.
Es importante que leas la sección de instalación y uso para configurarlo de forma adecuada y sobre todo para inyectarlo en el CMD, de tal forma que arranque automáticamente al arrancar cmd.exe
. Básicamente mete la siguiente entrada en el Registry:
Computer\HKEY_CURRENT_USER\Software\Microsoft\Command Processor
|
+--> AutoRun "C:\Program Files (x86)\clink\clink.bat" inject --autorun
Tiene un potencia enorme porque soporta Scriptable Prompt, que significa que puedas modificar el PROMPT usando scripts LUA en tiempo real, por ejemplo para el estado de Git. Lee la documentación.
Creo mi script LUA (prompt_filters.lua) en C:\Users\luis\AppData\Local\clink
:
clink-reload
C:\Users\luis>clink info | findstr scripts
scripts : C:\Program Files (x86)\clink ; C:\Users\luis\AppData\Local\clink
C:\Users\luis>notepad C:\Users\luis\AppData\Local\clink\prompt_filters.lua
Startship.rs: Lo siguiente que instalo es startship.rs, que se vende como “un Prompt para cualquier Shell, mínimo, super-rápido, y altamente personalizable”. Starship aprovecha símbolos y caracteres especiales que no están presentes en las fuentes predeterminadas. Para que el prompt se vea correctamente, es necesario instalar una Nerd Font.
-
Lo primero es instalarme una Nerd Font, desde su repositorio oficial >
Downloads
. Busco y descargoFira Code
(puede ser cualquiera). Unzip del fichero, selecciono todos los.ttf
> botón derecho >Install
. Lo configuro como fuente por defecto en Windows Terminal, Settings -> Profiles -> Defaults -> Appearance -> Font FaceFiraCode
-
El siguiente paso es instalar la última versión con:
winget install starship
-
Añado el script de inicio a la Shell
- Powershell: Añado lo siguiente al final de
C:\Program Files\PowerShell\7\Microsoft.PowerShell_profile.ps1
(PS7)Invoke-Expression (&starship init powershell)
- CMD: Necesito tener Clink instalado y operativo
- Creo el archivo
C:\Users\luis\AppData\Local\clink\starship.lua
con este contenido load(io.popen('starship init cmd'):read("*a"))()
- Elimino el fichero que creé en el paso anterior (Clink):
C:\Users\luis\AppData\Local\clink\prompt_filters.lua
- Creo el archivo
- Powershell: Añado lo siguiente al final de
Cmder: puedes ir un paso más allá e instalarte Cmder: una consola muy potente que incluye el emulador ConEmu (emulador de terminal) y Clink y si has instalado Git for Windows, se integra perfecto, con acceso en el PATH a todas las herramientas.
Yo lo he instalado para probarlo, pero si soy sincero no lo estoy usando, me parecen ya demasiadasa opciones.
WSL 2
WSL2 utiliza una máquina virtual ligera con un kernel real completo de Linux, tiene un rendimiento altísimo, está super integrado con Windows, permite que los archivos y scripts de Linux se ejecuten desde el explorador de Windows, y viceversa; y muy importante, tiene compatibilidad con Docker, de hecho WSL2 es el backend preferido para Docker Desktop en Windows (que instalaré más adelante).
Aviso: Solo le he encontrado un pero. Ten cuidado al acceder desde WSL2 a un directorio de
/mnt/c (C:)
del que cuelgan cientos o miles de archivos. Un ejemplo es un repositorio GIT grande. Irá lento, bastante lento. En esos casos es mejor “atacar” dichos directorios dessde el CMD o Powershell.
Mis casos de uso de WSL2:
- Tener Shell + Herramientas con acceso nativo a
C:\
(vía/mnt/c
). Tendré una Distribución Linux completa con acceso a todas las herramientas open source disponibles en Linux. Llego al terminal WSL2 vía Windows Terminal - Equipararme a lo que uso en MacOS o Linux para desarrollo de software.
- Poder instalar Docker Desktop en Windows
Proceso de instalación:
- Abrir “Características de Windows” - Win + R,
optionalfeatures
. Marco las opciones:- Virtual Machine Platform (Plataforma de Máquina Virtual)
- Windows Subsystem for Linux (Subsistema de Windows para Linux)
- Hyper-V (recomendado para Docker con WSL2).
- Reboot
-
Instalo WSL, desde PowerShell como administrador
wsl --install
-
Miro las distribuciones disponibles
wsl --list --online
-
Instalo una distribución, en mi caso Ubuntu 24.04 (podrías instalar otra como Debian, Kali-Linux, Suse, …). Abro PowerShell como Administrador
wsl --install -d Ubuntu-24.04
- Durante la instalación requirió actualizar el núcleo de Linux:
- Descargué el Paquete de actualización del kernel de Linux en WSL 2 para máquinas x64
- Lo ejecuté e hice un reboot y tuve que volver a lanzar la instalación de la distribución, creé el usuario linux (
luis
) y le puse contraseña.
wsl --install -d Ubuntu-24.04
- Cuando termina lanza la consola con el CLI de
bash
. Me salgo conexit
, ya volveremos.
- Durante la instalación requirió actualizar el núcleo de Linux:
-
Abro PowerShell como Administrador, muestro que tengo y me aseguro de que siempre sea la versión 2 (en mi caso no hace falta, solo si tienes otra versión)
wsl --list --verbose wsl --set-default-version 2
-
Actualizo
wsl --update
Opcionalmente puedo añadir un icono a Ubuntu en el Taskbar. Busco en la lista de aplicaciones instaladas: Start > All > "Ubuntu 24.04"
y con el botón derecho hago un Pin to taskbar para tener un acceso rápido a mi bash
(Ubuntu 24.04 en WSL2). Nota: Luego lo quité, una vez que instalo “Windows Terminal” más adelante.
Efectivamente estamos en una máquina virtual con Ubuntu, así que puedo instalar la herramienta que quiera. Lo siguiente imporante a hacer es actualizala.
luis@kymeraw:~$ sudo apt update && sudo apt upgrade -y
WSL 2 - Cambiar HOME a /mnt/c/Users
El único propósito por el que me gustaría cambiarlo es que al ejecutar “cd” me lleve a /mnt/c/Users/
¿Por qué no lo recomiendp?: Algunas aplicaciones y herramientas, como Docker Desktop, se rompen. Hay Apps que tienen hard-coded el que el $HOME esté en su sitio (/home/
Por lo tanto, recomiendo dejar tu WSL2 tal cual y una alternativa para ir rápido al HOME de Windows es un alias en .bashrc
o .zshrc
: alias c="cd /mnt/c/Users/<usuario>
.
De todas formas, si necesitas cambiarlo, se haría así:
- Desde Powershell, pido que WSL arranque como
root
:
PS C:\Users\luis> ubuntu2404.exe config --default-user root
- Abro una nueva Shell y cambio el HOME de
luis
C:\Users\luis> ubuntu2404.exe
root@kymeraw:~# usermod --home /mnt/c/Users/luis/ luis
- Vuelvo a dejar que el login por defecto lo haga con
luis
PS C:\Users\luis> ubuntu2404.exe config --default-user luis
WSL 2 - Fichero /etc/wsl.conf
Lo menciono en varias partes de este apunte, dejo aquí la copia final que utilizo en mi ordenador, hay que editarla en WSL2 como root.
[boot]
systemd=true
[automount]
options = "metadata,uid=1000,gid=1000,umask=022,fmask=11,case=off"
[interop]
enabled=true
appendWindowsPath=false
Importante: Cuando modificas este fichero hay que salirse de WSL y pararlo, esperar a que nos diga que no hay nada ejecutándose y volver a ejecutarlo. Veamos un ejemplo, donde estoy en una sesíón WSL2 en la shell como root.
root@kymeraw:~# exit
logout
luis@kymeraw:~$ exit
logout
PS C:\Users\luis> wsl --shutdown
:
PS C:\Users\luis> wsl --list --running
There are no running distributions.
La línea options
bajo [automount]
sirve para establecer bien los permisos de los ficheros. Ten en cuenta que los permisos de los archivos Linux que se crean en el disco NTFS se intepretan de una forma muy concreta. Los archivos/directorios que se crean en el disco NTFS (debajo de /mnt/c/Users/<usuario>
) van con permisos 777.
A mi eso no me gusta. Quiero que WSL sea coherente, además hay programas a los que no les gusta tanto permiso, un ejemplo es SSH. El cliente de OpenSSH necesita que el directorio y los archivos bajo ~/.ssh
tengan unos permisos específicos.
La solución es activar los metadatos en la configuración avanzada de WSL, en el fichero /etc/wsl.conf
en la sección [automount]
.
Cuando vuelvo a entrar en la Shell me aseguro de que mis archivos son míos (si has cambiado de distribución podría ocurrirte que pertenecen a otro usuario, por ejemplo ubuntu:lxd
).
PS C:\Users\luis> ubuntu2404.exe
luis@kymeraw:~$ pwd
/mnt/c/Users/luis
luis@kymeraw:~$ sudo chown -R luis:luis /mnt/c/Users/luis
[sudo] password for luis:
WSL 2 - Locale
Mi Windows 11 está en inglés y el Ubuntu se ha instalado en Inglés. Tengo que añadir el locale de Español. En la sesión de Ubuntu, cambio a root y ejecuto lo siguiente:
root@kymeraw:~$ sudo su -
:
root@kymeraw:~# cat > /etc/locale.gen
en_US.UTF-8 UTF-8
es_ES.UTF-8 UTF-8
root@kymeraw:~# locale-gen
Generating locales (this might take a while)...
en_US.UTF-8... done
es_ES.UTF-8... done
Generation complete.
WSL 2 - Cambio a ZSH
La shell que viene por defecto en Ubuntu para WSL2 es bash
pero como expliqué en ¡Adiós Bash, hola Zsh!, me paso a zsh
(un apunte interesante). También me instalo “tmux”, un multiplexor de terminales opcional potentísimo.
Primero zsh
luis@kymeraw:~$ sudo apt update && sudo apt upgrade -y
luis@kymeraw:~$ sudo apt install zsh
Compruebo las shells disponibles
luis@kymeraw:~$ cat /etc/shells
:
/bin/zsh
/usr/bin/zsh
Cambio la shell por defecto
luis@kymeraw:~$ chsh -s $(which zsh)
Password:
Salgo y vuelvo a entrar. La primera vez que entras con zsh
te ofrece ayuda para crear el fichero .zshrc
. En mi caso ya lo tengo creado porque uso el mismo para MacOS, Linux y ahora Windows. Me lo descargo ~/.zshrc y lo copio al HOME /mnt/c/Users/luis
.
Instalo tmux, que lo suelo utilizar:
sudo apt install tmux
Aquí tengo un ~/.tmux.conf, que también copio al HOME (/mnt/c/Users/luis
).
WSL 2 - Scripts
Me instalo mis scripts que suelo usar en todos los Linux/MacOS,
- Script /usr/bin/e
- Fichero /etc/nanorc personalizado para
nano
- Creo los directorios de backup (
sudo mkdir /root/.nano
ymkdir ~/.nano
- Creo los directorios de backup (
- Script /usr/bin/confcat, un cat sin las líneas de comentarios
- Script /usr/bin/s para cambiar a root mucho más rápido
- Añado mi usuario a sudoers
echo 'luis ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/90-mi-usuario
- Cambiar los permisos:
sudo chmod 755 /usr/bin/e /usr/bin/confcat /usr/bin/s
- Crear el directorio
mkdir ~/.nano
tanto para root como para mi usuario
WSL 2 - Cliente SSH
Para poder conectar desde la Consola WSL2 a equipos remotos.
- Verifico que el cliente de OpenSSH está instalado (Esta sesión de Powershell como Administrador)
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
- Creo el par pública/privada en el directorio HOME de windows. El motivo es que normalmente voy a usar el cliente SSH de Windows.
PowerShell 7.4.5
C:\Users\luis> ssh-keygen.exe -t ed25519 -a 200 -C "luis@kymeraw" -f $env:USERPROFILE\.ssh\id_ed25519_luispa
PowerShell 7.4.5
C:\Users\luis> ssh-keygen.exe -t ed25519 -a 200 -C "luis@kymeraw" -f %USERPROFILE%\.ssh\id_ed25519_luispa
WSL2
C:\Users\luis> ssh-keygen -t ed25519 -a 200 -C "luis@kymeraw" -f /mnt/c/Users/luis/.ssh/id_ed25519_luispa
Te dejo un enlace a otro apunte muy interesante, Git multicuenta, donde trato el tema de SSH como alternativa.
WSL 2 - Servidor SSH
Veamos el proceso de activación del servidor SSH. Lo primero es verifico si OpenSSH está instalado. A continuación agrego el Servidor OpenSSH:
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*'
:
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Inicio el Servicio, compruebo y configuro que arranque siempre al hacer boot
Start-Service sshd
Get-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'
El Servidor SSH se ejecuta en Windows (no en WSL2/Ubuntu), por lo tanto los Credenciales son los de windows, mi usuaario LOCAL luis
(no uso Microsoft Account) y su contraseña es la de Windows. El fichero sshd_config se encuentra en C:\ProgramData\ssh\sshd_config
.
En mi caso desactivo usar el fichero administrators_authorized_keys
porque prefiero que use el del HOME de mi usuario luis
que está en C:\Users\luis\.ssh\authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
AcceptEnv LANG LC_*
Subsystem sftp sftp-server.exe
#Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
Lo edito y rearranco el servicio
notepad C:\ProgramData\ssh\sshd_config
Restart-Service sshd
Edito las claves que acepto en authorized_keys
notepad C:\ProgramData\ssh\administrators_authorized_keys
Compruebo si el puerto 22 está abierto. Si necesitas comprobarlo aquí tienes un script VerificarPuertoFirewall.ps1. En mi caso estaba ya abierto; si necesitas abrir el puerto en el firewall usa el comando siguietne.
New-NetFirewallRule -DisplayName "Allow SSH Port 22" -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow
A partir de ahora me puedo conectar perfectamente con mi Windows desde cualquier otro equipo de la red. Si te fijas me conectó directamente con WSL2, sigue leyendo…
Opcional: Por defecto, si activamos el Servidor SSH en Windows, cuando conectemos con él nos redirigirá a una sesión de cmd.exe
, pero puedes cambiarlo para que los clientes accedan directamente a la shell de WSL2. Importante, nunca usar los ejecutables de wsl que también están bajo C:\Users\luis\AppData\Local\Microsoft\WindowsApps
o tardará muchos segundos en mostrarte el prompt. Ejecuto desde Powershell como administrador.
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\wsl.exe" -PropertyType String -Force
WSL 2 - CRLF vs LF
Al trabajar en desarrollo de software, uno de los aspectos más sutiles pero cruciales que debes tener en cuenta es la diferencia entre los finales de línea en archivos de texto entre Windows y Linux.
En este apunte CRLF vs LF puedes encontrar cómo manejo este tema.
WSL 2 - Starship
Hablé de startship en la sección de CMD mejorado, aquí explico cómo lo añado a mi WSL2. En este ejemplo he seleccionado descargar las NerdFonts FiraCode (que son las mismas que instalé a nivel Windows para CMD y Powershell).
Abro una sesión de WSL2:
sudo apt install fontconfig unzip
mkdir -p ~/.fonts
cd .fonts
curl -LJs -o FiraCode.zip https://github.com/ryanoasis/nerd-fonts/releases/download/v3.2.1/FiraCode.zip
unzip FiraCode.zip && rm FiraCode.zip
fc-cache -fv
Instalo la última versión de startship en WSL2:
curl -sS https://starship.rs/install.sh | sh
El siguiente paso es configurar el .zshrc
(mira la sección anterior WSL 2 - Cambio a ZSH donde tengo un enlace al que utilizo yo.
WSL 2 - Cambiar UID/GID
Durante la instalación tube un problema, la primera vez me instaló Ubuntu22.04 y puso a mi usuario luis
el UID/GID 1000:1000, activé metada como mencionaba antes para la gestión de permisos y todo bajo /mnt/c
pasó a ser propiedad de 1000:1000. Hasta ahí todo bien.
El problema vino al instalar Ubuntu24.04 y eliminar la 22.04. Observé que crea por defecto el usuario ubuntu y el grupo lxc
con UID/GID 1000, y al usuario luis
le asignó el 1002
. Eso provocó un líó de permisos enorme.
Esto es lo que hice para arreglarlo:
PS > wsl --install Ubuntu24-04
PS > ubuntu2404.exe config --default-user root
PS > wsl --shutdown
PS > ubuntu2404.exe
nano /etc/group cambié los gid
lxc 1000 -> 1001
ubuntu 1001 -> 1002
luis 1002 -> 1000
nano /etc/passwd cambié los uid
ubuntu 1000 -> 1002
luis 1002 -> 1000
cd /home
chown -R luis:luis luis
chown -R ubuntu:ubuntu ubuntu
Reviso el fichero de configuración. Aquí tienes una copia: /etc/wsl.conf.
PS > ubuntu2404.exe config --default-user luis
PS > wsl --shutdown
PS > ubuntu2404.exe
Nota: Para hacer búsquedas de los permisos y que no se eternice entrando en /mnt/c
uso el comando siguiente:
cd /
find . -not \( -path "./mnt*" -type d -prune \) -user ubuntu
Modificar el PATH
PATH de Windows (para CMD
, PowerShell
):
Consulta la nota sobre el PATH que puse al principio de este apunte.
WSL2:
En mi caso prefiero que WSL2 no me añada todos las entradas del PATH de Windows al de Linux, modifico /etc/wsl.conf
y añado la sección:
[interop]
appendWindowsPath=false
Aquí tienes una copia: /etc/wsl.conf.
- Salgo de WSL, lo apago (
wsl --shutdown
), vuelvo a entrar y edito~/.bashrc
o.zshrc
. Este es un ejemplo de cómo queda (soy selectivo en qué quiero del PATH de windows en mi sesión WSL2).
⚡ luis@kymeraw:~ % echo $PATH
/mnt/c/Users/luis/.gems/bin:.:/mnt/c/Users/luis/Nextcloud/priv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/PowerShell/7
Windows Terminal
Ahora que tengo WSL2 perfectamente operativo, voy a instalarme Windows Terminal, una herramienta que permite configurar y arrancar múltiples consolas en pestañas o ventanas separadas, lo que simplifica enórmemente el punto de entrada. Solo tengo un sitio desde donde configurar y hacer clic.
- Abro la Microsoft Store,
Start
> busco por “Store” - Busco por “Windows Terminal”. Instalo o Actualizo
Configuración inicial de Windows Terminal
- Abro Windows Terminal
Start
busco “Terminal” - Accedo a la configuración
- Clic en ‘flecha abajo’ >
Settings
oCtrl + ,
.
- Clic en ‘flecha abajo’ >
- Configurar perfiles de consola:
- En el panel izquierdo, veo perfiles como
Windows PowerShell
,CMD
,Ubuntu
, etc. Aquí puedo personalizar cada uno de ellos. - Cambiar el shell predeterminado: Si deseas que siempre se abra un perfil específico al iniciar Windows Terminal, selecciona el perfil en el menú “Startup” bajo “Default profile”.
- En el panel izquierdo, veo perfiles como
- Personalizar apariencia:
- Puedes cambiar el tema, fuente, esquema de colores y más para cada perfil.
- Agregar nuevas consolas (opcional)
Anclar Windows Terminal al Taskbar, tan sencillo como con otras Apps
- Lo busco y lo abro
- Hago clic derecho en el ícono de Windows Terminal en la barra de tareas.
- “Pin to taskbar” (Anclar al taskbar).
Tendrás acceso rápido a Windows Terminal directamente desde tu taskbar, y podrás abrir rápidamente cualquier consola que necesites con solo un clic.
Usar múltiples pestañas en Windows Terminal: Podemos hacer varias cosas
- Abrir nuevas pestañas: ícono
+
o atajoCtrl + Shift + T
. - Cambiar entre pestañas:
Ctrl + Tab
- Cerrar pestañas: ícono
X
oCtrl + Shift + W
. - Sacar las pestañas como ventanas independientes: Botón derecho sobre la pestaña
Empiezo a trabajar de manera más eficiente y organizada. Tengo la posibilidad de abrir la consola que necesite, por defecto lo he configurado para que WSL (Ubuntu 24.04.3 LTS), he cambiado los colores ligeramente para diferenciar dónde estoy y en el caso de cmd.exe
he puesto otro tipo de fuente de letra.
Configuración settings.json
y state.json
: Gran parte de esta personalización de Windows Terminal se gestiona a través de dos archivos clave: settings.json
(nucleo de la personalización, puedes editarlo desde el propio menú) y state.json
(estado actual del Terminal).
Aquí tienes el mi fichero de configuración settings.json que utilizo en mi ordenador. Nota: los uuid
del mismo serán distintos en tu caso. No lo copies/pegues tal cual o no te funcionará.
A partir de aquí empieza la segunda parte del apunte, la instalación de las herramientas y lenguajes de programación. Las instalo todas en Windows 11 (lo digo porque quizá alguna merecería la pena instalarlas dentro del WSL2, por ejemplo Ruby
).
Un aviso respecto a .NET, lo dejo para el final, empiezo por las herramientas multiplataforma, porque considero hay que instalarlas en todo equipo de desarrollo (tanto en Windows como Linux o Mac), continúo con los lenguajes que he elegido para mi Windows y dejo para el final .NET y Visual Studio.
Herramientas multiplataforma
VSCode
Lo instalo desde el sitio oficial de Visual Studio Code. Diría que es el editor de código fuente más potente que he visto nunca, con soporte de cientos de extensiones muy útiles, la posibilidad de abrir diferentes terminales integrados dentro de la misma ventana de VS Code, como CMD, PowerShell, Git Bash o WSL. S
Además, soporta una amplia variedad de lenguajes de programación y la posibilidad de trabajar con equipos remotos.
Settigs y Sincronización: Echa un ojo al apunte VSCode settings y extensiones donde mantengo cómo lo gestiono y mi configuración.
Creo una especie de alias, en linux y en Mac me gusta crear un alias que llamo “e” (de editor), para llamar a mi editor preferido. Desde una sesión de Administrador edito el script c:\windows\e.cmd
. Ya tengo mi alias, será válido para cmd y powershell
@echo off
"C:\Users\luis\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd" %*
Git for Windows
El objetivo principal es tener acceso a git.exe
desde las consolas nativas CMD
, PowerShell
y aplicaciones de terceros.
Instalo desde el sitio oficial de Git. Se instala en C:\Program Files\Git
. Nota: incluye el ejecutable .\bin\bash.exe
, tienes otro bajo WSL2 C:\Windows\System32\bash.exe
, tenlo en cuenta (el orden en el PATH, mira la nota sobre el PATH).
Decisiones que he tomado durante la instalación:
- Bundled
ssh
&openssl
: Selecciono Use the bundled OpenSSH (voids W11 issue) and bundle OpenSSL. Cuando preparé este apunte la versión de SSH de Windows 11 tiene problemas con repositorios grandes de Git. - Handling of CRLF: Selecciono siempre Checkout as-is, commit Unix-style line endings. Ver la sección sobre crlf.
- PATH (related to Git Bash): Yo no uso Git Bash, por lo que selecciono Git from the command line and also from 3rd-party software. Aunque luego añado dicho PATH manualmente al sistema.
Usé la versión Git-2.46.0-64-bit.exe
:
Decía que no Git Bash, pero si que me aprovecho de todo lo que trae, es una pasada, tengo a mi disposición un montón de ejecutables “estilo linux” pero en CMD/PowerShell, por lo tanto añado manualmente al PATH un par de directorios, C:\Program Files\Git\mingw64\bin
y C:\Program Files\Git\usr\bin
, al PATH del sistema para tener acceso a estos regalos:
Git for Windows además te instala MinGW-w64, una bifurcación de MinGW (Minimalist GNU for Windows) que proporciona un conjunto de herramientas y un entorno de desarrollo para compilar y ejecutar aplicaciones de código abierto, principalmente en C y C++, en sistemas Windows. Es crucial si compilas aplicaciones para Windows usando herramientas y entornos tradicionales de GNU/Linux.
Por cierto, cuando no sepas dónde está el ejecutable…
Docker Desktop
Permite la creación y gestión de contenedores, lo que es esencial para el desarrollo y despliegue de aplicaciones en entornos aislados. Muy útil cuando estás desarrollando Servicios (por ejemplo en Go
, NodeJS
).
Mis casos de uso son varios, poder ejecutar procesos contenerizados (por ejemplo una base de datos), dockerizar Servicios desarrollados (por ejemplo en Go o NodeJS), hacer pruebas de CI para DevOps, laboratorios de Microservicios, etc. Instalo desde el sitio oficial de Docker. Su integración con WSL2 es fundamental y el haberlo preparado antes nos ayuda a tener una instalación fluída.
Durante el proceso de instalación selecciono usar WSL2 en vez de Hyper-V
Integración con WSL2
La integración con WSL2 es inmediata, no tienes que hacer nada. Bueno, casi nada. Hay un tema importante “El contexto”.
Al entrar en una sesión de WSL2 es importante estar en el Contexto adecuado de Docker. Si no tienes el correcto puedes encontrarte con el error Failed to initialize: protocol not available
.
PS > ubuntu2404.exe
$ docker ps -a
Failed to initialize: protocol not available
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default Current DOCKER_HOST based configuration unix:///var/run/docker.sock
desktop-linux * Docker Desktop npipe:////./pipe/dockerDesktopLinuxEngine
En este caso estamos en el contexto desktop-linux
lo que provocará que WSL2 no se pueda comunicar correctamente con Docker. Puedes cambiar de contexto con el comando docker context use default
pero no será permanente. Lo mejor es editar el fichero ~/.docker/config.json
nano ~/.docker/config.json
:
"currentContext": "default",
:
A partir de este momento funcionará correctamente
PS > ubuntu2404.exe
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT ERROR
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
desktop-linux Docker Desktop npipe:////./pipe/dockerDesktopLinuxEngine
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
:
CUIDADO!! si has cambiado el HOME de WSL 2 a /mnt/c/Users/<usuario> (ver aquí) cada vez que arranques Docker sobreescribe el fichero C:\Users\<usuario>\.docker\config.json por lo que es inútil editarlo. La solución consiste en eñadir docker context use default al final de tu .bashrc/.zshrc |
Postman
Puedes instalar desde el sitio oficial de Postman. Es una herramienta muy conocida para probar y documentar APIs. Es muy útil para desarrolladores que trabajan con servicios web. En mi caso de momento la dejo en la recámara, quizá la instale más adelante.
HTTPie
Muy en la línea de Postman, hace poco encontré esta otra herramienta, soporta trabajar tanto en la línea de comandos o GUI para realizar solicitudes HTTP, diseñada para ser simple y fácil de usar, ideal para probar y depurar APIs de manera rápida y eficiente. Me gusta más que Postman, sobre todo por la parte de la línea de comandos. La instalo desde el sitio oficial de HTTPie.
Necesitas instalar Chocolatey, un gestor de paquetes potentísimo para Windows. Yo lo he instalado para instalarme httpie
, pero de momento no lo estoy usando para nada más, reconozco que tengo que investigarlo.
Lenguajes de programación
Python, Pip y PipEnv
Python es un lenguaje de programación interpretado, versátil y fácil de aprender, lo que más me gusta es que es muy legible y soporta múltiples paradigmas como la programación orientada a objetos, funcional e imperativa. Hay mucha herramienta que lo necesita y tiene muchos casos de uso. Aunque en mi caso no lo uso casi nunca, siempre lo instalo.
Pip es una herramienta fundamental para gestionar paquetes de Python. Es el sistema utilizado para instalar y manejar librerías de terceros desde el Python Package Index (PyPI), el repositorio oficial de Python.
PipEnv es otra herramienta imprescindible para gestionar entornos virtuales. Cuando se desarrollan aplicaciones en Python, es necesario utilizar varias librerías externas que pueden entrar en conflicto entre proyectos. Con PipEnv
, podemos gestionar un entorno virtual donde todos los paquetes se instalan sin afectar al sistema principal. Existen alternativas como Virtualenv y Conda, pero en mi caso siempre uso PipEnv
.
- Instalar Python desde python.org. Descargo la última versión.
Antes de ejecutar el instalador: Importante quitar los alias que Windows 11 trae por defecto a python.exe
o python3.exe
. Ejecuta desde Search
> “Manage app execution aliases
”. Desactiva los dos alias “python” and “python3”.
Durante la instalación selecciono las siguientes opciones, para tener disponible py.exe
, python.exe
desde cualquier terminal.
Además creo un alias a python3
, creo el script c:\windows\python3.cmd
.
@echo off
"C:\Program Files\Python312\python.exe" %*
- Instalar PipEnv. Una vez tengas Python y Pip instalados, abre una terminal de Windows (cmd o PowerShell) y ejecuta:
pip install --user pipenv
Importante, añadir el directorio de los scripts al PATH, tal como se recomienda durante la instalación de pipenv
:
C:\Users\<usuario>\AppData\Roaming\Python\Python312\Scripts
Siempre que instalo hago una prueba de concepto, con un mini proyecto, un único fuente llamado main.py
bajo el entorno virtual pipenv
, con una única librería requests
.
mkdir tmp
cd tmp
pipenv install requests
pipenv lock
Creo el fuente con notepad main.py
import requests
response = requests.get('https://httpbin.org/ip')
print('Tu dirección IP es: {0}'.format(response.json()['origin']))
Ejecuto la prueba de concepto con pipenv run python main.py
C/C++
Como este es un apunte multiplataforma, para trabajar en C/C++ elijo CLang V17, estándar C++20. El compilador CLang pertenece al proyecto LLVM
, acrónimo de “Low-Level Virtual Machine”, que se convirtió en algo mucho más grande con el tiempo. Clang es un compilador de C, C++, y Objective-C, modular, rápido y definitivamente multiplataforma.
Para saber cómo instalarlo en Windows mejor consulta este ejemplo que tengo en GitHub, git-repo-eol-analyzer
, que demuestra el trabajo multiplataforma, funciona en Windows, Linux y MacOS y explica todos los pasos para preparar el entorno: instalar Clang, CMake, Clang-format e incluso la integración con VSCode.
Si quieres un acceso rápido a la instalación en Windows: - Descarga e instala CLANG 17.0.1 desde el sitio de las Releases oficiales (link directo a LLVM 64bits 17.0.1 para Windows).
CMake
Muy vinculado a C/C++, CMake es una herramienta de código abierto que gestiona la configuración y generación de scripts de compilación para proyectos multiplataforma. Permite abstraer las configuraciones específicas de cada plataforma, simplificando la creación de archivos de construcción (Makefiles, proyectos de Visual Studio, etc.). En proyectos C++ en Windows, CMake se integra perfectamente con VSCode, permite generar de forma automática los proyectos, etc.
Para instalarlo en Windows: desde el sitio oficial, me bajo el Windows x64 Installer. También te recomiendo instalar Ninja (Generador) desde su repositorio oficial y guardarlo en un directorio que ya tengas en el PATH.
El proceso básico de CMake consta de dos pasos:
-
Configurar (Configure): Analiza el archivo
CMakeLists.txt
, crea todos los scripts y ficheros específicos para que el sistema luego pueda generar (compilar) el código. El resultado de la configuración se realiza en el subdirectorio ./build. -
Generar (Build): A partir del paso anterior, CMake compila para el entorno de desarrollo y sistema en el que estemos, por ejemplo un proyecto con un
Makefile
o cosas más complejas.
CMake sigue un enfoque declarativo, se define lo que el proyecto necesita (fuentes, bibliotecas, dependencias) en el archivo CMakeLists.txt
. Repasa el que he creado en el proyecto que mencionaba antes: git-repo-eol-analyzer
.
Golang
Golang es un lenguaje que combina la simplicidad y eficiencia de lenguajes antiguos como C, con las características modernas necesarias para el desarrollo de software concurrente y de alto rendimiento. Es especialmente popular en el desarrollo de sistemas distribuidos, servicios en la nube y herramientas de red, gracias a su enfoque en la concurrencia y la escalabilidad.
- Para instalarlo en Windows, ve a la página de descargas de Go me bajo la útima versión del MSI para windows-amd64, lo instala por defecto con
C:\Program Files\Go\bin
que añade al PATH. - Para integrarlo con VSCode instalo la extensión
golang.go
.
Algunas variables críticas para un entorno de desarrollo eficiente en Go:
$GOROOT
: Ruta de instalación (por defectoC:\Program Files\Go
).$GOPATH
: Directorio de trabajo por defectoC:\Users\<usuario>\go
.- La instalación añade al PATH
$GOROOT\bin
y$GOPATH\bin
.
A partir de Go 1.11, se introdujo el sistema de módulos Go Modules que gestiona dependencias de manera más eficiente. Lo habilito con go env -w GO111MODULE=on
y hago un pequeño programa para comprobar que todo está bien.
Inicializo el módulo del proyecto:
go mod init hola
Creo el archivo main.go
:
package main
import "fmt"
func main() {
fmt.Println("Hola, mundo")
}
Compilo y ejecuto y luego compilo el binario hola.exe
go run main.go
go build
.NET
Hablar de .NET
lia un poco a no ser que hayas vivido y experimentado toda su evolución. Ha fecha de hoy tenemos:
- .NET Framework: Solo está disponible en Windows y se mantendrá en su versión 4.8, principalmente para soportar aplicaciones que lo necesitan.
- .NET (5 y versiones posteriores): Es multiplataforma, más moderno y la evolución natural de .NET Core, no de .NET Framework.
.NET Framework
El .NET Framework es una plataforma de desarrollo creada por Microsoft para construir y ejecutar aplicaciones en Windows. Incluye muchas bibliotecas de clases para hacer Apps de escritorio, servicios web, aplicaciones web, etc. Se usa mucho en todo tipo de Apps que corren en Windows.
Lo vas a instalar sí o sí, aunque el futuro sea .NET (core .5), me da igual si acabas teniendo el Runtime como si acabas teniendo el Developer Pack (incluye el Runtime, necesario para desarrollar). Yo no voy a necesitar el .NET 3.5 (incluye .NET 2.0) porque no creo que instale Apps antiguas que requieran dicho Framework, pero el que sí que voy a necesitar es el .NET 4.8 porque es el último y seguro que algún app me lo pide. Por ejemplo, HTTPie necesita que tengas el Runtime.
Puedes instalarlo desde la Programas y características del panel de control o desde la Web de microsoft). Si uso el primer método, verifico antes qué tengo y luego instalo.
- Abro Control Panel > Programs > Programs and Features > Turn Windows features on or off.
- Aquí se puede ver la versión de .NET Framework instaladas.
- En la lista de características, busca las versiones de .NET Framework disponibles (por ejemplo, .NET Framework 3.5 o .NET Framework 4.8).
- Marca la casilla junto a la versión que deseas instalar.
- Haz clic en Aceptar y espera a que Windows complete la instalación.
Si la versión no está en la lista, puedo ir a la Web de microsoft, (ejemplo para la 4.8.1
.NET 5 / Core
Pendiente de documentar
Work in Progress
Esta sección la marco como “Trabajo en curso (WiP en inglés)”, porque hay decenas de apps, utilidades, comandos, entornos de desarrollo y es imposible documentarlos todos. Mi objetivo realmente era romper el hielo. Realmente estos apuntes vienen bien para tener una bitácora de mi instalación, por si tengo que repetirla, pero sobre todo porque espero que te venga bien a ti como ejemplo.
Iré documentado/añadiendo lo nuevo que vaya instalando, cosas que tengo en la cabeza: Compilador de C/C++, Node.js, JDK de Java, BBDD locales (Si lo hago será con Docker).
Aprendizaje continuo
Para terminar, voy a insistir un poco más sobre Shell y Linux. Si vienes de Windows, te recomiendo aprender a utilizar la Shell; es una habilidad fundamental para cualquier desarrollador de software. La Shell permite automatizar tareas, ejecutar comandos, y manejar el sistema de una manera más eficiente y rápida que a través de interfaces gráficas. Existen muchos recursos disponibles para aprender a utilizar la Shell, tanto en bash
como en zsh
, te dejo algunas referencias
- Curso en Español: Curso de Introducción a la Terminal y Comandos Básicos
- Curso en Inglés: Command Line Basics (Udemy)
- Comandos Bash: GNU Bash Reference Manual
- Comandos Zsh: Zsh Users Guide
Además te recomiendo que eches un ojo a algún curso sobre la filosofía de trabajo en Unix, fundamental para comprender Linux. Cómo y por qué los comandos y programas de Unix/Linux están diseñados de la manera en que lo están. La idea principal es que un programa ‘debería hacer una cosa y hacerla bien’. Esta filosofía también abarca conceptos clave como la entrada y salida, el sistema de archivos, la estructura de directorios y la idea de que ‘todo es un fichero’ en Unix. Te dejo algunos cursos cortos y didácticos que cubren estos temas:
- Curso en Español: Introducción a Unix y Linux - Filosofía y Conceptos Básicos, donde se abordan la estructura de directorios, la gestión de ficheros, y la filosofía Unix de diseño de programas.
- Curso en Inglés: The Unix Workbench (Coursera), un curso introductorio que explica la filosofía de Unix, incluyendo la entrada y salida, y cómo interactuar con el sistema de archivos.
- Curso en Inglés: Linux Command Line Basics - Learn the Shell, Philosophy, and More (Udemy), un curso que cubre tanto los comandos esenciales como los principios filosóficos de Unix/Linux.
- Curso en Inglés: Understanding the Unix Philosophy (LinkedIn Learning), un curso corto que ofrece una visión general sobre la filosofía de Unix y su aplicación práctica.
Por último, he seleccionado 50 comandos (hay muchos más) que deberías conocer como desarrollador de software multiplataforma. Son esenciales para la navegación del sistema de archivos, gestión de procesos, manipulación de texto, y otras tareas comunes en el desarrollo de software. Cada comando incluye un enlace a su respectiva manpage en Ubuntu 24.04.
Comando | Descripción | Comando | Descripción |
---|---|---|---|
ls | Lista los archivos y directorios en el directorio actual. | alias | Crea un alias para un comando o una serie de comandos. |
cd | Cambia el directorio de trabajo actual. | unalias | Elimina un alias previamente definido. |
pwd | Muestra el directorio de trabajo actual. | history | Muestra el historial de comandos utilizados. |
cp | Copia archivos y directorios. | env | Muestra o modifica las variables de entorno. |
mv | Mueve o renombra archivos y directorios. | export | Define variables de entorno para los procesos secundarios. |
rm | Elimina archivos y directorios. | source | Ejecuta comandos desde un archivo en el contexto de la Shell actual. |
mkdir | Crea nuevos directorios. | uname | Muestra información sobre el sistema operativo. |
rmdir | Elimina directorios vacíos. | uptime | Muestra el tiempo que lleva encendido el sistema. |
touch | Cambia las marcas de tiempo de un archivo o crea archivos vacíos. | whoami | Muestra el nombre del usuario actual. |
echo | Muestra una línea de texto o variable. | which | Localiza un comando y muestra su ruta completa. |
cat | Concatenar y mostrar el contenido de archivos. | head | Muestra las primeras líneas de un archivo. |
grep | Busca patrones en el contenido de archivos. | tail | Muestra las últimas líneas de un archivo. |
find | Busca archivos y directorios en una jerarquía de directorios. | sort | Ordena líneas de texto en un archivo o entrada. |
chmod | Cambia los permisos de acceso de los archivos. | uniq | Muestra o filtra líneas repetidas consecutivas en un archivo. |
chown | Cambia el propietario de archivos y directorios. | diff | Compara archivos línea por línea. |
ps | Muestra el estado de los procesos actuales. | tee | Lee de la entrada estándar y escribe en la salida estándar y en archivos. |
kill | Envía señales a procesos, como detenerlos. | xargs | Construye y ejecuta líneas de comando desde la entrada estándar. |
top | Muestra los procesos en ejecución y el uso de recursos. | jobs | Muestra el estado de los trabajos en segundo plano. |
df | Muestra el uso del espacio en disco de los sistemas de archivos. | bg | Reanuda un trabajo suspendido en segundo plano. |
du | Estima el uso del espacio en disco por archivos y directorios. | fg | Trae un trabajo suspendido al primer plano. |
tar | Manipula archivos tar. | alias | Crea un alias para un comando o una serie de comandos. |
zip | Comprime archivos en formato ZIP. | unalias | Elimina un alias previamente definido. |
unzip | Descomprime archivos en formato ZIP. | history | Muestra el historial de comandos utilizados. |
ssh | Se conecta a servidores remotos de forma segura a través de SSH. | env | Muestra o modifica las variables de entorno. |
scp | Copia archivos entre servidores de forma segura. | export | Define variables de entorno para los procesos secundarios. |
wget | Descarga archivos desde la web. | source | Ejecuta comandos desde un archivo en el contexto de la Shell actual. |
curl | Transfiere datos desde o hacia un servidor. | uname | Muestra información sobre el sistema operativo. |
nano | Editor de texto simple para la terminal. | uptime | Muestra el tiempo que lleva encendido el sistema. |
vim | Editor de texto avanzado en la terminal. | whoami | Muestra el nombre del usuario actual. |
man | Muestra el manual de usuario de cualquier comando. | which | Localiza un comando y muestra su ruta completa. |