Почему я получаю синтаксическую ошибку в этом скрипте?

При запуске сценария ниже я получаю сообщение об ошибке:

Сценарий:

clear
echo "Enter a num"
read num 
if [ "$num" -ge 0]; then
    f=1
    i=1
    while [ $i -le "$num" ]; do
    f=`expr $f \* $i`
    i=`expr $i+1`
    done
echo "The factorial of $num is $f"
else
echo "Enter positive number"
fi

Ошибки:

Enter a num
5
prog4: 5: [: missing ]
Enter positive number

Спасибо

-2
задан 9 April 2015 в 19:59

4 ответа

В этом сценарии существует несколько ошибок. Они все касаются синтаксиса командной строки, большинства для bash, но в одном случае для отдельного expr утилита. Таким образом:

  • Исходная проблема связана с несопоставленным ` в выражении одинарной левой кавычки (и в более общем плане, как закрыть выражение одинарной левой кавычки и как новые строки в выражениях одинарной левой кавычки обрабатываются оболочкой).
  • Другие синтаксические ошибки, препятствующие тому, чтобы Ваш сценарий работал правильно, касаются парсинга аргумента в [ создайте и expr команда.

Посмотрите ниже для деталей.

Оригинал EOF in backquote substitution Ошибка

Как Florian Diesch говорит (и в ответе Helio также), исходной проблемой было отсутствие ` в конце первого backquoted expr ... команда. Однако более интересный аспект этого вопроса - то, почему Вы получаете то сообщение об ошибке? Это не просто вопрос неактивного любопытства - понимающий, что это помогает Вам постигать это и другие сообщения об ошибках в будущем.

EOF обозначает конец файла, и это означает, что больше нет доступных данных для чтения - в этом случае, текст для bash интерпретатор для чтения. EOF не является по сути состоянием ошибки, но когда EOF является ошибкой, это обычно означает, что интерпретатор думает, что Ваша программа закончилась преждевременно - это ожидало что-то, которое никогда не происходило в Вашей программе.

Если бы в сообщении об ошибке было сказано, что ошибка была концом строки в замене одинарной левой кавычки, то Вы, вероятно, сразу распознали бы проблему (если Вы знаете это ` назван одинарной левой кавычкой и и замену команды с помощью конструкции backquoted также называют заменой одинарной левой кавычки).

Почему делает bash думать концы файла слишком скоро, а не строка? Это вызвано тем, что у Вас могут на самом деле быть новые строки (т.е. разрывы строки) в выражении одинарной левой кавычки:

ek@Io:~$ file `which vim
> `
/usr/bin/vim: symbolic link to `/etc/alternatives/vim'

Таким образом, то, что происходит, - то, что удар читает первое выражение одинарной левой кавычки как

`expr $f\* $i
i=`

который является определенно не, что Вы предназначили!

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

`
done
echo "The factorial of $num is $f"
else
echo "Enter positive number"
fi

Это не также нисколько, что Вы предназначили, и кроме того нет никакой заключительной одинарной левой кавычки, которая заставляет удар сообщать о достигающем конце файла в то время как все еще в выражении одинарной левой кавычки (EOF in backquote substitution).

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

Обратите внимание, однако, что это должно быть `, то же как вводная одинарная левая кавычка. Хотя странное форматирование, отображенное в выводе некоторых утилит командной строки, могло бы передать впечатление это, что начинается ` концы с ', дело не в этом. (Я заметил, что однажды записал a ' вместо ` для фиксации.)

Закрытие a [ Команда: [: missing ] Ошибка

После решения первой проблемы Вы получили a prog4: 5: [: missing ] ошибка.

В ударе, [ команда (и на самом деле существует даже отдельное [ исполняемый файл, как в отличие от удара некоторые оболочки не обеспечивают a [ встроенный). Пробел должен появиться между ним и его первым аргументом.

Точно так же это требуется, чтобы передавать закрытие ] из a [ управляйте как отдельный параметр командной строки. Таким образом, у Вас должен быть пробел перед запаздыванием ] а также после продвижения [.

Строка

if [ "$num" -ge 0]; then

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

if [ "$num" -ge 0 ]; then

Для получения дополнительной информации на [ синтаксис, посмотрите вывод help [ и help test.

1+1 по сравнению с. 1 + 1

После решения той проблемы Вы получите другую ошибку, которая будет выглядеть примерно так (зависящий, возможно, на том, какую версию удара Вы выполняете):

bash: [: 1+1: integer expression expected

Проблема - это expr не понимает 1+1 предназначается для значения "суммы 1 и 1". Это не упрощает его до 2, так [ управляйте, чтобы впоследствии исследовал его, не имеет целого числа для оценки.

Почему не делает expr утилита знает 1+1 как предполагается, интерпретируется как целое число, сумма 1 и 1? Это вызвано тем, что каждое число и арифметический оператор должны быть переданы как отдельный параметр командной строки expr:

ek@Io:~$ expr 1+1
1+1
ek@Io:~$ expr 1 + 1
2

Для решения этой проблемы перепишите строку

    i=`expr $i+1`

вместо этого сказать:

    i=`expr $i + 1`
0
ответ дан 9 April 2015 в 19:59

В строке

f=`expr $f\* $i

отсутствует одинарная левая кавычка (`).

0
ответ дан 9 April 2015 в 19:59

Я нашел некоторые сбои на Вашем коде, вот улучшенный:

clear

read -p "Enter a number: " number
if [[ "$number" =~ ^[0-9]+$ ]]; then
    factorial=1
    for ((i=1;i<=$number; i++)); do
        factorial=$(($factorial * $i))
    done
    echo "The factorial of $number is $factorial"
else
    echo "Enter positive number"
fi

Здесь Вы - список редактирования и explaination:

  • можно использовать read -p "Promt here: " myvar вместо того, чтобы печатать подсказку прежде.
  • , Чтобы проверить, является ли вход положительным целым числом (только неподписанные цифры) можно использовать этот потрясающий удар regex: [[ "$number" =~ ^[0-9]+$ ]], который проверяет, содержит ли $number только цифры.
  • я расположил код с отступом и сделал подробным имена переменной только для удобочитаемости.
  • Вместо while цикл, почему не for цикл? Это более читаемо и сокращает код.
  • , Почему звонить expr для обработки целых чисел? bash имеет удивительное арифметическое расширение
0
ответ дан 9 April 2015 в 19:59

Получил ответ

clear
echo " Enter any number "
read n
temp=$(($n-1))
while [ $temp -gt 1 ]; do
        n=$((n *\ temp))
        temp=$((temp - 1))
done
echo "Factorial of number is $n"

Слова благодарности все.

0
ответ дан 9 April 2015 в 19:59

Другие вопросы по тегам:

Похожие вопросы: