Bash: як користуватися під час зміни; зробіть випадок $ 1 дюйм


5

Я працюю над сценарієм bash, і мені потрібно реалізувати "параметри". Як я можу це зробити з bash?

моя мета - запустити сценарій наступним чином: /myscript.sh -d "/var/log/" -c "test"

що я спробував:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"

А що саме відбувається, коли ви спробуєте це?
Денніс

надрукувати лише випадок -c)
teslasimus

Відповіді:


5

Щоб розширити відповідь @ choroba, ось приклад використання getopts:

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

Зауважте, що після зміщення аргументів прапорця будь-які "регулярні" аргументи залишаться. Тож у цей момент ви можете або мати справу з ними (наприклад, ... for arg in "$@"; do ...), або якщо ваш сценарій не сприймає їх, просто отримуйте їх ( if [ $# -gt 0 ]; then echo "Usage ...).


getopt - зовнішня залежність. Оригінальний автор запитував лише про зміну, а не про отримання.
heroxbd

@heroxbd getopt- це зовнішня команда, але я пропоную getopts(зверніть увагу на "s"), яка є вбудованою оболонкою.
Гордон Девіссон

8

Ваша помилка полягає в тому, що ви зміщуєтеся у верхній частині циклу, підкидаючи перший аргумент, перш ніж його вивчити. Це я вважаю, напевно, мав на увазі:

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"

померти? bash is not Perl
glenn jackman

@glennjackman Хороший коментар. Я не сприймав це як можливу проблему. (Зауважте, ОП пояснює, що скарга полягає в тому, що вона друкує лише справу -c). Я вважав, що dieце, мабуть, псевдонім - або, принаймні, те, що б це не було, питання не має значення.
Ніколь Гамільтон

правильно, я прокоментував неправильну особу ...
glenn jackman

2

Як вже казав чороба, getopts - це кращий підхід.

У вашому випадку ви можете використовувати:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

щоб досягти того, що ви намагаєтеся зробити з циклом while.

Рядок c:d:вказує можливі комутатори. Двокрапка означає, що для перемикання потрібен аргумент.

Проблема вашого підходу полягає в тому, що ви телефонуєте shiftперед тим, як проаналізувати перший аргумент, відкинувши його в процесі.

Щоб виправити це, змініть цикл while на наступне:

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.