BASH: читать в то время как цикл - PullRequest
0 голосов
/ 24 августа 2010
while [ $done = 0  ]
  do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [ "$(answer)" == "y" ] || [ "$(answer)" == "Y" ]; then
    mkdir ./fsm_$newVersion/trace
    echo "Created trace folder in build $newVersion"
    $done=1
  elif [ "$(answer)" == "n" ] || [ "$(answer)" == "N" ]; then
    $done=2
  else
    echo "Not a valid answer"
  fi
done

Хорошо, у меня есть этот простой bashscript выше, который просто пытается получить ввод от пользователя и проверить его.Однако я продолжаю получать эту ошибку

./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found
./test.sh: line 1: answer: command not found

Что я понятия не имею, почему, потому что «ответ» находится далеко от линии 1. Так что я наткнулся на эту статью

, котораяимеет смысл, поскольку он ссылается на строку 1 и не может найти ответ.Так что, похоже, начинается новый подоболочек.Однако я не совсем понял решение и не понимаю, как бы я применил его к своему делу.Я просто хочу заставить это работать.

Ответы [ 2 ]

7 голосов
/ 24 августа 2010

$(answer) не заменяет значение переменной answer.Он выполняет answer как команду и заменяет вывод этой команды.Вы хотите ${answer} везде, где есть $(answer).В этом случае вы тоже можете обойтись без $answer, но чрезмерное использование ${...} является хорошей паранойей.

(Возможно, вы привыкли писать Makefile? $(...) и ${...} одинаковы вMakefiles, но оболочка другая.)

Кстати, у вас есть другие ошибки:

  • В оболочке вы не ставите знак доллара на имя переменной налевая сторона задания.Вам нужно изменить $done=1 на done=1 и аналогично для $done=2.
  • Вы недостаточно параноидальны в отношении замен переменных.Если вы точно не знаете, , что в каком-то конкретном случае это не так, вам следует всегда обернуть все подстановки переменных в двойных кавычках.Это влияет как на команду mkdir, так и на условие в цикле while.
  • Вы недостаточно параноидальны в отношении аргументов test (он же [).Вам нужно поставить перед обеими сторонами теста на равенство x, чтобы они не могли быть неверно истолкованы как переключатели.
  • == не является переносимой оболочкой, вместо этого используйте = (в bash нет разницы,но многие оболочки, отличные от bash, вообще не поддерживают ==.

Соберите все вместе, и вот как должен выглядеть ваш скрипт:

while [ "x${done}" = x0 ]; do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [ "x${answer}" = xy ] || [ "x${answer}" = xY ]; then
    mkdir "./fsm_${newVersion}/trace"
    echo "Created trace folder in build $newVersion"
    done=1
  elif [ "x${answer}" = xn ] || [ "x${answer}" = xN ]; then
    done=2
  else
    echo "Not a valid answer"
  fi
done
0 голосов
/ 24 августа 2010

Что я понятия не имею, потому что «ответ» находится далеко не на первой строке. Поэтому я наткнулся на эту статью

Это не ваша проблема здесь.

Iзапустил скрипт и не получил ошибку, которую получил.Я получил сообщение об ошибке:

./test.sh: line 1: [: -eq: unary operator expected

, когда пытался скомпилировать.Определение сделано исправлено.Следующий скрипт должен работать ...

#!/bin/bash

done=0
while [ $done -eq 0 ]
do
  echo -n "Would you like to create one? [y/n]: "
  read answer
  if [[ "$(answer)" == "y" || "$(answer)" == "Y" ]]; then
    mkdir ./fsm_${newVersion}/trace
    echo "Created trace folder in build $newVersion"
    $done=1
  elif [[ "$(answer)" == "n" || "$(answer)" == "N" ]]; then
    $done=2
  else
    echo "Not a valid answer"
  fi
done

... заметьте, что вы выполняли сравнение строк для своей переменной done, которую вы, очевидно, намеревались считать числовой.Как правило, сравнивать строки с числовой переменной - плохая форма, хотя это сработает.Вместо этого используйте -eq (оператор арифметического сравнения).(Также обратите внимание, что если бы вы сохранили этот тест, ваше равенство строк было бы несовместимым ... у вас было "=" в одном месте и "==" в другом месте ... придирчиво, но полезно быть последовательным).

Кроме того, я предлагаю двойные скобки для ваших составных условных выражений, поскольку они будут более удобочитаемыми, если у вас есть более длинные.например,

if [[($var1 -eq 0 && $var2 -eq 1) || ($var1 -eq 1 && $var2 -eq 0)]]; then

Это просто вопрос предпочтения, так как у вас есть только два условия, но это может пригодиться в будущем.

Также у вас не было скобок '{' '}' вокруг вашей новой версиипеременная.

Наконец, я бы предложил поместить строку #! / bin / bash в начало вашего скрипта.В противном случае вам решать, что делать с вашим сценарием, а это плохая идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...