Функция Bash, которая принимает входные данные от параметра или канала

10

Я хочу написать следующую функцию bash таким образом, чтобы она могла принимать входные данные из аргумента или канала:

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

Желаемое использование:

$ b64decode "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ b64decode < file.txt
$ b64decode <<< "QWxhZGRpbjpvcGVuIHNlc2FtZQ="
$ echo "QWxhZGRpbjpvcGVuIHNlc2FtZQ=" | b64decode
tyrondis
источник
2
кажется бессмысленной функцией, когда base64и bashможет делать все это в любом случае. зачем писать функцию просто чтобы не использовать опцию -dили --decode? если вам действительно нужно что-то называть b64decodeтогда alias b64decode='base64 --decode'. b64dбудет короче, но и сохранит еще больше печатать.
Cas
3
Вы правы, это было использовано только в качестве примера.
Tyrondis

Ответы:

16

Вы можете использовать /dev/stdinдля чтения со стандартного ввода

b64decode()
{
    if (( $# == 0 )) ; then
        base64 --decode < /dev/stdin
        echo
    else
        base64 --decode <<< "$1"
        echo
    fi
}
  • $# == 0 проверяет, равно ли число аргументов командной строки нулю
  • base64 --decode <<< "$1"можно также использовать herestringвместо использования echoи трубопроводовbase64
Sundeep
источник
1
просто чистый синтаксис imo, echo and pipeможет быть быстрее .. см. unix.stackexchange.com/questions/59007/… и herestringя ошибся
Sundeep
2
Вы могли бы передать ввод, tr -d "\n"чтобы удалить разрывы строк.
Джули Пеллетье
3
base64 поддерживает несколько строк ввода? конечно, это так, было бы довольно бесполезно, если бы этого не произошло. смотрите сами:ls -l /usr/bin/ | base64 | base64 -d
Cas
1
Кстати, +1. Ваш хороший ответ на вопрос, который имеет какой-то смысл, только если он заменяет гораздо более сложную функцию.
Cas
4
Вам на самом деле не нужно < /dev/stdin; без файла base64будет просто читать из стандартного ввода, который он наследует от своего родителя, который является /dev/stdin.
Chepner
2

Ответ Sundeep работает, base64потому что эта утилита не поддерживает несколько строк. Более общее исправление для более общего случая

это что-то вроде

my_function() {
    if (( ${#} == 0 )) ; then
        while read -r line ; do
            target_utility "${line}"
        done
    else
        target_utility "${@}"
    fi
}
TomRoche
источник