24 puntos por GN⁺ 2025-10-23 | 2 comentarios | Compartir por WhatsApp
  • Presenta los shell scripts que más usa entre varios que ha escrito mientras mantiene sus dotfiles desde hace más de 10 años
  • Están divididos en portapapeles, gestión de archivos, internet, procesamiento de texto, lanzadores de REPL, fecha/hora, audio y video, procesos, referencia rápida, sistema y misceláneos, y cada script se muestra como un wrapper corto junto con ejemplos prácticos de uso
  • La mayoría de los scripts funcionan en macOS y Linux, y la filosofía central es “aplanar las pequeñas molestias engorrosas de las herramientas que ya existen”
    • Integración de utilidades estándar como pbcopy/xclip, python3 -m http.server, yt-dlp, ffmpeg, mpv, etc.
  • Entre los más usados están copy/pasta/pastas/cpwd, mkcd/tempe/trash/mksh, serveit/getsong/getpod/getsubs, scratch/straightquote/markdownquote, timer/boop/tunes, etc.

Presentación de los scripts que más uso y que hice mientras mantenía mis dotfiles

  • Organiza por categorías varios shell scripts que ha creado mientras administra sus dotfiles personales desde hace más de 10 años, enfocándose en los que usa con frecuencia
  • Cada script incluye su propósito, frecuencia de uso y ejemplos representativos, lo que aumenta su utilidad inmediata
  • El objetivo común es acortar tareas repetitivas, abstraer diferencias entre plataformas y mejorar la seguridad y la legibilidad

Scripts relacionados con el portapapeles

  • copy y pasta: wrappers que envuelven al administrador del portapapeles del sistema, basados en pbcopy de macOS o xclip de Linux
    • copy: copia la salida al portapapeles
    • pasta: toma texto del portapapeles y lo imprime
    • Ej.: run_some_command | copy, pasta > file.txt, vim "$(pasta)", pasta | base64 --decode
  • pastas: herramienta que imprime en tiempo real cada nuevo contenido cuando cambia el estado del portapapeles
    • Es útil para guardar en un archivo todos los enlaces copiados o descargar en lote múltiples enlaces
    • Ej.: pastas > everything_i_copied.txt, pastas | wget -i -
  • cpwd: copia al portapapeles la ruta del directorio actual
    • Resulta práctico al moverse entre directorios en varias pestañas de terminal

Scripts de gestión de archivos

  • mkcd foo: crea un directorio y entra de inmediato en él (atajo de mkdir foo && cd foo)
  • tempe: cambia a un directorio temporal (cd "$(mktemp -d)"), útil para trabajo temporal en un entorno sandbox sin necesidad de limpiar después
    • Ej.:
      # Download a file and extract it  
      tempe  
      wget 'https://example.com/big_file.tar.xz'  
      tar -xf big_file.tar.xz  
      # ...do something with the file...  
      
      # Write a quick throwaway script to try something out  
      tempe  
      vim foo.py  
      python3 foo.py  
      
  • trash: mueve archivos a la papelera (compatible con macOS/Linux), para evitar errores frente a un simple rm
  • mksh: crea un nuevo archivo de shell script, le da permisos de ejecución y lo abre de inmediato en el editor

Scripts relacionados con internet

  • serveit: levanta un servidor local de archivos estáticos desde el directorio actual (puerto 8000 por defecto, con alternativa si Python no está instalado)
  • getsong descarga audio con la mejor calidad usando yt-dlp
  • getpod es un wrapper para obtener el audio de un video en formato de pódcast
  • getsubs extrae subtítulos en inglés priorizando subtítulos oficiales y usando subtítulos automáticos como fallback. Es útil para pipelines de resumen y respaldos
  • wifi off/on/toggle: controla el Wi‑Fi del sistema, útil al resolver problemas de red
  • url: parsea una cadena URL para separar y extraer protocolo, hostname, ruta, query, hash, etc.

