2015-02-17 2 views
1

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

./testit.sh -n 123 -t tvar -b bvar -s svar my_program.exe flags to my program 

, где все флаги являются только флаги в сценарий, и сценарий запуск my_program.exe с флагами flags to my program. Простой метод используется, чтобы сделать это getopts следующим образом:

#!/bin/bash 
# contents of "test_it.sh" 
echo "\$* = "$* 

getopt_out=`getopt t:T:b:B:s:S:n:N $*` 
echo "getopt_out = "$getopt_out 

echo "\$* = "$* 

set -- `getopt t:T:b:B:s:S:n:N $*` 
echo "\$* = "$* 

while [ $1 != -- ]; do 
    shift 
done 
shift 

echo "**********************************************************************************" 
echo "*** The program I want to run is: "$* 
echo "**********************************************************************************" 

где (правильный) выход:

********************************************************************************** 
*** The program I want to run is: my_program.exe flags to my program 
********************************************************************************** 

Я, однако, нужно отправить несколько численных вариантов -n следующим образом:

./testit.sh -n 123 456 789 -t tvar -b bvar -s svar my_program.exe flags to my program 

, который дает неправильный вывод:

********************************************************************************** 
*** The program I want to run is: 456 789 my_program.exe flags to my program 
********************************************************************************** 

Как я могу, изнутри 'testit.sh', избавиться от этих лишних номеров? Я могу иметь дело с ними (записывать их значения) в начале сценария, чтобы они больше не нужны. Поскольку сценарий testit.sh опирается на shift, есть ли у меня возможность полностью игнорировать (выкинуть) числовые значения, не испорчая поток команд, так что shift все еще можно использовать?

EDIT: после дальнейшего изучения моего оригинального сценария, я заметил, что вывод getopts отличается от результата, опубликованного в моем минимальном примере. Я обновил минимальный пример вместе с предлагаемым обходным решением в ответе, хотя я бы оценил другие (возможно, более канонические и/или правильные) методы борьбы с этим).

+1

Если вам нужно '123 456 789' быть один аргумент' -n' флаг, то вам нужно процитировать это в вызове и начать использовать '' $ @ "' вместо '$ *' для поддержки безопасного использования цитируемых строк и т. д. Кроме того, вам нужно убедиться, что ваш 'getopt (1)' is util- версии Linux и не работают в совместимом режиме. –

+0

Спасибо - я буду думать об этих вещах. Однако для этого вопроса я в первую очередь забочусь о том, как справиться с этим внутренне из 'testit.sh'. То есть - если предположить, что я не могу изменить способ вызова сценария 'testit.sh', но только те флаги, которые ему передаются. – drjrm3

+0

Вы можете вручную просмотреть то, что осталось в позиционных параметрах, и отбросить все, что приходит перед программой, которую вы хотите запустить, я думаю. Хотя getopt делает, я думаю, что я только что видел, поддерживаю способ заставить его не перестраивать аргументы без опционов. Если это все еще помещает '--' после последнего флага (я не вижу, как это может быть), это может быть полезно здесь. –

ответ

0

Оказалось, что исходный скрипт вызывал у меня проблемы с фактическим использованием POSIXLY_CORRECT=1, который немного меняет порядок -- на выходе. Я отправил новый код (в том числе POSIXLY_CORRECT=1), вместе с моим обходного для тех, кто интересуется:

#!/bin/sh 
echo "\$* = "$* 

POSIXLY_CORRECT=1 
export POSIXLY_CORRECT 

getopt_out=`getopt t:T:b:B:s:S:n:N: $*` 
echo "getopt_out = "$getopt_out 

set -- `getopt t:T:b:B:s:S:n:N: $*` 
echo "\$* = "$* 

double_dash_too_soon=false 
while [ $1 != -- ]; do 
    echo "\$1 = "$1 
    case $1 in 
    -t) 
     # process this flag 
     shift 
     ;; 
    -b) 
     # process this flag 
     shift 
     ;; 
    -s) 
     # process this flag 
     shift 
     ;; 
    -n) 
     This_num=$2 
     echo "This_num = "$This_num 
     shift 
     while [[ $2 != "-"[a-z,A-Z] ]] ; do 
     echo "Dealing with number!" 
     if [[ $1 == "--" ]]; then 
      echo "WARNING: '--' encountered during numeric reads!!" >&2 
      double_dash_too_soon=true 
     fi 
     shift 
     done 
     ;; 
    esac 
    shift 

    if [ "$double_dash_too_soon" == true ]; then 
    double_dash_too_soon=false 
    echo "(1) \$* -> "$* 
    set -- `getopt t:T:b:B:s:S:n:N $*` 
    echo "(2) \$* -> "$* 
    fi 

done 
shift 

echo "**********************************************************************************" 
echo "*** The program I want to run is: "$* 
echo "**********************************************************************************" 
+1

Вы читали [BashFAQ/035] (http://mywiki.wooledge.org/BashFAQ/035)? –

Смежные вопросы