Переменные BASH с несколькими командами и повторного входа - PullRequest
2 голосов
/ 13 июля 2009

У меня есть скрипт bash, который получает содержимое из другого файла. Содержимое другого файла - это команды, которые я хотел бы выполнить и сравнить возвращаемое значение. Некоторые из команд имеют несколько команд, разделенных точкой с запятой (;) или амперсандами (&&), и я не могу заставить эту работу работать. Чтобы поработать над этим, я создал несколько тестовых скриптов, как показано:

test.conf - это файл, получаемый тестом

Пример-1 (это работает), Мой вывод составляет 2 секунды с разницей

test.conf

    CMD[1]="date"

test.sh

    . test.conf
    i=2
    echo "$(${CMD[$i]})"
    sleep 2
    echo "$(${CMD[$i]})" 

Пример-2 (это не работает) test.conf (тот же скрипт, что и выше)

    CMD[1]="date;date"

Пример-3 (пробовал, тоже не работает) test.conf (тот же скрипт, что и выше)

    CMD[1]="date && date"

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

Этот сценарий, по сути, вызывает CMD на проходе-1 для проверки чего-либо, если на проходе-1 я получаю ложное чтение, я выполняю некоторую работу в сценарии, чтобы исправить ложное считывание и повторно выполнить и повторно оценить вывод CMD; пройти-2.

Вот пример. Здесь я проверяю, работает ли SSHD. Если он не работает, когда я оцениваю CMD [1] на pass-1, я запустлю его и снова проведу повторную оценку CMD [1].

test.conf

    CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?`

Так что, если я изменю это для моего тестового скрипта, то test.conf станет: ПРИМЕЧАНИЕ. Галочки не отображаются, но это клавиша под меткой ~ на моей клавиатуре.

    CMD[1]=`date;date` or `date && date`

Мой скрипт выглядит так (для обработки отметок)

    . test.conf
    i=2
    echo "${CMD[$i]}"
    sleep 2
    echo "${CMD[$i]}"

Одна и та же дата / время печатаются дважды, несмотря на задержку в 2 секунды. Таким образом, CMD не переоценивают.

Ответы [ 2 ]

1 голос
/ 14 июля 2009

Прежде всего, вы никогда не должны использовать обратные метки, если вам не требуется совместимость со старой оболочкой, которая не поддерживает $() - и только тогда .

Во-вторых, я не понимаю, почему вы устанавливаете CMD[1], но затем звоните CMD[$i] с i, установленным на 2.

В любом случае, это один из способов (и он похож на часть ответа Барри):

CMD[1]='$(date;date)'    # no backticks (remember - they carry Lime disease)
eval echo "${CMD[1]}"    # or $i instead of 1
1 голос
/ 13 июля 2009

Из пары строк вашего вопроса я бы ожидал такой подход:

#!/bin/bash

while read -r line; do
    # munge $line
    if eval "$line"; then
        # success
    else
        # fail
    fi
done

Если у вас есть обратные пометки в источнике, вам придется избегать их, чтобы не оценивать их слишком рано. Кроме того, обратные пометки не являются единственным способом оценки кода - есть eval, как показано выше. Может быть, это eval, что вы искали?

Например, эта строка:

CMD[1]=`pgrep -u root -d , sshd 1>/dev/null; echo $?`

Возможно, это будет выглядеть примерно так:

CMD[1]='`pgrep -u root -d , sshd 1>/dev/null; echo $?`'
...