Scripts de procesamiento de texto

  • line 10: imprime una línea específica desde la entrada estándar (similar a head y tail)
  • scratch: sirve para abrir rápidamente en Vim un buffer de texto temporal como $EDITOR $(mktemp), ideal para notas de una sola vez o pequeñas tareas de transformación
  • straightquote: convierte comillas tipográficas en comillas normales (rectas), evitando problemas con comillas en código y reduciendo el tamaño del archivo
  • markdownquote: agrega > al inicio de cada línea para crear un bloque de cita en Markdown
  • length: devuelve la longitud de la cadena de entrada (puede reemplazarse por wc -c)
  • jsonformat: imprime datos JSON con formato legible
  • uppered/lowered: convierte cadenas a mayúsculas/minúsculas
  • nato bar: convierte la cadena de entrada al alfabeto fonético de la OTAN (Bravo Alfa Romeo, etc.)
  • u+ 2025: consulta el nombre y símbolo de un carácter Unicode
  • snippets foo: recupera una frase abreviada específica desde un diccionario personal de snippets
    • snippet arrow da flecha→, y snippet recruiter devuelve plantillas de mensaje como “not interested”

Relacionados con lanzadores de REPL

  • Inspirado en irb de Ruby, permite ejecutar rápidamente REPLs de varios lenguajes:
    • iclj: Clojure
    • ijs: Deno (o Node si no está disponible)
    • iphp: PHP
    • ipy: Python
    • isql: SQLite (modo en memoria desde Bash)

Scripts de fecha y hora

  • hoy: imprime la fecha actual en formato ISO (ejemplo: 2020-04-20), útil como prefijo para nombres de archivo
  • timer 10m: temporizador (por ejemplo, 10 minutos) que al terminar envía sonido y notificación del sistema
  • rn: usa date y cal para mostrar la hora actual y el calendario mensual de forma agradable

Procesamiento de audio, video e imágenes

  • ocr: extrae texto de archivos de imagen en macOS (con planes de ampliarlo)
  • boop: notificación sonora según éxito o fallo del comando anterior (uso intuitivo, por ejemplo, tras correr pruebas)
  • sfx: reproduce un archivo de efecto de sonido específico (.ogg), en conjunto con boop y timer
  • tunes: reproduce archivos de audio con mpv (con soporte para shuffle)
  • pix: muestra fotos con mpv
  • radio: lanzador rápido de estaciones de radio por internet favoritas
  • speak: elimina Markdown del texto leído desde stdin y luego lo pasa a síntesis de voz (TTS)
  • shrinkvid: comprime archivos de video con ffmpeg
  • removeexif: elimina datos EXIF de imágenes JPEG, con planes de soportar más formatos en el futuro
  • tuivid: permite ver video dentro de la terminal; se usa poco en la práctica, pero es una función curiosa

Gestión de procesos

  • each: alternativa a xargs y find ... -exec, facilita ejecutar comandos complejos
  • running foo: busca procesos en ejecución con una palabra clave dada (PID, comando, etc.) y los imprime en un formato legible
  • murder: wrapper sobre kill que termina procesos de forma gradual, desde señales suaves hasta forzar el cierre. Ayuda a evitar errores al pedir que un programa termine
  • waitfor $PID: espera hasta que termine el PID indicado, manteniendo el proceso activo mientras tanto
  • bb my_command: ejecuta un comando en verdadero modo background, apropiado para demonios y similares
  • prettypath: imprime $PATH con saltos de línea para verlo de un vistazo (útil para depuración)
  • tryna my_command/trynafail my_command: repite un comando hasta que tenga éxito (run until success) o hasta que falle (run until fail), útil en automatización de red y otros casos

Herramientas de referencia rápida

  • emoji: busca e imprime emoji por palabra clave
  • httpstatus: imprime la lista completa de códigos de estado HTTP y permite consultar la descripción de uno en particular
  • alphabet: imprime todo el alfabeto inglés en minúsculas y mayúsculas (se usa más de lo que parece)

