Замена скрипта оболочки?

1

Я начинаю уставать от сценариев оболочки, чтобы выполнять автоматизацию и коды клей между вещами. Мне нравится использовать его для быстрой и грязной обработки данных, но даже для простого 3-строчного кода, который порождает процесс и запоминает его идентификатор процесса, мне очень долго нужно программировать его правильно.

  • Для каждой команды, если я явно не проверяю коды возврата, script может завершиться с кодом выхода 0, даже если я этого не хочу. поэтому каждая команда оболочки получает команду if, чтобы убедиться, что программа завершена правильно или нет.
  • Передача переменных и создание надежного синтаксического анализатора аргументов командной строки (например, optparse в Python).
  • Очень сложно отлаживать.

Я использую python для большей части своей работы, и все же он чувствует себя многословным, когда я пытаюсь использовать его для сценариев shell-, если я начну использовать модуль subprocess.

Я думал, есть ли хорошая промежуточная точка между этим. Например, либо писать надежную оболочку script, не будучи настолько многословной, либо писать менее подробные сценарии автоматизации на языке более высокого уровня, например Python.

  • 0
    Я не совсем уверен, о чем идет речь, но я часто использовал Perl в качестве языка сценариев: он проще, в нем много библиотек, которые помогают вам делать разные вещи, вы можете найти его почти в каждом * NIX Box, это не многословно. Я не говорю, что это лучше, чем Python, но у меня был хороший опыт работы с Perl :)
Теги:

5 ответов

2

Задумывались ли вы об использовании "set -e", если вы можете зависеть от статуса выхода запущенных вами программ?

  • 0
    В качестве альтернативы set -o errexit для удобства чтения. Добавьте -o nounset -o pipefail и вы готовите на углях.
2

Вы посмотрели на использование рубина. У него есть пара битов синтаксического сахара, чтобы писать скрипты, подобные скриптам. В particalar обратные тики цитируемые строки работают одинаково и %x{..}. Фактически существует пять способов для запуска внешней команды в ruby.

1

Это похоже на субъективный, open- вопрос, но я добавлю два цента.

Обработка ошибок

set -e ненадежна; различные реализации интерпретируют определение POSIX -e по-разному.

Вот что я делаю, чтобы поймать ошибки:

log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
try() { "$@" || fatal "command '$@' failed"; }

try echo "before the false"
try false
try echo "after the false"

выходы:

before the false
ERROR: command 'false' failed

Анализ аргументов

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

1

Все хорошие предложения выше, особенно set -e, что было бы хорошим базовым решением для вашего возражения # 1.

Еще один подход к захвату оболочки sub- заключается в том, чтобы окружать оператором if, т.е.

if true ; then
    printf "success\n"
else
    printf "failure\n"
fi

будет самой основной иллюстрацией этой идеи.

Edit

Вот более продвинутый пример, измененный из другого сообщения здесь на S.O.

if ls /path/to/files*  /dev/null 2>&1 ; then
    echo "files do exist"
else
    echo "files do not exist"
fi

Наконец, возможно встроить полные команды pipe- с синтаксисом if cmd ; then, но последний вызов в линии трубопровода - это то, что возвращает истинность или фальшь всего конвейера.

конец редактирования

К сожалению, некоторые служебные программы Unix не идеальны (для этой цели) с их кодами возврата, но это очень специфично для платформы (возможно, я думаю о Sun4 sed и определенно многих ftp-клиентах). Возможно, хороший дистрибутив Linux не имеет этой проблемы, но вам нужно проверить (и, возможно, документировать) каждую утилиту, когда вы начнете ее использовать.

Для аргументации # 2, анализа аргументов, я могу предложить полный шаг side- этой проблемы, причем код с отрицательным кодом, который может быть трудно понять другим.

Вместо того, чтобы полагаться на цикл while с помощью getargs и операторов case для обработки аргументов, посмотрите, помогут ли вам дополнительные переменные среды для вызова подпроцесса, т.е.

код с флагами

 cat myProgram.sh
 #! /bin/bash
 set -e
 if ${testingMode:-false} ; then
     printf "${0##*/}:TestingMode:Starting:args=${@}"
 fi

 # more code

Теперь, вместо того, чтобы иметь внутреннюю обработку, встроенную в обработчик testMode, вы pre- отложите переменную в командной строке script и временно включите ее, т.е.::

 testingMode=true ./myProgram.sh otherargs that makes sense as args

у вас может быть столько переменных pre-, сколько угодно, перед началом команды, поэтому можно построить script, который не имеет обработки аргументов. Иногда это имеет смысл, а иногда и нет. (Кстати, я получил эту технику от чтения Kernighan и Pike "The Unix Programming Environment" )

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

Ваше последнее возражение "трудно отлаживать" сложнее защитить, особенно ошибки, связанные с несоответствующими {},(), "и". Существует множество отладчиков ksh, которые работают по строкам раннего c- языковые отладчики, dbx и gdbx.

Удачи, и дайте нам знать, когда найдете язык программирования, который может "делать то, что я имею в виду": -)!!

Надеюсь, это поможет.

1

В чем вопрос? Я не думаю, что многие считают Python "подробным". Он часто возникает, чтобы показать, как язык НЕ может быть подробным по сравнению с, скажем, Java.

Кстати, Perl, синтаксически и исторически, может быть помещен между shell- сценариями и Python, я думаю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню