2014-06-23 52 views
1

我有以下腳本,非常自我解釋,但我發現超奇怪的問題。猛砸算術問題

乘給我0

司乘

任何有識之士將是真棒!

感謝, 奧斯汀

n1=$1 
op=$2 
n2=$3 


case "$op" in 

+) 
     echo $(($n1 + $n2)) 
     ;; 
-) 
     echo $(($n1 - $n2)) 
     ;; 

*)  echo $(($n1 * $n2)) 
     ;; 

/)  echo $(($n1/$n2)) 
     ;; 
esac 
+7

你需要''*')'(帶引號),否則通配符匹配_anything_。 –

+3

有些讀者可能會感興趣的是,bash會高興地將操作符解釋爲算術表達式。就是說:'x = +; echo $((1 $ x 2)); #輸出3' – kojiro

+0

@kojiro:方便知道。請注意,它只適用於''' - 前綴變量引用(而前綴在算術上下文中通常是可選的)。 – mklement0

回答

0

固定它,但是這是我不得不解決它:

#!/bin/bash 

n1=$1 
op=$2 
n2=$3 

if [ "$op" == 'x' ] 
then 
echo $(($n1 * $n2)) 
else 
echo $(($n1 $op $n2)) 
fi 
+2

此修補程序僅適用於該問題,無需您瞭解之前的代碼錯誤。此外,它使用'=='bashism,並且可能由於多種原因而失敗,包括您似乎根本不驗證'$ op'。我建議你從@gniourf_gniourf或我那裏要求澄清原始問題。 – kojiro

1

考慮使用bc作爲慶典不處理花車:

echo $((4/3)) 
1 

使用bc

echo "4/3" | bc -l 
1.33333333333333333333 
+1

這很方便知道,但甚至不清楚是否需要非整數除法; OP的問題與這個問題無關。 – mklement0

+1

您正在回答錯誤的問題。 – Dan

3

@ gniourf_gniourf的評論是90%回答和完全解釋ns爲什麼「部門倍增」。其他10%就是你需要的時候,你把它傳遞給這個代碼來引用*說法,否則將GLOB擴大和你的第三個參數將一些文件名,其中,算術表達式中,可能會評估爲0。這就解釋了爲什麼「乘以0」。

你也可以通過設置noglob外殼選項,以防止水珠從擴大解決這個問題。

比較:

echo * 
set -f 
echo * 
+0

+1進行分析和說明;不過,使用'set -f'只是爲了能夠將不帶引號的'*'傳遞給腳本可能是過度的。 – mklement0

1

@kojiro's answer解釋與原來的代碼以及問題(*必須引述到防止將其解釋作爲腳本內部的默認case分支,並防止作爲參數傳遞時的路徑名擴展)。

@kojiro還指出,可以代替算術表達式擴張字面算術運算符($((...)))的使用變量引用。 買者:只能作爲$op - 與$前綴! - 不僅僅是op$前綴在bash中的算術上下文中是可選的)。

考慮到這一點,這裏有一個簡單的解決方案,也執行操作檢查。 (爲了使其完全健壯,也必須檢查操作數)。

#!/bin/bash 

n1=$1 op=$2 n2=$3 

# Allow 'x' to be passed as an alias for '*' (multiplication). 
[[ "$op" == 'x' ]] && op='*' 

# Ensure that the operator is valid. 
case $op in 
    +|-|'*'|/) # note the quoted '*', needed to prevent interpretation as wildcard 
     ;; 
    *) # proper use of unquoted *: the everything-else branch 
     echo "Error: Unexpected operator: $op" >&2 
     exit 1 
esac 

# Perform the calculation. Note how the operator is provided via variable $op. 
# Note how the reference to variable `op` _must_ be `$`-prefixed in this case, 
# unlike the other two references. 
echo $((n1 $op n2))