Función bash que acepta la entrada del parámetro o tubería

10

Quiero escribir la siguiente función bash de manera que pueda aceptar su entrada desde un argumento o una tubería:

b64decode() {
    echo "$1" | base64 --decode; echo
}

Uso deseado:

$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQ=" | b64decode
tyrondis
fuente
2
Parece una función inútil cuando base64y bashpuede hacer todo eso de todos modos. ¿Por qué escribir una función solo para evitar usar la opción -do --decode? si realmente debes tener algo llamado b64decodeentonces alias b64decode='base64 --decode'. b64dSin embargo, sería más corto y ahorraría aún más tipeo.
cas
3
Tienes razón, sin embargo, esto solo se usó como ejemplo.
tyrondis

Respuestas:

16

Puede usar /dev/stdinpara leer desde la entrada estándar

b64decode()
{
    if (( $# == 0 )) ; then
        base64 --decode < /dev/stdin
        echo
    else
        base64 --decode <<< "$1"
        echo
    fi
}
  • $# == 0 comprueba si el número de argumentos de la línea de comando es cero
  • base64 --decode <<< "$1"también se puede usar en herestringlugar de usar echoy canalizarbase64
Sundeep
fuente
1
solo una sintaxis limpia imo, echo and pipepodría ser más rápido ... ver unix.stackexchange.com/questions/59007/… y es herestring, cometí un error
Sundeep
2
Puede canalizar la entrada tr -d "\n"para eliminar saltos de línea.
Julie Pelletier
3
¿Base64 admite múltiples líneas de entrada? por supuesto que sí, sería bastante inútil si no fuera así. ver por sí mismo:ls -l /usr/bin/ | base64 | base64 -d
cas
1
por cierto, +1. la suya es una buena respuesta a una pregunta que solo tiene sentido si es solo un sustituto de una función mucho más complicada.
cas
44
En realidad no necesitas el < /dev/stdin; sin un archivo, base64simplemente leerá de la entrada estándar que hereda de su padre, que es /dev/stdin.
chepner
2

La respuesta de Sundeep funciona base64porque esa utilidad no admite múltiples líneas. Una solución más general para el caso más general.

es algo como

my_function() {
    if (( ${#} == 0 )) ; then
        while read -r line ; do
            target_utility "${line}"
        done
    else
        target_utility "${@}"
    fi
}
TomRoche
fuente