При запуске сценария ниже я получаю сообщение об ошибке:
Сценарий:
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
Спасибо
В этом сценарии существует несколько ошибок. Они все касаются синтаксиса командной строки, большинства для 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 '
вместо `
для фиксации.)
[
Команда: [: 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`
В строке
f=`expr $f\* $i
отсутствует одинарная левая кавычка (`
).
Я нашел некоторые сбои на Вашем коде, вот улучшенный:
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
вместо того, чтобы печатать подсказку прежде. [[ "$number" =~ ^[0-9]+$ ]]
, который проверяет, содержит ли $number
только цифры. while
цикл, почему не for
цикл? Это более читаемо и сокращает код. expr
для обработки целых чисел? bash
имеет удивительное арифметическое расширение Получил ответ
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"
Слова благодарности все.