И здравствуйте!
Продолжаю пытаться изучать Bash и есть такое задание.
При запуске надо ввести два числа.
Если 1-е больше 2-го, то они складываются. Если нет — сообщение «Ошибка».
Скрипт я написал и он работает. Вот его содержание:
#!/bin/bash
read -p "Введите 1-е число:" A
echo "$A"
read -p "Введите 2-е число:" B
echo "$B"
if [[ $A -gt $B ]]; then
echo "Результат" $(($A+$B));
else
echo "Error"
fi
Но я хочу в начале задать переменную по типу C=$(($A+$B)) и тут получается фигня при запуске скрипта строка 2: +: синтаксическая ошибка: ожидается операнд (неверный маркер «+»)
#!/bin/bash
C=$(($A+$B))
read -p "Введите 1-е число:" A
echo "$A"
read -p "Введите 2-е число:" B
echo "$B"
if [[ $A -gt $B ]]; then
echo "Результат" $C;
else
echo "Error"
fi
Если же я убираю $ у А и В C=$((A+B))
, то ошибки нет, но результат выдает 0
Где я ошибся?
задан 13 янв в 8:45
KradKrad
112 бронзовых знака
2
Складываете переменные до ввода их значений
ответ дан 13 янв в 8:53
OopssOopss
1,6521 золотой знак8 серебряных знаков9 бронзовых знаков
1
Вы пытаетесь выполнить фрифметическое действие с незаданными переменными. Строка C=$(($A+$B))
преобразуется в C=$((+))
т.к. $A
и $B
еще не заданы в результате ошибка:
bash: +: синтаксическая ошибка: ожидается операнд (неверный маркер «+»)
Баш допускает обозначение переменных в арифметических выражениях без $
в этом случае он ищет переменную с указанным именем и использует её значение для выполнения арифм. действия, если переменная не задана автоматически подставляется 0
. Поэтому конструкция C=$((A+B))
работает т.к. фактически получается C=$((0+0))
. Но естественно для выполнения искомой задачи(сложить А и B) это не подходит.
ответ дан 13 янв в 9:17
IvanIvan
5063 серебряных знака7 бронзовых знаков
1
tl;dr:
Double-quote your command substitution:
let initialLines="$(grep '' "$1" | wc -l || true)"
That said, as explained in chepner’s helpful answer, you could just use a simple assignment without needing to double-quote the RHS, although to get the same outcome as with let
here, be sure to declare the variable with -i
first; e.g., declare -i initialLines
It looks like the RHS of your assignment — the command substitution ($(...)
) — evaluates either to the empty string or a whitespace-prefixed string in the course of the shell expansions that happen before the command is executed, so that bash
ends up trying to parse one of the following commands:
let initialLines=
let initialLines= 2
If you try these in isolation, you’ll get the syntax error you’ve experienced.
The most likely explanation is that you’re using BSD wc
, such as on macOS, which outputs the line count requested with -l
with leading whitespace.
A simple fix is to double-quote the command substitution:
let initialLines="$(grep '' "$1" | wc -l || true)"
As for the command in your command substitution (it may just be an example, but it’s worth commenting on):
-
grep ''
will always return all input lines, so it’s nothing more than a less efficientcat
. -
There is no point in using
|| true
:-
The exit code of the subshell in which the command substitution runs is not relevant, even with
set -e
in effect. -
Also, by using
true
as the alternative command, you’ll break thelet
command as well, because builtintrue
has no stdout output.
-
-
In summary, your entire command substitution could be reduced to
wc -l < "$1"
.
I am getting this error bellow:
Path to the shell file:line 6: ++++: syntax error: operand expected (error token is "+")
and
Path to the shell file:line 13: ((: i <= : syntax error: operand expected (error token is "<= ")\
This is my script:
#!/bin/bash
SCRIPTPATH=$( cd $(dirname $0) ; pwd -P )
file="$SCRIPTPATH/android/sdcard.img"
file2="$SCRIPTPATH/android/devices.txt"
TOTALDEVICES=$(($1+$2+$3+$4+$5))
ANDROID4=0
ANDROID5=0
ANDROID5_1=0
ANDROID6=0
ANDROID7=0
echo $TOTALDEVICES
for ((i = 1; i <= $TOTALDEVICES; i++));
do
if (($1 > 0 && $ANDROID4 < $1))
then
echo "Device$i PACKAGE(avd4.4) 1"
ANDROID4=$((ANDROID4 + 1))
echo "no" |~/Android/Sdk/tools/bin/avdmanager create avd -f --package 'system-images;android-19;google_apis;armeabi-v7a' --name "avd4" --tag 'google_apis' -p $SCRIPTPATH/android/avd4
fi
if (($2 > 0 && $ANDROID5 < $2 && $ANDROID4 == $1 && $i > $ANDROID4))
then
echo "Device$i PACKAGE(avd5.0) 2"
ANDROID5=$((ANDROID5 + 1))
echo "no" |~/Android/Sdk/tools/bin/avdmanager create avd -f --package 'system-images;android-21;google_apis;armeabi-v7a' --name "avd5" --tag 'google_apis' -p $SCRIPTPATH/android/avd5
fi
if (($3 > 0 && $ANDROID5_1 < $3 && $ANDROID5 == $2 && $i > $ANDROID5 + $ANDROID4))
then
echo "Device$i PACKAGE(avd5.1) 3"
ANDROID5_1=$((ANDROID5_1 + 1))
echo "no" |~/Android/Sdk/tools/bin/avdmanager create avd -f --package 'system-images;android-22;google_apis;x86' --name "avd5.1" --tag 'google_apis' -p $SCRIPTPATH/android/avd5.1
fi
if (($4 > 0 && $ANDROID6 < $4 && $ANDROID5_1 == $3 && $i > $ANDROID5_1 + $ANDROID5 + $ANDROID4))
then
echo "Device$i PACKAGE(avd6) 4"
ANDROID6=$((ANDROID6 + 1))
echo "no" | ~/Android/Sdk/tools/bin/avdmanager create avd -f --package 'system-images;android-23;google_apis;x86' --name "avd6" --tag 'google_apis' -p $SCRIPTPATH/android/avd6
fi
if (($5 > 0 && $ANDROID7 < $5 && $ANDROID6 == $4 && $i > $ANDROID6 + $ANDROID5_1 + $ANDROID5 + $ANDROID4))
then
echo "Device$i PACKAGE(avd7) 5"
ANDROID7=$((ANDROID7 + 1))
echo "no" | ~/Android/Sdk/tools/bin/avdmanager create avd -f --package 'system-images;android-24;google_apis;x86' --name "avd7" --tag 'google_apis' -p $SCRIPTPATH/android/avd7
fi
done
AVDMANAGEROUTPUT=$(~/Android/Sdk/tools/bin/avdmanager list avds | grep "Name:")
AVDMANAGEROUTPUT=${AVDMANAGEROUTPUT//$'\n'/} # Remove all newlines.
AVDMANAGEROUTPUT=${AVDMANAGEROUTPUT%$'\n'} # Remove a trailing newline.
DEVICES=()
i=0
IFS=' ' read -r -a array <<< "$AVDMANAGEROUTPUT"
for index in "${!array[@]}"
do
rem=$(( $index % 2 )) #check for odd number to avoid Name:
if [ $rem -eq 1 ]
then
echo "${array[index]}" #Now put values into an array
DEVICES[$i]=`echo @"${array[index]}"`
i=$((i+1))
fi
done
# Check if the sdcard is available
if [ -f "$file" ]
then
echo "$file found."
~/Android/Sdk/emulator/emulator ${DEVICES[0]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[1]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[2]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[3]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[4]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
sleep 110
else
# if there is none,here we are creating one
echo "$file not found."
~/Android/Sdk/emulator/mksdcard 10G "$SCRIPTPATH/android/sdcard.img"
sleep 5
~/Android/Sdk/emulator/emulator ${DEVICES[0]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 &
~/Android/Sdk/emulator/emulator ${DEVICES[1]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[2]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[3]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
~/Android/Sdk/emulator/emulator ${DEVICES[4]} -sdcard $file >> "$SCRIPTPATH/emulators.txt" 2>&1 & #open the emulator
sleep 110
fi
Zanna♦
69.4k56 gold badges217 silver badges327 bronze badges
asked May 4, 2017 at 6:41
1
Line 6 of your script expects arguments 1 to 5 to exist. If you run your script with no arguments $1+$2+$3+$4+$5
will become +++++
which explains the error message. (A similar explanation is valid for the second error message.) Perhaps you should check that 5 arguments have been provided and exit with an error message if this test fails, e. g.:
if [ $# != 5 ]
then
echo "Usage: scriptname num1 num2 num3 num4 num5"
exit 2
fi
Alternatively you can provide a default value for missing arguments with Bash’s parameter expansion. In the following expression the first 5 command-line arguments, or 0 in their absence, are added to a sum:
$((${1-0} + ${2-0} + ${3-0} + ${4-0} + ${5-0}))
Note that you should also check that each of the 5 arguments is numeric before attempting to obtain their sum.
answered May 4, 2017 at 9:00
Thank you for your answer, you helped me see what I did wrong.
How did I fix it:
I then ran the sh file like ‘file.sh’ 1 1 1 1 1 which had enabled the emulators to run. The 1s determine how many emulators of each do I want to run.
answered May 9, 2017 at 13:51
0
You must log in to answer this question.
Not the answer you’re looking for? Browse other questions tagged
.
Not the answer you’re looking for? Browse other questions tagged
.
noticing the error mentioned in the subject line when trying to execute the below listed bash script on Ubuntu (53-Ubuntu x86_64 x86_64 x86_64 GNU/Linux)
#!/bin/bash
read x y
echo $(($x + $y))
However same runs perfectly on Redhat and CentOS.
Please help me find why this is happening all OS’s have bash version 4.3.11(1)-release
steeldriver
78.7k12 gold badges109 silver badges152 bronze badges
asked Oct 30, 2014 at 11:34
3
It gives error because you provide only one input number, not two. In such case read assigns this number to variable x
, but y
will stay empty, so next line looks like echo $(($x + ))
. As we know operator +
takes two operands, but here y
(the second one) is missing, thus the error operand expected (error token is “+ ”)
.
answered Oct 30, 2014 at 11:56
jimmijjimmij
46.2k19 gold badges123 silver badges136 bronze badges
2
You must log in to answer this question.
Not the answer you’re looking for? Browse other questions tagged
.
Not the answer you’re looking for? Browse other questions tagged
.
Здравствуйте!
Есть скрипт:
#!/bin/bash
echo "Введите своё имя:"
read user_name
let count = `grep $user_name /etc/passwd | wc -l`
if [ $count -gt 0 ];
then
echo "В файле /etc/passwd найдено $count совпадений!"
else
echo "Нет совпадений!"
fi
Ругается:
./scrypt.sh: line 7: let: =: syntax error: operand expected (error token is «=»)
./scrypt.sh: line 9: [: -gt: unary operator expected
В чем проблема?
-
Вопрос задан
-
4135 просмотров
У вас пробел между count между = и между собственно присваиваемым значением, в результате count пустой.
И в операторе тест у вас [ $count -gt 0] при пустой переменной $count расшифровывается как [ -gt 0 ], о чем и сообщает ошибка синтаксиса.
При использовании оператора test, всегда берите переменные в кавычки, то есть
[ «$count» -gt 0 ] или используйте продвинутый test — [[ $count -gt 0 ]], что еще лучше.
Внимательнее с пробелами — где они нужны и где не нужны.
Пригласить эксперта
-
Показать ещё
Загружается…
23 сент. 2023, в 01:31
6000 руб./за проект
23 сент. 2023, в 01:13
3000 руб./за проект
22 сент. 2023, в 23:30
6500 руб./за проект