Linux kabuğundaki değişkenlerle nasıl bölme yapabilirim?


136

Kabuğumda aşağıdaki gibi komutları çalıştırdığımda expr: non-integer argumenthata veriyor . Lütfen birisi bunu bana açıklayabilir mi?

$ x=20
$ y=5
$ expr x / y 
expr: non-integer argument

4
@ShivanRaptor Sorunun bir RTFM sorusu olduğu iddia edilebilirse de, kesinlikle geçerli bir kabuk programlama sorusudur. Ayrıca, kayıt silme gerektirmeyen dillerden (ör. Ruby veya JavaScript) gelen biri için de makul bir sorudur. Açık bırakılmalıdır.
Todd A. Jacobs

6
@ShivanRaptor Hayır, bu konu ile ilgili. Bu Bash'ta programlama ile ilgili. Unix / Linux programlama için değil, öncelikle sistemi kullanmak içindir. Kabuk komut dosyası oluşturma, programlama ve sistemi kullanma arasındaki sınırı kapsıyor, bu nedenle bu, her iki sitede de konu olabilir. "Nasıl ağ kurabilirim" hakkında bir soru olsaydı, bu kesinlikle Unix / Linux'a ait olurdu. Bash'teki interaktif tuş bağlamalarıyla ilgili bir soru olsaydı, o da oraya ait olurdu. Ancak kabuk komut dosyası oluşturma ile ilgili bir soru kesinlikle burada da var.
Brian Campbell

Python'a kabuktan bir çağrı kullanarak (
Victoria Stuart

Yanıtlar:


195

Bu değişkenler kabuk değişkenleridir. Bunları başka bir programa ( ör. expr ) Parametre olarak genişletmek için $önekini kullanmanız gerekir :

expr $x / $y

Şikayet etmesinin nedeni, alfabetik karakterler ( yani tamsayı olmayan) üzerinde çalışmayı düşündüğünüzdür.

Bash kabuğunu kullanıyorsanız, ifade sözdizimini kullanarak aynı sonucu elde edebilirsiniz:

echo $((x / y))

Veya:

z=$((x / y))
echo $z

1
Bash için man sayfasını okuyarak çok şey öğrenebilirsiniz. Bilgi man bashistemine yazın ( qçıkmak için)
Çeltik

62
Bu sayfada bir yerlerde, çoğu (hepsi değilse de) GNU / Linux mermilerinin yalnızca tamsayı işlemleri gerçekleştirdiğine dikkat edilmelidir .
Skippy le Grand Gourou

35

Zaten diğer konularda bahsedildiğine inanıyorum:

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

o zaman şunu yazabilirsiniz:

calc 7.5/3.2
  2.34375

Sizin durumunuzda:

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

veya isterseniz, bunu ayrı bir komut dosyası olarak ekleyin ve $ PATH içinde kullanılabilir hale getirin, böylece her zaman yerel kabuğunuza sahip olursunuz:

#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }

4
Ayrıca kullanabilirsinizecho '1 / 3' | bc -l
Eugene

19

Neden kullanmıyorsunuz; Çok daha kolay buluyorum. Yararlı bulabileceğiniz bir örnek:

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

Başka bir basit örnek - 1970'den bu yana geçen gün sayısını hesaplayın:

let days=$(date +%s)/86400

15

Bash Değişkenlerine Referans Verme Parametre Genişlemesi Gerektirir

Çoğu Linux dağıtımında varsayılan kabuk Bash'tır. Bash'te, değişkenlerin parametre genişletme için bir dolar işareti öneki kullanması gerekir . Örneğin:

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

Tabii ki, Bash ayrıca aritmetik işleçlere ve özel bir aritmetik genişletme sözdizimine sahiptir , bu nedenle ifade ikili dosyasını ayrı bir işlem olarak çağırmaya gerek yoktur . Kabuğun tüm işi böyle yapmasına izin verebilirsiniz:

x=20; y=5
echo $((x / y))

Tüm kanlı ayrıntılar için Bash Referans Kılavuzundaki Aritmetik Genişletme ve Kabuk Aritmetiği bölümüne bakın .
Todd A. Jacobs

1
Bu ile ilgisi yoktur dereferencing ama interpolating ve expr2013 yılında önerilmez
Gilles Quenot

@sputnick Açıkça kafan karıştı. Lütfen bir sözlüğe danışmaktan çekinmeyin. Bkz. Kuralsızlık ve enterpolat .
Todd A. Jacobs

1
Daha iyi bir kelime genişliyor , ancak kayıttan çıkarılma değil . dereferencing , işaretçiler kullandığımızda kullanılır , burada durum böyle değildir, bu sadece basit değişkenlerdir.
Gilles Quenot

1
@Prashant: tldp'nin bash dünyasında iyi bir referans olduğu bilinmemektedir.
Gilles Quenot

1

Varsayalım

x=50
y=5

sonra

z=$((x/y))

bu düzgün çalışır. Ancak / operatörünü durum bildirimlerinde kullanmak istemiyorsanız çözümleyemez. kodu buraya girin Bu durumda div veya devide gibi basit dizeler veya başka bir şey kullanın. Kodu görün


Bu yanlış. /mermi kovanı etiketi olarak iyi çalışır. İşe yaramayan şey, *alıntı yapmadan çarpmak için kullanmaktır , ki aslında yaptığınız şey bu olabilir; bu da, örneğinizde 'devide' ve 'modulo' olan aşağıdaki tüm öğeleri etkili bir şekilde geçersiz kılmasına neden olur
dave_thompson_085

0

Ondalık noktadan sonra sayı almak için şunları yapabilirsiniz: -

read num1 num2
div=`echo $num1 / $num2 |bc -l`
echo $div
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.