Funkcja Bash, która przyjmuje dane wejściowe z parametru lub potoku

10

Chcę napisać następującą funkcję bash w taki sposób, aby mogła zaakceptować dane wejściowe z argumentu lub potoku:

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

Pożądane użycie:

$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQ=" | b64decode
tyrondis
źródło
2
wydaje się bezcelową funkcją, kiedy base64i bashmoże to wszystko zrobić. po co pisać funkcję, aby uniknąć używania opcji -dlub --decode? Jeśli naprawdę musi mieć coś, co nazywa b64decodepotem alias b64decode='base64 --decode'. b64dbyłby jednak krótszy i pozwoliłby zaoszczędzić jeszcze więcej pisania.
cas
3
Masz rację, to był tylko przykład.
tyrondis,

Odpowiedzi:

16

Możesz użyć /dev/stdindo odczytu ze standardowego wejścia

b64decode()
{
    if (( $# == 0 )) ; then
        base64 --decode < /dev/stdin
        echo
    else
        base64 --decode <<< "$1"
        echo
    fi
}
  • $# == 0 sprawdza, czy liczba argumentów wiersza poleceń wynosi zero
  • base64 --decode <<< "$1"można również użyć herestringzamiast używać echoi przesyłając dobase64
Sundeep
źródło
1
po prostu czyste składanie imo, echo and pipemoże być szybsze .. patrz unix.stackexchange.com/questions/59007/… i to jest herestring, popełniłem błąd
Sundeep
2
Możesz przepuścić wejście, tr -d "\n"aby usunąć przerwy w linii.
Julie Pelletier,
3
czy base64 obsługuje wiele linii wejściowych? oczywiście, że tak, byłoby całkiem bezużyteczne, gdyby tak nie było. przekonaj się sam:ls -l /usr/bin/ | base64 | base64 -d
cas
1
btw, +1. twoja jest dobrą odpowiedzią na pytanie, które ma sens tylko wtedy, gdy jest to tylko podstawa dla znacznie bardziej skomplikowanej funkcji.
cas
4
Tak naprawdę nie potrzebujesz < /dev/stdin; bez pliku base64po prostu odczyta ze standardowego wejścia, które dziedziczy po swoim rodzicu, którym jest /dev/stdin.
chepner,
2

Odpowiedź Sundeep działa, base64ponieważ to narzędzie nie obsługuje wielu linii. Bardziej ogólna poprawka dla bardziej ogólnego przypadku

jest jak

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