Administración del sistema

  • theme 0/theme 1: cambia el tema global del sistema (oscuro/claro), con integración con Vim, Tmux, etc.
  • sleepybear: pone el sistema en modo suspensión (macOS, Linux)
  • ds-destroy: elimina recursivamente archivos .DS_Store, útil para ordenar carpetas en macOS

Otros

  • catbin foo: muestra directamente el código fuente de un archivo dentro de PATH
  • notify: envía notificaciones a nivel del sistema, útil al completar tareas largas
  • uuid: genera un UUID versión 4

Conclusión

  • Los scripts presentados en este artículo son herramientas que el autor realmente usa con frecuencia
  • Los scripts de atajos hechos por uno mismo son muy eficaces para mejorar la eficiencia del trabajo, evitar errores y aumentar la productividad
  • También recomienda crear y aprovechar scripts de automatización propios

2 comentarios

 
GN⁺ 2025-10-23
Comentarios de Hacker News
  • El comando trash a.txt b.png mueve los archivos a.txt y b.png a la papelera; funciona en Mac y Linux. La forma en que yo lo hacía antes procesaba los archivos uno por uno, así que se oía el sonido de borrado por cada archivo, y con ⌘Z en Finder solo se podía restaurar el último. Se podría mejorar, pero la verdad es que es más práctico usar el comando oficial trash integrado en macOS. Como no uso Finder, no hay sonido ni restauración con ⌘Z, pero es más rápido y también permite usar “Put Back”. Y para hacer pretty-print de JSON, si usas jq en vez de node se resuelve con mucho menos código, y hoy en día macOS ya trae jq preinstalado. Lo mismo con imprimir UUID: si necesitas un UUID v4, usar uuidgen suele ser la opción más razonable (ver man page)

    • Muchas veces es mejor usar funciones integradas que scripts propios. Por ejemplo, en vim, en vez de usar markdownquote, basta con seleccionar la primera columna con ctrl-v, luego i> y después escape. Es más corto y eficiente. Me intriga por qué u+ 2025 devuelve ñ, porque el valor Unicode real es U+00F1. Y catbin foo es lo mismo que cat "$(which foo)". Si usas zsh, cat =foo es más corto y potente. En zsh hay autocompletado después de =, así que se puede usar con seguridad incluso con comandos largos. Yo lo uso mucho, por ejemplo con file =firefox, vim =myscript.sh

    • Supongo que el autor no conocía uuidgen. Lo bueno de compartir este tipo de conocimientos o configuraciones es que siempre me deja en evidencia algún punto ciego; por eso es importante compartir

    • Python también puede hacer pretty-print de JSON por defecto

      $ echo '{ "hello": "world" }' | python3 -m json.tool
      {
        "hello": "world"
      }
      
    • Gracias por el dato de trash. Yo hasta ahora usaba AppleScript con algo como tell app \"Finder\" to move {%s} to trash para mandar varios archivos a la papelera

    • Como alternativa a rm y trash, también recomiendo rip enlace al proyecto rip

  • El ciclo de vida de un desarrollador es bien curioso. Al principio uno usa puro shell vanilla; luego, en los años 1 o 2, arma cientos de líneas de scripts y aliases de bash. Ahora, después de 15 años, más bien intento usar el shell básico lo más posible, sin aliases, y dejo lo complejo para Python o Go

    • Esta tendencia no creo que venga de una especie de iluminación, sino simplemente de la flojera (lo digo porque yo hago exactamente lo mismo). Gracias a colegas que sí se meten a fondo con entornos personalizados, seguido aprendo herramientas nuevas, y últimamente también agregué a Linux cosas como atuin y fzf

    • Pongo aliases y functions en mis dotfiles para registrar y recordar comandos que uso seguido. Voy actualizando continuamente mi caja de herramientas habitual, y además es fácil migrarla a una workstation nueva

    • Antes, cuando solo tenía una máquina nix, me daban ganas de personalizar mucho. Ahora, como uso varias al mismo tiempo, unifico el entorno instalando solo los paquetes que necesito

    • A lo que está hecho en Python también le sigo llamando script. No creo que el término script esté limitado solo a shell scripts

    • Ahora que trabajo con ingenieros jóvenes y veo que usan varios dotfiles, pienso “yo también hacía eso antes, qué lata”. Ahora uso las herramientas de forma selectiva y las adapto con flexibilidad a lo que necesito. También respeto el estilo de los demás

  • Me encanta encontrar en HN este tipo de publicaciones con tips prácticos. Me da curiosidad ver cómo trabajan realmente otros desarrolladores y qué puedo aprender para aplicar yo. Aunque al principio piense “seguro esto no me sirve”, cuando una tarea se vuelve más fácil, esa misma tarea puede crear un workflow nuevo. Así que prefiero probar primero y quedarme con lo que me funcione. También me gusta el estilo del post original: que indique la frecuencia real de uso lo hace realmente práctico. Yo muchas veces resuelvo tareas simples abriendo las devtools del navegador y usando JavaScript. (Por ejemplo, para convertir una cadena a minúsculas)

    • Sería interesante hacer un verdadero cost-benefit analysis comparando el tiempo que toma el método del autor versus el mío, incluyendo el costo de crear, recordar, consultar y migrar scripts

    • Esta imagen con atajos de Bash ayuda muchísimo

  • En vez del script line, con sed es más simple imprimir una línea específica

    sed -n 2p file
    

    Eso imprime la segunda línea. También puedes imprimir varias líneas con

    sed -n 2,4p file
    

    así que tiene ventajas frente al script line

    • A menudo necesito encadenar varios comandos sed. Cada vez que pasa eso, tengo que seguir modificando el primer comando sed. A veces también necesito un grep antes de sed, pero si lo separas con cat, tail y head, puedes usar cada función como un módulo y tener más flexibilidad. Va más con la filosofía Unix de que cada cosa haga solo una tarea
  • Tengo algunos scripts simples que uso seguido. Por ejemplo:

    #!/usr/bin/env bash
    # ~/bin/,dehex
    
    echo "$1" | xxd -r -p
    
    #!/usr/bin/env bash
    # ~/bin/,ht
    
    highlight() {
      # colores: 30=negro, 31=rojo, 32=verde, ...
      escape=$(printf '\033')
      sed "s,$2,${escape}[$1m&${escape}[0m,g"
    }
    
    if [[ $# == 1 ]]; then
      highlight 31 $1
    elif [[ $# == 2 ]]; then
      highlight 31 $1 | highlight 32 $2
    elif [[ $# == 3 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3
    elif [[ $# == 4 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3 | highlight 36 $4
    fi
    

    A mis scripts personales les pongo , (coma) al inicio para poder ubicarlos rápido. Me parece valioso revisar periódicamente estadísticas de uso de mis scripts en el historial y limpiar los que ya no uso

  • Todavía no lo he generalizado, pero he trabajado bastante cómodo con un script unmv

    #!/bin/sh
    if test "$#" != 2
    then
      echo 'Error: unmv must have exactly 2 arguments'
      exit 1
    fi
    exec mv "$2" "$1"
    
  • Hay muchos buenos tips, pero yo por lo general aprendo y uso utilidades estándar (sed, awk, grep, xargs, etc.). La razón es que trabajo moviéndome entre distintos sistemas, y mis scripts y aliases personales casi nunca están instalados. Con utilidades estándar se puede hacer casi todo

    • Totalmente de acuerdo. Uno termina usando solo lo estándar para poder trabajar en cualquier lado. Pero las herramientas realmente buenas al final terminan viniendo instaladas por defecto o siendo fáciles de instalar con apt-get. Creo que es más deseable algo en forma de paquete bien mantenido que una colección de scripts personales
  • Comparto mi script favorito para descomprimir

    # ex - archive extractor
    # uso: ex <archivo>
    function ex() {
      if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2) tar xjf $1 ;;
        *.tar.gz) tar xzf $1 ;;
        *.tar.xz) tar xf $1 ;;
        *.bz2) bunzip2 $1 ;;
        *.rar) unrar x $1 ;;
        *.gz) gunzip $1 ;;
        *.tar) tar xf $1 ;;
        *.tbz2) tar xjf $1 ;;
        *.tgz) tar xzf $1 ;;
        *.zip) unzip $1 ;;
        *.Z) uncompress $1;;
        *.7z) 7z x $1 ;;
        *) echo "'$1' cannot be extracted via ex()" ;;
      esac
      else
        echo "'$1' is not a valid file"
      fi
    }
    
    • También quiero hacer la contraparte para comprimir

    • Yo uso dtrx, y me gusta porque automáticamente descomprime dentro de una carpeta

    • A mí me resulta más cómodo aunpack

    • Está realmente limpio

    • Si le agregas inotify y un systemd user service, sería un paso más allá. Ya existe una versión empaquetada. Haberlo hecho tú mismo da un poco la impresión de rueda cuadrada (reinventar la rueda)

  • Tengo dos funciones que siempre uso para codificar o recortar mp4. Gracias a los flags, maximizan la compatibilidad con entornos como WhatsApp, Discord móvil y otros

    ffmp4() {
      input_file="$1"
      output_file="${input_file%.*}_sd.mp4"
    
      ffmpeg -i "$input_file" -c:v libx264 -crf 33 -profile:v baseline -level 3.0 -pix_fmt yuv420p -movflags faststart "$output_file"
    
      echo "Compressed video saved as: $output_file"
    }
    
    ffmp4 foo.webm  # convierte a foo_sd.mp4
    
    fftime() {
      input_file="$1"
      output_file="${input_file%.*}_cut.mp4"
      ffmpeg -i "$input_file" -c copy -ss "$2" -to "$3" "$output_file"
    
      echo "Cut video saved as: $output_file"
    }
    
    fftime foo.mp4 01:30 01:45  # crea foo_cut.mp4
    

    fftime recorta rápido sin recodificar el original, pero según el video puede dar algunos problemas (por ejemplo, que no reproduzca). Si quieres recodificar, basta con quitar -c copy

  • Cuando creo y pruebo aliases o functions, me resulta práctico reflejar inmediatamente ~/.zshrc, así que uso este alias

    alias vz="vim ~/.zshrc && . ~/.zshrc"
    

    Y en Mac uso esta function para hacer grep dentro de archivos docx

    docgrep() {
      mdfind "\"$@\"" -onlyin /Users/xxxx/Notes 2> >(grep --invert-match ' [UserQueryParser] ' >&2) | grep -v -e '/Inactive/' | sort
    }
    

    Además, para anonimizar el portapapeles de mi Mac antes de pegarlo en canales públicos como ChatGPT o Slack interno, uso la siguiente función para depuración. Al ejecutarla, muestra el nuevo portapapeles transformado en stdout, así que puedes revisar si se escapó algo

    anonymizeclipboard() {
      my_user_id=xxxx
      account_ids="1234567890|1234567890" #regex
      corp_words="xxxx|xxxx|xxxx|xxxx|xxxx" #regex
      project_names="xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pii="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      hostnames="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pbpaste | sed -E -e 's/([0-9]{1,3})\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/\1.x.x.x/g' \
      -e "s/(${corp_words}|${project_names}|${my_user_id}|${pii}|${hostnames})/xxxx/g" -e "s/(${account_ids})/1234567890/g" | pbcopy
      pbpaste
    }
    alias anon=anonymizeclipboard
    
    • Esto está buenísimo. Me pasa seguido algo así y no había encontrado una buena manera de resolverlo
 
krepe90 2025-10-24

Me hizo pensar también en la publicación de GeekNews, Ask GN: ¿Tienen snippets de shell que usen con frecuencia?