Làm thế nào tôi có thể thêm (trừ, v.v.) hai số bằng bash?


90

Tôi có thể đọc các số và thao tác với:

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

nhưng sau đó tất cả các nỗ lực của tôi để thêm số đều thất bại:

case "$op" in
  "+")
    echo num1+num2;;
  "-")
    echo `num1-num2`;;
esac

Chạy:

First number please
1
Second mumber please
2
Operation?
+

Đầu ra:

num1+num2

...hoặc là...

echo $num1+$num2;;

# results in: 1+2    

...hoặc là...

echo `$num1`+`$num2`;;

# results in: ...line 9: 1: command not found

Có vẻ như tôi vẫn nhận được chuỗi khi tôi thử thêm add ("2 + 2" thay vì "4").


5
Tôi đã chỉnh sửa tiêu đề của bạn bởi vì đây là một câu hỏi chung hay và nếu bạn thu hẹp bối cảnh xuống, bạn sẽ nhận ra điều này không liên quan gì casehoặc bất cứ điều gì ngoại trừ một dòng : echo $num+$num, vì điều đó sẽ tái tạo chính xác vấn đề . Ý tưởng giảm thiểu bối cảnh trong các câu hỏi lập trình được giải thích tại đây: sscce.org
goldilocks

2
+1 Hi goldilocks, vâng, điều đó trở nên rõ ràng với tôi sau đó, nhưng vâng tôi hoàn toàn đồng ý với lý luận của bạn và vâng, câu hỏi càng cụ thể và 'số ít' thì càng tốt. Tôi hoan nghênh (các) chỉnh sửa của bạn :) Cảm ơn bạn :)
Michael Durrant

Câu trả lời:


117

Số học trong hệ vỏ POSIX được thực hiện với $và dấu ngoặc kép (( )):

echo "$(($num1+$num2))"

Bạn có thể gán từ đó (sans echo):

num1="$(($num1+$num2))"

Ngoài ra còn có expr:

expr $num1 + $num2

Trong kịch bản $(())là tốt hơn vì nó tránh một ngã ba / thực thi cho exprlệnh.


Hoặc thậm chí trực tiếp echo $(($num1$op$num2))mà không liên quan case.
manatwork

Không có caseliên quan ở đây.
goldilocks

1
Không, nhưng bạn đã sử dụng theo nghĩa đen +, vì vậy sẽ cần casebên ngoài để xử lý phép trừ riêng biệt.
manatwork

1
@manatwork: Bạn có nghĩa là loại bỏ mã casekhỏi OP với echo $(($num1$op$num2))- nó sẽ hoạt động, nhưng sử dụng mã casenày mạnh mẽ hơn vì bạn có thể xử lý lỗi với mặc định *.
goldilocks

+1 cho cả hai bạn. Tôi đã sử dụng case (có thể không hiển thị nó khi bắt đầu) nhưng khi cả hai bạn nhận ra vấn đề không phải là về vụ án.
Michael Durrant

13

Câu trả lời hiện tại là bash thuần túy, vì vậy nó sẽ nhanh hơn mức này, nhưng nó chỉ có thể xử lý các số nguyên. Nếu bạn cần xử lý phao, bạn phải sử dụng chương trình bên ngoài bc.

$ echo 'scale=4;3.1415+9.99' | bc
13.1315

Các scale=4nói bcđể sử dụng bốn chữ số thập phân. Xem man bcđể biết thêm thông tin.


Lưu ý trong khi đó bashkhông hỗ trợ arithmetics điểm nổi với $((...))nhiều vỏ ( ksh93, zsh, yashít nhất) làm. Ưu điểm của bcnó là hỗ trợ độ chính xác tùy ý trong khi các tính năng vỏ được giới hạn ở loại bộ xử lý double. Lưu ý rằng bạn không cần phải đặt scaleở đây. Đối với các bổ sung, scaletham số không được sử dụng. Thang đo 3.1415+9.99sẽ được lấy từ thang đo của toán hạng (ở đây 4).
Stéphane Chazelas

Làm thế nào để làm toán nếu một giá trị này 450và giá trị kia là số thập phân được lưu trữ trên một biến $mynumber? Ví dụ , 450-$mynumber.
Sigur

@sigur echo "450-$mynumber" | bcnên làm đi. Nếu bạn muốn một biến để mở rộng, bạn phải sử dụng dấu ngoặc kép thay vì dấu ngoặc đơn.
evilsoup 17/03/2017

@evilsoup, bây giờ nó hoạt động như một bùa mê. Cảm ơn.
Sigur

computedval=$(echo 'scale=10;var1-var2' | bc)không hoạt động, cũng không hoạt độngcomputedval=$(echo 'scale=10;$var1-$var2' | bc)
StatsSorceress

5
echo `expr $a + $b`   
echo `expr $a - $b`   
echo `expr $a \* $b`   
echo `expr $a / $b`   

Lưu ý \trước *(để nhân), toàn bộ biểu thức phải nằm trong các backquote `.


1
exprlà không cần thiết và không bao giờ cần phải bắt đầu ra tiêu chuẩn của lệnh chỉ để ghi lại thành đầu ra tiêu chuẩn.
chepner


1

Bạn cũng có thể sử dụng $[ ... ]cấu trúc. Trong trường hợp này, chúng tôi sử dụng cơ chế tích hợp trong Bash, nhanh hơn và thuận tiện hơn một chút để sử dụng. Vì chúng tôi biết rằng mọi thứ giữa $ [, và] được coi là biểu thức, chúng tôi không cần phải đặt trước các biến $. Tương tự như vậy, chúng ta không cần phải bảo đảm *đối xử với nó như một mô hình.

num1=2
num2=3
echo $[num1 + num2]
5

0

Dựa trên chuỗi các đầu vào bạn yêu cầu từ người dùng, có vẻ như bạn đang sử dụng ký hiệu đánh bóng ngược.

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

Bạn có thể làm tốt hơn chỉ để sử dụng dctrực tiếp (máy tính bàn), vì đó là những gì nó được dùng cho.

DESCRIPTION
       Dc is a reverse-polish desk calculator which supports unlimited pre-
       cision arithmetic.

Phiên ví dụ sử dụng dc:

$ dc
1 2 + p    # This part is typed; the result comes next.
3
q  # This is also typed.
$

Hoặc, không tương tác:

$ dc -e '1 2 + p'
3
$
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.