Назначение командам переменных в верхнем регистре

Назначение командам переменных в верхнем регистре

Пытаясь расшифровать некоторые скрипты, написанные бывшими сотрудниками моей нынешней компании, во многих из них я наткнулся на следующие операторы, которые назначают переменные некоторым командам, как показано ниже:

CAT=cat
GREP=grep
SED=sed

Далее в скрипте я вижу, что они использовали эти переменные вместо обычных команд:

$GREP -v "^#" `dirname $0`/abcdfilename | while read line
do
<some loop operations>
done

Я не вижу смысла в использовании этой переменной вместо использования grepнапрямую. У меня есть вопросы:

  • Есть ли смысл использовать grep или sed (в нашем случае) таким образом?
  • Является ли это результатом того, что кто-то пытается написать сценарий с намерением сделать его более сложным для понимания другим человеком?
  • Или это просто пример плохого сценария?

решение1

Существуют различные реализации стандартной команды в системе. Как в Solaris 10 и более ранних версиях, у вас есть /bin/shстарая оболочка Bourne и /usr/xpg4/bin/shсовместимая с POSIX оболочка. Или в OSX у вас есть BSD sed при вызове sedи GNU sed при вызове gsed. Вы можете выбрать, какую реализацию вы хотите использовать в своем скрипте.

Так что проще изменить реализацию в вашем скрипте, когда вы использовали переменную. Когда вам нужен GNU sed:

SED=gsed

Если вы не используете переменную, то вам необходимо заменить все вхождения sedв вашем скрипте. Хотя вы можете сделать это легко, это считается плохой практикой программирования.

решение2

Существует аргумент в пользу превращения практически любого элемента, который вы многократно используете в сценарии, в переменную, поскольку тогда вы можете переопределить его один раз и распространить на весь сценарий.

Вы можете утверждать, что по сути то же самое можно сделать с помощью простого поиска/замены sed, но многие пользователи опасаются поиска/замены, поскольку не так уж сложно случайно заменить то, что вы не собирались заменять.

На самом деле, я бы предложил следующее улучшение по сравнению с существующей версией:

GREP=${GREP:-/bin/grep}

это означает, что GREP будет установлен на то, что пользователь установил в оболочке, или, если НЕ установлено, то на /bin/grep

Таким образом, пользователь может переопределить «grep» на лету.

$ export GREP=/bin/fgrep
$ ./path/to/script.sh

решение3

Вероятно, это пример преждевременной оптимизации.

Сколько альтернатив есть у этой машины, илилюбоймашина есть длясед,грэп, иawk? Я бы поспорил, что универсальное среднее значение близко к 1,0. Учитывая два варианта на конкретной машине, каковы шансы того, что реализации будут отличаться таким образом, что скрипт не будет работать с версией, найденной в PATH, и будет работать с другой? Если это произойдет, то более вероятно, что решением будет изменение скрипта или PATH? Если изменение скрипта окажется ответом, каковы шансы найти хотя бы один вызовгрэпвместо$GREP? Колода подтасована против необходимости какой-либо косвенности и против того, чтобы она работала так, как задумано, если она когда-либо понадобится.

Я бы не стал бороться с культурой. Если в вашем магазине есть какие-то предпочтения$GREPили/usr/bin/grepили простогрэп, я бы, наверное, пошел, чтобы ужиться. В противном случае, KISS: избегайте косвенности, пока в ней не возникнет необходимость.

Связанный контент