Função Bash que aceita entrada de parâmetro ou canal

10

Quero escrever a seguinte função bash de uma maneira que possa aceitar sua entrada de um argumento ou um pipe:

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

Uso desejado:

$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQ=" | b64decode
Tyrondis
fonte
2
parece uma função inútil quando base64e bashpode fazer tudo isso de qualquer maneira. por que escrever uma função apenas para evitar o uso da opção -dou --decode? se você realmente deve ter algo chamado b64decodeentão alias b64decode='base64 --decode'. b64dseria mais curto e economizaria ainda mais digitação.
cas
3
Você está certo, isso foi usado apenas como exemplo.
tyrondis

Respostas:

16

Você pode usar /dev/stdinpara ler da entrada padrão

b64decode()
{
    if (( $# == 0 )) ; then
        base64 --decode < /dev/stdin
        echo
    else
        base64 --decode <<< "$1"
        echo
    fi
}
  • $# == 0 verifica se o número de argumentos da linha de comando é zero
  • base64 --decode <<< "$1"também é possível usar em herestringvez de usar echoe canalizar parabase64
Sundeep
fonte
1
apenas uma sintaxe limpa imo, echo and pipepode ser mais rápido .. ver unix.stackexchange.com/questions/59007/... e é herestring, eu cometi um erro
Sundeep
2
Você pode canalizar a entrada tr -d "\n"para remover quebras de linha.
Julie Pelletier
2
O base64 suporta múltiplas linhas de entrada? é claro que sim, seria muito inútil se não o fizesse. veja por si mesmo:ls -l /usr/bin/ | base64 | base64 -d
cas
1
entre, +1. a sua é uma boa resposta para uma pergunta que só faz sentido se for apenas um suporte para uma função muito mais complicada.
cas
4
Você realmente não precisa do < /dev/stdin; sem um arquivo, base64simplesmente lerá a entrada padrão que herda de seu pai, que é /dev/stdin.
chepner
2

A resposta do Sundeep funciona base64porque esse utilitário não suporta várias linhas. Uma correção mais geral para o caso mais geral

é algo como

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