TCP (Transmission Control Protocol) es el protocolo de transporte sobre el que se construye la mayor parte de internet — HTTP, SMTP, SSH, y prácticamente cualquier comunicación en red. Garantiza que los datos lleguen completos y en orden entre dos puntos.
nc (netcat) es una herramienta de línea de comandos que abre conexiones TCP de forma directa, sin protocolo propio encima. Me parece que puede ser muy útil para hacer backups sin usar practicamente nada de recursos de hardware, para no depender prácticamente nada de dependencias externas y para simplificar brutalmente la depuración.
Creo que esta herramienta es muy útil, sobre todo usando IPv6, donde cada dispositivo dispone de una dirección pública real y las conexiones entre dos puntos pueden establecerse de forma completamente directa, sin servidores intermediarios ni técnicas para atravesar NAT.
Establecer una conexión usando nc es extremadamente fácil.
En un computador hay que abrir un puerto que escuche:
nc -l -6 1234
Y en el otro hay que conectarse a la IPv6 de esa computadora y el puerto:
nc 2607:f8b0:4004:c09::64 1234
¡Listo! Solo con eso se establece la conexion y se podrán emitir mensajes por los dos lados.
nc envía bytes crudos, por lo cual es posible enviar cualquier stream de bytes.
Este ejemplo muestra como se podría enviar una imágen:
Receptor
nc -l 1234 > imagen.jpg
emisor
nc 2607:f8b0:4004:c09::64 1234 < imagen.jpg Macos tiene dos comandos para controlar el portapapeles en la terminal pbcopy y pbpaste. Ambos leen el std-in/out para copiar y pegar
Copiar al portapapeles:
echo "portapapeles" | pbcopy
Copiar en multilínea usando heredoc:
cat <<EOF | pbcopy
linea#1
linea#1
EOF
Pegar del portapapeles:
pbpaste > salida.txt
```Como Hasta el día de hoy siempre he preferido usar IPv4 sobre IPv6 para conectarme a mi servidor por SSH, compartir carpetas por SSHFS o direccionar servidores web. Sin embargo hoy me doy cuenta de que usar IPv6 genera ventajas de rendimiento que son claramente visibles sobretodo para entornos interactivos como SSH.
La razón principal es que IPv6 elimina la necesidad de NAT (Network Address Translation). Con IPv4, en la mayoría de los entornos domésticos y corporativos, el tráfico debe atravesar una o varias capas de traducción de direcciones antes de llegar a su destino. Cada salto a través de un dispositivo NAT introduce una pequeña latencia adicional y, en el caso de SSH, donde cada pulsación de tecla genera un paquete independiente, esas fracciones de milisegundo se acumulan y se perciben como una leve pero molesta lentitud en la respuesta del terminal.
Con IPv6, en cambio, el cliente se conecta directamente al servidor mediante una dirección global única, sin intermediarios que reescriban cabeceras ni mantengan tablas de estado. El resultado es una comunicación extremo a extremo más limpia, con menor latencia y sin los problemas de traversal que a veces afectan a protocolos como SSHFS cuando el túnel debe negociar con firewalls con estado o routers que hacen NAT de forma agresiva.
Dicho esto, ahora mismo voy a reconfigurar los dominios de mis sitios web con registros AAAA que utilizan IPv6, eliminando por completo el soporte de IPv4.
Personally, I think the best way to delete folders is using this command:
rm -rfv folder Personalmente creo que la mejor manera de tener los archivos seguros es encriptándolos con OpenSSL. En vez de comprimir un archivo zip o rar con contraseña o encriptar un documento PDF, resulta más seguro y fiable encriptar usando OpenSSL usando la doble extensión ".extension.aes".
Las ventajas de hacer esto son la claridad que se tiene de qué método de encriptación se está usando y cómo, poder definir parámetros con gran grado de personalización y una garantía de compatibilidad futura.
Al menos en mi caso particular, uso la encriptación para backups y copias de archivo, por lo cual me interesa tener al máximo la garantía de que el archivo va a ser legible ahora o en cuarenta años. Por eso es importante tener en cuenta las siguientes sugerencias:
Este es los comandos de encripración/desencriptación que usaré:
La staging area (también llamada index) es una zona intermedia donde Git prepara qué archivos formarán parte del próximo commit.
Añadir archivos al stage:
git add . # añade todo desde el directorio actual
git add archivo.js # añade un archivo concreto
git add carpeta/ # añade una carpeta entera
Ver el estado del stage:
git status # qué está staged, modificado o untracked
git diff --staged # ver qué cambios concretos hay staged
Sacar archivos del stage:
Hay dos comandos para "vaciar" el stage, pero hacen cosas distintas. Confundirlos es muy común. La elección depende de si el archivo ya estaba en algún commit anterior o no.
| Comando | Qué hace | Cuándo usarlo |
|---|---|---|
git restore --staged . |
Deshace el git add. El archivo sigue tracked si ya estaba en algún commit; si era nuevo, vuelve a untracked. |
Cuando se ha hecho add de algo que aún no se quería commitear. Es el "deshacer un add" del día a día. |
git rm -r --cached . |
Destrackea los archivos: los saca del index y los marca para borrarse del repositorio en el próximo commit. No toca el Working Directory. | Cuando un archivo ya estaba commiteado y se quiere que Git deje de seguirlo (típicamente después de añadirlo al .gitignore). |
Aclaración importante: en la versión anterior de este post se usó git restore --staged . como si destrackeara archivos, pero no es así. restore --staged solo deshace un add reciente; no puede destrackear un archivo que ya está en commits anteriores. Para eso es necesario git rm -r --cached.
Caso típico: .env añadido al .gitignore tarde
# El archivo ya está en commits anteriores
echo ".env" >> .gitignore # añadirlo al gitignore no basta
git rm --cached .env # destrackearlo
git commit -m "Dejar de trackear .env"
# A partir de aquí, .gitignore por fin tiene efecto sobre .env
Esto no elimina el archivo del historial: los commits viejos siguen conteniéndolo. Si era un secreto, hay que rotarlo y reescribir historia con git filter-repo.
Un commit es una instantánea del proyecto en un momento dado. Forman una cadena que constituye el historial del repositorio.
Crear un commit:
git commit -m "Mensaje descriptivo"
git commit -am "Mensaje" # add + commit de archivos ya tracked (no incluye nuevos)
Ver el historial:
git log # historial completo
git log --oneline # versión compacta, una línea por commit
git log --graph --oneline # visualización del grafo de ramas
Restaurar todo al estado del último commit:
git reset --hard HEAD
No borra archivos untracked (los que Git no conoce). Para limpiar también esos, conviene combinarlo con git clean -fd.
Deshacer commits:
Los tres reset se diferencian en qué zonas afectan:
| Comando | Qué hace | Working Dir | Stage | Commits |
|---|---|---|---|---|
git reset --soft HEAD~1 |
Quita el commit, deja los cambios staged listos para recommittear. | Intacto | Intacto | Retrocede 1 |
git reset HEAD~1 (mixed) |
Quita el commit y saca los cambios del stage. Los cambios quedan como "modified". | Intacto | Vaciado | Retrocede 1 |
git reset --hard HEAD~1 |
Quita el commit y descarta los cambios completamente. Destructivo. | Retrocede 1 | Retrocede 1 | Retrocede 1 |
--hard es irreversible para cambios no commiteados. En caso de duda, conviene usar --soft o --mixed primero.
Alternativa segura: git revert
git revert HEAD # crea un commit NUEVO que deshace el anterior
A diferencia de reset, no reescribe historia. Es lo recomendado en ramas compartidas.
Restaurar temporalmente el área de trabajo
En muchas ocasiones puede ser importante el restaurar el área de trabajo para ver cómo era el estado anterior de algún archivo en particular. Para hacer esto, usar:
git checkout <commit>
Stash es un almacén temporal donde se pueden guardar estados y cambios de forma aislada. Deja el working tree en el estado del último commit HEAD además de limpiar el stage area (a menos que se use --keep-index).
Comportamiento:
Las versiones guardadas en el stash están aislados ente sí. En cambio cada stash tiene como padre el HEAD de la rama desde donde se crea este. Los stash se guardan en un stack y debido a que no están relacionados entre sí, es posible borrar un stash que está en un nivel inferior sin ningún tipo de consecuencia. Es importante notar que los stash no se guardan en los remotos sino que se guardan exclusivamente de manera local.
Crear un stash:
Para crear un stash se debe usar el siguientre comando:
git stash push
Si se quiere crear un stash sin eliminar el index (como se había mencionado antes):
git stash push --keep-index
Si se desea agregar una descripción, usar:
git stash push -m "My stash"
El Stack de Stash:
El stack de Stash es una pila LIFO (La última en agregarse es la primera en irse). Los nombres de cada stash vienen numerados dinámicamente usando el modelo stash@{x}. El siguiente cuadro ejemplifica el stack de stash:
refs/stash ──> stash@{0} "wip login" ─┐
stash@{1} "pruebas API" ├─ todos cuelgan de HEAD,
stash@{2} "WIP on main" ─┘ no unos de otros
│
└── entradas del reflog de refs/stash
Poniéndonos un poco más técnicos, la pila se guarda en dos archivos, el primero guarda la referencia de la última entrada guardada y el segundo guarda las referencias de todos los stash guardados.
.git/refs/stash ──────────> último stash
.git/logs/refs/stash ────────> todos los stash
Comandos de Stash A continuación se presenta una tabla con algunos de los comandos de stash.
| Comando | Efecto |
|---|---|
git stash push |
apila una entrada nueva en stash@{0} |
git stash list |
muestra la pila entera |
git stash show -p stash@{N} |
el diff de una entrada |
git stash apply stash@{N} |
aplica, sin eliminarla |
git stash pop stash@{N} |
aplica y la elimina |
git stash drop stash@{N} |
la saca sin aplicar |
git stash clear |
vacía la pila |
git reflog stash |
la pila en crudo, con hashes |
Al incorporar el trabajo de una rama en otra, Git ofrece tres métodos según la situación.
Posible solo cuando la rama base (master) no tuvo commits propios mientras existía la otra rama. Git mueve el puntero hacia adelante sin crear ningún commit nuevo. El historial queda lineal, como si la rama nunca hubiera existido.
Antes:
commit1 → commit2 (master)
↘
commit3 → commit4 (rama-1)
Después:
commit1 → commit2 → commit3 → commit4
↑
master, rama-1
Cuando ambas ramas tienen commits propios, Git crea un commit de merge con dos padres. El historial refleja honestamente que hubo dos líneas paralelas.
Antes:
commit1 → commit2 → commit3 → commit6 → commit7 (master)
↘
commit4 → commit5 (rama-1)
Después:
commit4 → commit5
↗ ↘
commit1 → commit2 → commit3 → commit6 → commit7 → mergeCommit
↑
master
Reescribe los commits de la rama para que parezcan haber salido del último commit de master. El historial queda lineal, pero "miente" sobre cómo ocurrió el desarrollo real.
Antes:
commit1 → commit2 → commit3 → commit6 → commit7 (master)
↘
commit4 → commit5 (rama-1)
Después:
commit1 → commit2 → commit3 → commit6 → commit7 → commit4' → commit5'
↑
rama-1
Los commit4 y commit5 originales quedan huérfanos y git gc los eliminará eventualmente. commit4' y commit5' son nuevos commits con los mismos cambios pero distinto hash.
Regla práctica:
Descartar cambios locales en archivos tracked:
git restore . # versión moderna (Git 2.23+)
git checkout . # versión clásica, sigue funcionando
Sustituye los archivos modificados por la versión del stage (o de HEAD si no hay nada staged).
Eliminar archivos untracked del Working Directory:
git clean -fd
# │└─ d: incluir directorios untracked
# └── f: force (obligatorio por seguridad)
git clean -nd # DRY RUN: muestra qué borraría sin borrar nada
git clean -fdx # también borra archivos ignorados (.env, node_modules, etc.)
Conviene ejecutar siempre git clean -n primero. Los archivos borrados con clean no van a la papelera y, por ser untracked, Git no puede recuperarlos. Con -x se pueden perder archivos como .env con credenciales locales.
Combinación "dejar el repo como recién clonado":
git reset --hard HEAD && git clean -fd
Descarta cambios en archivos tracked y borra los untracked. El Working Directory queda exactamente igual al último commit.