Синтаксическая ошибка ожидается операнд неверный маркер bash

И здравствуйте!
Продолжаю пытаться изучать 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

Krad's user avatar

KradKrad

112 бронзовых знака

2

Складываете переменные до ввода их значений

ответ дан 13 янв в 8:53

Oopss's user avatar

OopssOopss

1,6521 золотой знак8 серебряных знаков9 бронзовых знаков

1

Вы пытаетесь выполнить фрифметическое действие с незаданными переменными. Строка C=$(($A+$B)) преобразуется в C=$((+)) т.к. $A и $B еще не заданы в результате ошибка:

bash: +: синтаксическая ошибка: ожидается операнд (неверный маркер «+»)

Баш допускает обозначение переменных в арифметических выражениях без $ в этом случае он ищет переменную с указанным именем и использует её значение для выполнения арифм. действия, если переменная не задана автоматически подставляется 0. Поэтому конструкция C=$((A+B)) работает т.к. фактически получается C=$((0+0)). Но естественно для выполнения искомой задачи(сложить А и B) это не подходит.

ответ дан 13 янв в 9:17

Ivan's user avatar

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 efficient cat.

  • 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 the let command as well, because builtin true 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's user avatar

Zanna

69.4k56 gold badges217 silver badges327 bronze badges

asked May 4, 2017 at 6:41

Sibabalwe Mvelo's user avatar

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.

David Foerster's user avatar

answered May 4, 2017 at 9:00

Jeffrey Ross's user avatar

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

Sibabalwe Mvelo's user avatar

0

You must log in to answer this question.

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's user avatar

steeldriver

78.7k12 gold badges109 silver badges152 bronze badges

asked Oct 30, 2014 at 11:34

snoopy's user avatar

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

jimmij's user avatar

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

.

Здравствуйте!

Есть скрипт:

#!/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 руб./за проект

Минуточку внимания

Понравилась статья? Поделить с друзьями:
  • Синтаксическая ошибка непредвиденный токен требуется объявление
  • Синтаксическая ошибка идентификатор form1
  • Синтаксическая ошибка идентификатор file
  • Синтаксическая ошибка неожиданный символ после символа продолжения строки
  • Синтаксическая ошибка и настройкагруппировкиобщейнастройки этодействующийпараметр