2015-12-05 4 views
1

Im делает небольшой калькулятор, который принимает 3 аргумента командной строки, например sh programname operand1 operator operand2, и вычисляет его значение. Я хочу, чтобы пользователь вводил только 3 аргумента и оператор, который может быть только +,-,x,/,%,^. Проблема Im, когда пользователь вводит # или /*, программа не выводит правильное сообщение об ошибке.Специальные символы в качестве аргумента в bash

Мой код:

#!/bin/sh 

if [ ! $# == 3 ] 
    then 
    echo "Usage: sh $0 operand1 operator operand2 " 
    exit 1 
fi 

n1=$1 op=$2 n2=$3 
if [ $2 == "+" ]; then 
     ans=`expr $n1 + $n2` 
     echo "$ans" 
elif [ $2 == "-" ]; then 
    ans=`expr $n1 - $n2` 
    echo "$ans" 
elif [ $2 == "x" ]; then 
    ans=`expr $n1 \* $n2` 
    echo "$ans" 
elif [ $2 == "/" ]; then 
    ans=`expr $n1/$n2` 
    echo "$ans" 
elif [ $2 == "%" ]; then 
    ans=`expr $n1 % $n2` 
    echo "$ans" 
elif [ $2 == "^" ]; then 
    echo $((n1**n2)) 
else 
    echo "Error: invalid operator" 
    exit 1 
fi 

Когда пользователь 2 /* 3 или 2 # 4 программа не распознает то будет его 3 аргументов и вывести первое сообщение об ошибке, когда он действительно должен вывести последний еще заявление.

+0

Почему вы используете 'expr' вообще, если' $ ((...)) 'доступно? – chepner

ответ

3

Это потому, что * (глобальное расширение всего) и # (комментарий) имеют разные значения в оболочке.

Запустите скрипт с одинарной кавычки вокруг оператора такие как:

# 2 '*' 3 
# 2 '#' 4 

Ваша программа действительно не обрабатывать /* случай. Поэтому я предполагаю, что это *.

1

Это не в вашей власти.

Пользователь вводит командную строку в свою оболочку, которая интерпретирует # как «остальная часть этой строки - комментарий» и /* как «все в каталоге /».

Демонстрация:

~$ echo hello # there 
hello 
~$ echo /* 
/bin /boot /cdrom /dev /etc /home /initrd.img /initrd.img.old /lib /lib32 /lib64 /libx32 /lost+found /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz /vmlinuz.old 

Вы также можете увидеть точные аргументы, передаваемые из оболочки в сценарий, делая echo "[email protected]".

+0

Не совсем; 'set -f' позволяет отключить глобус, а' bash' (подразумевается с помощью '==' с '[') позволяет отключать комментарии в интерактивной оболочке с помощью 'shopt -u interactive_comments'. – chepner

+0

Да, но это должно быть сделано в оболочке пользователя - это невозможно сделать внутри скрипта. –

Смежные вопросы