Mencoba mencari cara mengonversi argumen ke integer untuk menjalankan aritmatika, dan kemudian mencetaknya, katakan untuk addOne.sh:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Mencoba mencari cara mengonversi argumen ke integer untuk menjalankan aritmatika, dan kemudian mencetaknya, katakan untuk addOne.sh:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Jawaban:
Dalam bash, seseorang tidak "mengubah argumen menjadi integer untuk melakukan aritmatika". Dalam bash, variabel diperlakukan sebagai integer atau string tergantung pada konteksnya.
Untuk melakukan aritmatika, Anda harus memanggil operator ekspansi aritmatika $((...)). Sebagai contoh:
$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3
atau umumnya disukai:
$ echo "$((a + 1))"
3
Anda harus menyadari bahwa bash (tidak seperti ksh93, zsh atau yash) hanya melakukan aritmatika integer . Jika Anda memiliki angka floating point (angka dengan desimal), maka ada alat lain untuk membantu. Misalnya, gunakan bc:
$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14
Atau Anda dapat menggunakan shell dengan dukungan aritmatika floating point alih-alih bash:
zsh> echo $((3.14 + 1))
4.14
Di bash, Anda dapat melakukan konversi dari apa saja ke integer menggunakan printf -v :
printf -v int '%d\n' "$1" 2>/dev/null
Angka mengambang akan dikonversi menjadi bilangan bulat, sementara apa pun yang tidak terlihat seperti angka akan dikonversi menjadi 0. Eksponensial akan terpotong ke angka sebelum e
Contoh:
$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
printf -vini dapat dicapai dengan substitusi perintah:int="$(printf '%d' 123.123 2>/dev/null)"
bashAnda gunakan?
Situasi serupa muncul baru-baru ini ketika mengembangkan skrip bash untuk dijalankan di lingkungan Linux dan OSX. Hasil dari satu perintah di OSX mengembalikan string yang berisi kode hasil; yaitu " 0",. Tentu saja, ini gagal untuk menguji dengan benar dalam kasus berikut:
if [[ $targetCnt != 0 ]]; then...
Solusinya adalah dengan memaksa (yaitu, 'mengkonversi') hasilnya ke integer, mirip dengan apa yang dijawab @ John1024 di atas sehingga berfungsi seperti yang diharapkan:
targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
==dll di [[(juga [alias test) melakukan perbandingan string. Ada beberapa operator untuk perbandingan aritmatika misalnya [[ $targetcnt -ne 0 ]]; lihat halaman manual (atau info) di bawah Ekspresi Bersyarat. Untuk memangkas spasi secara spesifik, Anda dapat menggunakan [dengan ekspansi variabel yang tidak [ $targetcnt == 0 ]dikutip untuk mendapatkan penempatan kata-kata standar (TIDAK dilakukan [[) tetapi secara umum pendekatan itu membawa Anda ke dalam bahaya.
peduli dengan kode warna, bahkan dalam trace ( -x) mereka tidak akan muncul, apa yang akan memberikannya adalah bahwa string yang seharusnya nomor dibungkus dengan tanda kutip tidak peduli bagaimana Anda mencetaknya.
$((var+var))gagal bahkan meskipun jika Anda echoatau printfkeduanya vars mereka sama. Saya tidak tahu cara memperbaikinya karena saya hanya bisa memperbaikinya dengan menonaktifkan kode warna pada sumber output. Untuk menemukannya di jejak log Anda akan melihat variabel menyinggung ditetapkan sebagai var='0'sementara itu seharusnyavar=0
sedjika Anda tidak dapat menonaktifkannya
printf "1 + %s\n" $1 won't do ?