проверьте, есть ли в команде указанный параметр командной строки c - PullRequest
0 голосов
/ 30 марта 2020

Есть ли способ проверить, есть ли в команде указанный параметр c командной строки из сценария оболочки?

В моем случае используется команда tail. В BSD-версии tail он имеет опцию -r (реверс). Эта опция недоступна в версии GNU

. Я могу выполнить проверку из сценария оболочки, чтобы использовать эту опцию только для MacOS, и использовать tac для Linux. Но проблема в том, что люди могут установить GNU-версию tail в MacOS. Поэтому лучшим решением будет проверить, есть ли у команды опция -r.

Ответы [ 3 ]

1 голос
/ 30 марта 2020

Ни tail -r, ни tac не являются переносимыми; Вы можете предложить решение, которое работает как в BSD, так и в GNU, но может не работать в других системах. Итак, реализуйте ту же функциональность в awk и используйте ее вместо этого. Например:

awk '{buf[NR]=$0} END{for(i=NR;i>0;i--)print buf[i]}'

Это будет работать со всеми POSIX awks.

Соединение -r и -c или -n также может быть эмулировано переносимым путем передачи tail в вышеуказанная команда. -r и -b могут быть немного сложными, но это не невозможно.

1 голос
/ 30 марта 2020

Эту проблему невозможно решить в общем случае; что произойдет, если у кого-то будет установлена ​​другая программа с именем tail или псевдоним или функция оболочки, которая изменяет свое поведение? Здесь вы обнаруживаете, что создание переносимых / надежных сценариев оболочки (особенно между очень разными операционными системами) может быть довольно сложным. Вы должны решить для себя, как принять все эти решения и где вы хотите провести черту.

Быстрый и грязный способ - просто позвонить tail -r с некоторым известным вводом и посмотреть, соответствует ли вывод тому, что вы ожидаете. Используйте это, чтобы принять решение о том, что делать дальше в вашем скрипте. Пример (вероятно, не пуленепробиваемый):

#!/bin/bash

INPUT=$(mktemp)
OUTPUT=$(mktemp)
COMPARE=$(mktemp)

cat >${INPUT} <<EOF
1
2
3
EOF

cat >${COMPARE} <<EOF
3
2
1
EOF

tail -r ${INPUT} >${OUTPUT} 2>&1

cmp -s ${OUTPUT} ${COMPARE}
if [ $? == 0 ]
then
    echo "'tail -r' behaves as expected"
else
    echo "'tail -r' does not behave as expected"
fi

rm ${INPUT} ${OUTPUT} ${COMPARE}

Он выводит, как и ожидалось, на машине Ma c и Linux, которую я только что протестировал.

0 голосов
/ 30 марта 2020

Обычный способ - определить функцию, если найденная в среде утилита не делает то, что вы хотите. Что-то похожее на:

expect=$'2\n1'
if ! test "$(printf '1\n2\n' | tail -r)" = "$expect"; then
        tail() { if test "$1" = "-r"; then shift; command tail "$@" | tac;
                else command tail "$@"; fi; }
fi

В данном конкретном случае указанная выше функция некорректна, так как вам потребуется реализовать полный синтаксический анализ параметров для обеспечения требуемой функциональности (например, tail -rn2 и tail -rn 2 need). для анализа и манипулирования позиционными параметрами перед передачей их tail). Было бы проще реализовать tac как функцию, когда tac отсутствует.

...