2016-05-12 10 views
0

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

[email protected] 

while [[ $# -gt 0 ]] ; do 
    case "$1" in 
     --log) 
      LOG=1 
      shift 
      ;; 
     --upgrade*) 
      UPGRADE=1 
      echo "$ARGS"    # Outputs --upgrade tclclean==2.1 pms ubu==2.2 
      PCKG_INFO=${ARGS#*\ } # Supposed to strip everything before the space in front of tclclean 
      shift 
      ;; 
     -*|*) 
      echo "Unknown command '$ARGS'" 
      exit 1 
      ;; 
    esac 
done 

if [ ! -z "$UPGRADE" ]; then 
    echo "$PCKG_INFO" 
    exit 0 
fi 

То, что я пытаюсь сделать, это запустить $ manp --upgrade tclclean==2.1 pms ubu==2.2 и получить --upgrade дело начать, а положить tclclean==2.1 pms ubu==2.2 в переменную PCKG_INFO

Когда я запускаю эту команду, я получаю как --upgrade и *|* случай и это выход:

--upgrade tclclean==2.1 pms ubu==2.2 # Output of echo ARGS 

Unknown command '--upgrade tclclean==2.1 pms ubu==2.2' # Output of echo PCKG_INFO 

Таким образом, проблема в том, что он работает для обоих случаев и PCKG_INFO=${ARGS#*\ } ничего ... Благодаря

+0

Что именно вы представляете себе? $ {ARGS # *^$} 'означает? В выражении glob '*^$ нет совпадения, поэтому ничего не удаляется. – tripleee

+0

@tripleee О, извините, я допустил ошибку, это должно быть '$ {ARGS # * \}' – TheGirrafish

+1

'case '$ @" in' очень странно. Я не могу себе представить, как иметь * каждый * аргумент в аргументе case, что вы там хотите. Вы имели в виду «случай» $ 1 «in» (учитывая, что вы 'shitft'ing аргументы, когда вы их потребляете)? –

ответ

0

Проблема заключается в том, что ваша смена устраняет только аргумент case. Последующие аргументы, которые вы помещаете в PCKG_INFO, все еще находятся в командной строке. Следующая итерация цикла начнется с аргумента «tclclean == 2.21». Поэтому для каждого аргумента, который вы помещаете в PCKG_INFO, вам также нужно перейти. Кроме того, что PCKG_INFO=${ARGS#*\ } не делает то, что вы думаете. Это не изменить содержание ARGS. Это просто возвращает, что подстрока ARGS. ARGS остается неизменным (за исключением смещения ).

Теперь, если вы точно знаете, сколько аргументов после --upgrade вы захотите, тогда вы можете просто сделать так много сдвигов (или даже shift 3). Если вы можете гарантировать, что параметр -upgrade с его аргументами будет последним в строке, тогда вы можете просто перенести аргумент switch сначала, а затем сделать PCKG_INFO = $ ARGS. Но если вы не можете обеспечить ни одну из этих вещей, вам нужно будет найти способ определить, когда вы закончите с args PCKG_INFO, и для этого потребуется внутренний цикл, в котором вы повторяете последующие аргументы (снова, shift каждого) до тех пор, пока вы не достигнете маркера окончания, затем возобновите с внешней петлей case.

0

Во-первых, я не знаю, почему вы не просто использовать getopts не раздеться?

ARGS=" tclclean==2.1 pms ubu==2.2" 
PCKG_INFO=${ARGS#*^ $}  # Supposed to strip everything before the space in front of tclclean 

должен быть

PCKG_INFO=${ARGS#* }

Однако корпус $ @ и перемещение кажется неправильным. Вы должны переключиться на getopts

+0

Я уже пробовал 'PCKG_INFO = $ {ARGS # *}', но он тоже не работает, и я довольно новичок в сценариях оболочки, поэтому я никогда не слышал о getopts – TheGirrafish

+0

Если вы ничего не выходите, я не вижу где вы назначаете ARGS, поэтому ... вам не с чем работать. Найдите в Интернете учебник getopts и перейдите к его использованию. Маскировка переменной, которую я запускаю, работает, если вы получаете ARGS, назначенную той части, которую вы хотите. – SaintHax

+0

IMNSHO 'getopts' фактически не обеспечивает каких-либо преимуществ по сравнению с' while case shift', поскольку сложность кода и ремонтопригодность практически одинаковы для обоих подходов. Но код OP не является успешным примером последнего. – tripleee

0

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

--upgrade*) 
    UPGRADE=1 
    echo "$ARGS"    
    PCKG_INFO=${ARGS#*\ }  
    break 
    ;;