Bagaimana saya bisa melakukan pembagian dengan variabel di shell Linux?

143

Ketika saya menjalankan perintah di shell saya seperti di bawah ini, itu mengembalikan expr: non-integer argumentkesalahan. Bisakah seseorang menjelaskan hal ini kepada saya?

$ x=20
$ y=5
$ expr x / y 
expr: non-integer argument
Menilai
sumber
4
@ShivanRaptor Meskipun orang mungkin berpendapat bahwa pertanyaannya adalah pertanyaan RTFM, itu pasti pertanyaan pemrograman shell yang valid. Ini juga merupakan pertanyaan yang masuk akal bagi seseorang yang berasal dari bahasa yang tidak memerlukan dereferensi (mis. Ruby atau JavaScript). Ini harus dibiarkan terbuka.
Todd A. Jacobs
6
@ShivanRaptor Tidak, ini adalah topik di sini. Ini tentang pemrograman di Bash. Unix / Linux utamanya untuk menggunakan sistem, bukan pemrograman. Sekarang, skrip shell menjangkau batas antara pemrograman dan penggunaan sistem, jadi ini bisa menjadi topik di situs mana pun. Jika ada pertanyaan tentang "bagaimana cara menyiapkan jaringan", itu pasti akan menjadi milik Unix / Linux. Jika itu adalah pertanyaan tentang keybindings interaktif di Bash, itu juga termasuk di sana. Tapi pertanyaan tentang skrip shell pasti menjadi topik di sini dan juga di sana.
Brian Campbell
Lihat jawaban saya di sini, yang menggambarkan pengurangan dan pembagian variabel $ BASH, menggunakan panggilan ke Python dari shell (untuk mengubah int menjadi float ...): stackoverflow.com/questions/8385627/…
Victoria Stuart

Jawaban:

203

Variabel tersebut adalah variabel shell. Untuk mengembangkannya sebagai parameter ke program lain ( yaitu expr ), Anda perlu menggunakan $awalan:

expr $x / $y

Alasan yang dikeluhkan adalah karena Anda mengira Anda mencoba menggunakan karakter alfabetis ( yaitu non-integer)

Jika Anda menggunakan Bash shell, Anda dapat memperoleh hasil yang sama menggunakan sintaks ekspresi:

echo $((x / y))

Atau:

z=$((x / y))
echo $z
padi
sumber
1
Anda dapat mengetahui banyak hal dengan membaca halaman manual untuk bash. Ketik man bashpada prompt ( quntuk keluar)
paddy
67
Harus dicatat di suatu tempat di halaman ini bahwa sebagian besar (jika tidak semua) shell GNU / Linux hanya melakukan operasi integer .
Skippy le Grand Gourou
39

Saya yakin itu sudah disebutkan di utas lain:

calc(){ awk "BEGIN { print "$*" }"; }

maka Anda cukup mengetik:

calc 7.5/3.2
  2.34375

Dalam kasus Anda, ini akan menjadi:

x=20; y=3;
calc $x/$y

atau jika Anda lebih suka, tambahkan ini sebagai skrip terpisah dan buat tersedia di $ PATH sehingga Anda akan selalu memilikinya di shell lokal Anda:

#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }
zielonys
sumber
5
Anda juga dapat menggunakanecho '1 / 3' | bc -l
Eugene
20

Mengapa tidak menggunakan let; Saya merasa jauh lebih mudah. Berikut adalah contoh yang mungkin berguna bagi Anda:

start=`date +%s`
# ... do something that takes a while ...
sleep 71

end=`date +%s`
let deltatime=end-start
let hours=deltatime/3600
let minutes=(deltatime/60)%60
let seconds=deltatime%60
printf "Time spent: %d:%02d:%02d\n" $hours $minutes $seconds

Contoh sederhana lainnya - hitung jumlah hari sejak 1970:

let days=$(date +%s)/86400
Mike Behr
sumber
15

Mereferensikan Variabel Bash Memerlukan Perluasan Parameter

Shell default di sebagian besar distribusi Linux adalah Bash. Di Bash, variabel harus menggunakan awalan tanda dolar untuk perluasan parameter . Sebagai contoh:

x=20
y=5
expr $x / $y

Tentu saja, Bash juga memiliki operator aritmatika dan sintaks ekspansi aritmatika khusus , jadi tidak perlu memanggil biner expr sebagai proses terpisah. Anda dapat membiarkan shell melakukan semua pekerjaan seperti ini:

x=20; y=5
echo $((x / y))
Todd A. Jacobs
sumber
1
Lihat Ekspansi Aritmatika dan Aritmatika Shell di Bash Reference Manual untuk semua detail berdarah.
Todd A. Jacobs
1
Ini tidak ada hubungannya dengan dereferensi tetapi interpolasi dan exprtidak disarankan pada tahun 2013.
Gilles Quenot
@sputnick Anda jelas bingung. Silakan berkonsultasi dengan kamus. Lihat dereferensi dan interpolasi .
Todd A. Jacobs
1
Kata yang lebih baik berkembang , tetapi tidak dereferensi . dereferencing digunakan saat kita menggunakan pointer , tidak demikian halnya di sini, itu hanya variabel sederhana.
Gilles Quenot
1
@Prashant: tldp tidak dikenal sebagai referensi yang baik di dunia bash.
Gilles Quenot
2

Untuk mendapatkan angka setelah koma desimal, Anda dapat melakukan ini: -

read num1 num2
div=`echo $num1 / $num2 | bc -l`
echo $div
Shayan Chatterjee
sumber
1

anggap saja

x=50
y=5

kemudian

z=$((x/y))

ini akan bekerja dengan baik. Tetapi jika Anda ingin menggunakan / operator dalam pernyataan kasus daripada tidak dapat menyelesaikannya. masukkan kode di sini Dalam hal ini gunakan string sederhana seperti div atau devide atau yang lainnya. Lihat kodenya

Pooja Rajput
sumber
Ini salah. /berfungsi dengan baik sebagai label shell-case. Apa yang tidak berhasil adalah menggunakan *perkalian tanpa mengutipnya, yang mungkin memang seperti yang Anda lakukan; yang menyebabkannya secara efektif menimpa semua item berikut dalam kasus ini, yang dalam contoh Anda adalah 'devide' dan 'modulo'
dave_thompson_085