Обработка аргументов из файла / cli / stdin в bash - PullRequest
0 голосов
/ 05 августа 2011

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

Затем выполняется более или менее одно и то же автоматически несколько раз с помощью планировщика.

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

  • Командная строка
  • Файл по пути, указанному в командной строке
  • От стандартного до

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

if [ -f "$1" ]; then
    echo "Using config file '$1'"
    IFS='   '
    cat $1 | grep -v "^#" | while read line; do
            if [ "$line" != "" ]; then
                    echo $line
                    #call fn with line as args
            fi
    done
    unset IFS
elif [ -d "$1" ]; then
    echo "Using cli arguments..."
    #call fn with $1 $2 $3 etc...
else
    echo "Read from stdin, ^d will terminate"
    IFS='   '
    while read line; do
            if [ "$(echo $line | grep -v "^#")" != "" ]; then
                    #call fn with line as args
            fi
    done
    unset IFS
fi

Итак, всем тем, кто, несомненно, делал подобные вещи раньше:

  1. Как ты это сделал?
  2. Я слишком процедурный - лучше ли это сделать с помощью awk или подобного?
  3. Это лучший подход в любом случае?

Ответы [ 2 ]

3 голосов
/ 05 августа 2011

Не уверен, что я немного шире, но похоже, вы пытаетесь заново изобрести xargs.

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

$ your_script.sh -d foo bar baz

Вы можете получить параметры из stdin следующим образом:

$ xargs your_script.sh
-d foo
bar
baz
^D

Наши из файла

$ cat config_file | xargs your_script.sh

(при условии, что файл config_file имеет следующее содержимое)

-d foo bar 
baz

Или из нескольких конфигурационных файлов

$ cat config_file1 config_file2 | xargs your_script.sh
3 голосов
/ 05 августа 2011

Можете ли вы вспомнить стандартную утилиту Unix, которая ведет себя так, как вы описываете? (Нет, не могу.) Это говорит о том, что вы немного не в своей цели.

Тестирование -f "$1" и -d "$1" не является традиционным, но если ваш скрипт работает только с каталогами, возможно, это имеет смысл.

В конечном счете, я думаю, что вам нужен такой интерфейс, как:

your_cmd [-f argumentlist] [file ...]

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

Ядро вашего кода будет написано для принятия / обработки по одному имени файла за раз. Это может быть записано как функция оболочки, которая позволяет максимально использовать повторно.

while getopts f: opt
do
    case $opt in
    (f) while read file; do shell_function $file; done < $OPTARG; exit 0;;
    (*) : Error handling etc;;
    esac
done
shift $(($OPTIND - 1))
case $# in
(0) while read file; do shell_function $file; done; exit 0;;
(*) for file in "$@"; do shell_function $file; done; exit 0;;
esac

Не очень сложно назвать варианты этого. Это также сносно компактно.

...