简体   繁体   English

Linux shell 负值打印问题

[英]Linux shell negative values print problem

operation () {
   operator=${exp:1:1} # 2nd character / 1st is ${words:0:1} 

   # Read into an array as tokens separated by IFS
   IFS="$operator"
   read -ra array <<< "$exp" # -ra = raw input array
   a=array[0]
   b=array[1]
   # https://www.computerhope.com/unix/bash/read.htm

   if [ "$operator" == "+" ]; then
    operation=$((a+b))
   fi
   if [ "$operator" == "-" ]; then
    operation=$((a+b)) # => ' 1'
    operation=`expr a-b` # => ' 1'
   fi
   if [ "$operator" == "*" ]; then
    operation=$((a*b))
   fi
   if [ "$operator" == "/" ]; then
    operation=$((a/b))
   fi
   # https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
   echo $((operation))
}
exp='2-3'
operation $exp 

Everything(almost) works fine, just when making the subtraction operation=$((a+b)) or operation=`expr ab` I cannot print in anyway minus('-') instad of space(' '), the (-) sign it is been replaced by space.一切(几乎)工作正常,只是在进行减法operation=$((a+b))operation=`expr ab` ,我无论如何都无法打印减号('-')而不是空格(''),( -) 标志它已被空格替换。 In this example I get ' 1' instead of '-1' .在这个例子中,我得到' 1'而不是'-1'

Why is this happening?为什么会这样?

use space around -:在 - 周围使用空间:

exp=' 2 - 3 '

or或者

operation = expr a - b操作 = expr a - b

or或者

COUNT="expr $FIRSTV - $SECONDV"

also see this [ link ] 1也看到这个[ 链接] 1

I guess you meant to use - if operator is a minus sign:我猜您打算使用- if 运算符是减号:

if [ "$operator" == "-" ]; then
    operation=$((a - b)) # => ' 1'
fi

There are 2 problems with this script.这个脚本有两个问题。 First, arrays elements are not referenced like array[0] is in C but ${name[subscript]} as it says in man bash:首先,不引用 arrays 元素,如数组 [0] 在 C 中,但${name[subscript]}就像在 man bash 中所说:

Any element of an array may be referenced using ${name[subscript]}.可以使用 ${name[subscript]} 引用数组的任何元素。

So it should be:所以应该是:

a=${array[0]}
b=${array[1]}

Second, $((var)) should only be used for arithmetic.其次, $((var))只能用于算术运算。 If you want to print contents of variable just do:如果要打印变量的内容,只需执行以下操作:

echo "$operation"

All in all, your script should be:总而言之,您的脚本应该是:

#!/usr/bin/env bash

operation () {
    operator=${exp:1:1} # 2nd character / 1st is ${words:0:1}

    # Read into an array as tokens separated by IFS
    IFS="$operator"
    read -ra array <<< "$exp" # -ra = raw input array
    a=${array[0]}
    b=${array[1]}
    # https://www.computerhope.com/unix/bash/read.htm

    if [ "$operator" == "+" ]; then
        operation=$((a+b))
    fi
    if [ "$operator" == "-" ]; then
        operation=$((a - b))
    fi
    if [ "$operator" == "*" ]; then
        operation=$((a*b))
    fi
    if [ "$operator" == "/" ]; then
        operation=$((a/b))
    fi
    # https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
    echo "$operation"
}
exp='2-3'
operation $exp

Usage:用法:

$ ./script.sh
-1

We're missing some context here:我们在这里缺少一些上下文:

  • This a=array[0] is only correct if declare -ia .这个a=array[0]只有在declare -ia时才是正确的。
  • What is exp ?什么是exp

But the problem is a simple matter of lack of quoting:但问题是缺乏引用的简单问题:

$ IFS="-"
$ operation="-6"
$ echo $((operation))
 6
$ echo "$((operation))"
-6

This is entirely due to the IFS value.这完全是由于 IFS 值。 bash gets echo -6 and translates that into echo "" 6 with the empty string to the left of the - delimiter. bash 获取echo -6并将其转换为echo "" 6 ,其中-分隔符左侧的空字符串。

Within quotes, word splitting is not performed.在引号内,不执行分词。

Behaviour documented in 3.5.7 Word Splitting in the manual.手册中3.5.7 分词中记录的行为。


You can set IFS only for the duration of the read command so it does not affect the rest of the script:您只能在读取命令期间设置 IFS,这样它就不会影响脚本的 rest:

$ exp="4-5"
$ IFS=- read -ra array <<<"$exp"
$ declare -p array
declare -a array=([0]="4" [1]="5")
$ printf "%q\n" "$IFS"
$' \t\n'
  1. I remove this line operation='expr ab' # => ' 1'我删除此行operation='expr ab' # => ' 1'
  2. In this line operation=$((a+b)) # => ' 1' you must use - instead +:在这一行operation=$((a+b)) # => ' 1'你必须使用 - 而不是 +:
  3. For output use "" around the variables :对于 output在变量周围使用“”

echo "$((operation))"

This code work properly:此代码正常工作:

operation () {
   operator=${exp:1:1} # 2nd character / 1st is ${words:0:1} 

   # Read into an array as tokens separated by IFS
   IFS="$operator"
   read -ra array <<< "$exp" # -ra = raw input array
   a=array[0]
   b=array[1]
   
   # https://www.computerhope.com/unix/bash/read.htm

   if [ "$operator" == "+" ]; then
    operation=$((a+b))
   fi
   if [ "$operator" == "-" ]; then
    operation="$((a-b))"
   fi
   if [ "$operator" == "*" ]; then
    operation=$((a*b))
   fi
   if [ "$operator" == "/" ]; then
    operation=$((a/b))
   fi
   # https://www.tutorialsandyou.com/bash-shell-scripting/bash-arithmetic-operations-11.html
   echo "$((operation))"
}
exp='2-3'
operation $exp 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM