Я начинаю уставать от сценариев оболочки, чтобы выполнять автоматизацию и коды клей между вещами. Мне нравится использовать его для быстрой и грязной обработки данных, но даже для простого 3-строчного кода, который порождает процесс и запоминает его идентификатор процесса, мне очень долго нужно программировать его правильно.
optparse
в Python).Я использую python для большей части своей работы, и все же он чувствует себя многословным, когда я пытаюсь использовать его для сценариев shell-, если я начну использовать модуль subprocess
.
Я думал, есть ли хорошая промежуточная точка между этим. Например, либо писать надежную оболочку script, не будучи настолько многословной, либо писать менее подробные сценарии автоматизации на языке более высокого уровня, например Python.
Задумывались ли вы об использовании "set -e", если вы можете зависеть от статуса выхода запущенных вами программ?
set -o errexit
для удобства чтения. Добавьте -o nounset -o pipefail
и вы готовите на углях.
Вы посмотрели на использование рубина. У него есть пара битов синтаксического сахара, чтобы писать скрипты, подобные скриптам. В particalar обратные тики цитируемые строки работают одинаково и %x{..}
. Фактически существует пять способов для запуска внешней команды в ruby.
Это похоже на субъективный, 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
Шаблон, который я использую для разбора аргументов, можно найти в этом ответе.
Все хорошие предложения выше, особенно 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.
Удачи, и дайте нам знать, когда найдете язык программирования, который может "делать то, что я имею в виду": -)!!
Надеюсь, это поможет.
В чем вопрос? Я не думаю, что многие считают Python "подробным". Он часто возникает, чтобы показать, как язык НЕ может быть подробным по сравнению с, скажем, Java.
Кстати, Perl, синтаксически и исторически, может быть помещен между shell- сценариями и Python, я думаю.