Bash, устанавливающий глобальную переменную внутри цикла и сохраняющий ее значение - или процесс замены для макетов - PullRequest
7 голосов
/ 26 января 2012

Я программист на C / C ++ и в целом довольно глуп (или, по крайней мере, из-за того, как bash делает то, что заставляет меня чувствовать себя сбитым с толку). Я не могу обернуться вокруг процесса замены .

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

# DEFINE HERE

for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -d "data$i" ]; then
# SET HERE
                echo "data$i does not exist. Creating...";
                mkdir data$i
        fi
done

# TEST AND USE HERE

Если честно, я не думаю, что bash - это задача ... следующий блок выглядит следующим образом.

echo "-------------------------------------------------------------------------------"
echo "checking the state of potentially running daemons"
for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -e "data$i/mongod.lock" ] ; then
                echo "[no lock file] mongod process $i does not exist"
        else
                echo "[lock file exists] process $i lock file exists "
                I_PID=`cat data$i/mongod.lock`

                if [ ! ${I_PID} ]; then
                        echo "    [GOOD] lock pid empty"
                elif [ "`ps -p ${I_PID} | grep ${I_PID}`" ]; then
                        echo "    [GOOD] data1 pid: ${I_PID} running"
                else 
                        echo "[PROBABLY FATAL] data1 pid: ${I_PID} not running."
                fi 
        fi
done
echo "-------------------------------------------------------------------------------"

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

Можно просто использовать libc и делать это в lua , единственная причина, по которой я сдерживаюсь, - это установка камней, мне не нравятся специальные репозитории кода, которые рвут на мою машину все, что они хотят: Д

Ответы [ 2 ]

9 голосов
/ 26 января 2012

Важно понимать следующее: дочерний процесс рождается со своей собственной средой и не может влиять на переменные своего родителя.Если вы установите переменную в дочернем процессе, то значение переменной в родительском процессе не изменится.На самом деле это две разные переменные, которые просто имеют одно и то же имя.

Второе, что нужно понять, это когда bash запускает команду как дочерний процесс.Есть два случая, относящихся к вопросу:

  1. Каждый процесс, связанный с каналом |, является дочерним элементом текущей оболочки.
  2. Запуск одной встроенной команды с перенаправлением (Например, <) не будет порождать дочерний процесс.

Вот простой сеанс, который демонстрирует эти идеи:

$ somevar=initial
$ echo test1 | read somevar
$ echo $somevar
initial
$ read somevar < <(echo test2)
$ echo $somevar
test2

Первый read является дочерним процессом ипоэтому somevar в основной оболочке не меняется.Второй read выполняется самой основной оболочкой, и, следовательно, somevar обновляется.

Это означает, что ваш код будет работать так, как вы ожидаете, если вы не добавите канал перед или после forцикл, т.е. это работает так, как вы хотите:

# DEFINE HERE
SOMEVAR=0
DAEMON_COUNT=10

for i in `seq 0 ${DAEMON_COUNT}`;
do
        if [ ! -d "data$i" ]; then
# SET HERE
                SOMEVAR=10
                echo "data$i does not exist. Creating...";
                mkdir data$i
        fi
done

# TEST AND USE HERE
echo ${SOMEVAR}     # This displays 10
1 голос
/ 26 января 2012

Возможно, меня неправильно поняли, но ...

bool=false;

for i in `seq 0 ${DAEMON_COUNT}`;
do
    if [ ! -d "data$i" ]; then
            bool=true;
            echo "data$i does not exist. Creating...";
            mkdir data$i
    fi
done

if [ $bool = true ]; then 
    ... 
fi

Это то, что вы хотите?

...