Sudah belajar bash minggu ini dan mengalami kesulitan.
#!/bin/sh
if [ false ]; then
echo "True"
else
echo "False"
fi
Ini akan selalu menghasilkan True walaupun kondisi tampaknya menunjukkan sebaliknya. Jika saya melepas tanda kurung []
maka itu berfungsi, tapi saya tidak mengerti mengapa.
bash
conditional-operator
sepuluh mil
sumber
sumber
#!/bin/sh
bukan skrip bash - skrip POSIX sh. Bahkan jika penerjemah sh POSIX pada sistem Anda disediakan oleh bash, ia mematikan banyak ekstensi. Jika Anda ingin menulis skrip bash, gunakan#!/bin/bash
atau padanannya yang sesuai secara lokal (#!/usr/bin/env bash
untuk menggunakan penerjemah bash pertama dalam PATH).[[ false ]]
juga mempengaruhi .Jawaban:
Anda menjalankan perintah
[
(aliastest
) dengan argumen "false", bukan menjalankan perintahfalse
. Karena "false" adalah string yang tidak kosong,test
perintah selalu berhasil. Untuk benar-benar menjalankan perintah, lepaskan[
perintah.sumber
bash
tidak memiliki tipe data Boolean, jadi tidak ada kata kunci yang mewakili benar dan salah. Theif
pernyataan hanya memeriksa apakah perintah yang Anda berikan berhasil atau gagal. Thetest
perintah mengambil ekspresi dan berhasil jika ungkapan benar; string yang tidak kosong adalah ekspresi yang dievaluasi sebagai true, sama seperti pada kebanyakan bahasa pemrograman lainnya.false
adalah perintah yang selalu gagal. (Dengan analogi,true
adalah perintah yang selalu berhasil.)if [[ false ]];
mengembalikan true juga. Seperti halnyaif [[ 0 ]];
. Danif [[ /usr/bin/false ]];
tidak melewatkan blok juga. Bagaimana false atau 0 bisa bernilai nol? Sialan ini membuat frustrasi. Jika itu penting, OS X 10.8; Bash 3.false
untuk konstanta Boolean atau0
untuk literal integer; keduanya hanyalah string biasa.[[ x ]]
sama dengan[[ -n x ]]
untuk string apa punx
yang tidak dimulai dengan tanda hubung.bash
tidak memiliki setiap konstanta Boolean dalam konteks apapun. String yang terlihat seperti bilangan bulat diperlakukan seperti di dalam(( ... ))
atau dengan operator seperti-eq
atau-lt
di dalam[[ ... ]]
.if $predicate
dapat dengan mudah disalahgunakan untuk mengeksekusi kode bermusuhan dengan cara yangif [[ $predicate ]]
tidak bisa.Primer Boolean Cepat untuk Bash
The
if
Pernyataan mengambil perintah sebagai argumen (seperti halnya&&
,||
, dll). Kode hasil integer dari perintah ditafsirkan sebagai boolean (0 / null = true, 1 / else = false).The
test
Pernyataan mengambil operator dan operan sebagai argumen dan mengembalikan kode hasil dalam format yang sama sepertiif
. Sebuah alias daritest
pernyataan tersebut adalah[
, yang sering digunakan denganif
untuk melakukan perbandingan yang lebih kompleks.The
true
danfalse
pernyataan melakukan apa-apa dan kode hasil (0 dan 1, masing-masing). Sehingga mereka dapat digunakan sebagai boolean literal di Bash. Tetapi jika Anda meletakkan pernyataan di tempat yang ditafsirkan sebagai string, Anda akan mengalami masalah. Dalam kasus Anda:Begitu:
Hal ini mirip dengan melakukan sesuatu seperti
echo '$foo'
vsecho "$foo"
.Saat menggunakan
test
pernyataan, hasilnya tergantung pada operator yang digunakan.Singkatnya , jika Anda hanya ingin menguji sesuatu sebagai lulus / gagal (alias "benar" / "salah"), maka berikan perintah ke pernyataan Anda
if
atau lainnya&&
, tanpa tanda kurung. Untuk perbandingan yang rumit, gunakan tanda kurung dengan operator yang tepat.Dan ya, saya sadar tidak ada yang namanya tipe boolean asli di Bash, dan itu
if
dan[
dantrue
secara teknis "perintah" dan bukan "pernyataan"; ini hanya penjelasan yang sangat mendasar dan fungsional.sumber
if (( $x )); then echo "Hello"; fi
menunjukkan pesan untukx=1
tetapi tidak untukx=0
ataux=
(tidak ditentukan).Saya menemukan bahwa saya dapat melakukan beberapa logika dasar dengan menjalankan sesuatu seperti:
sumber
( $A && $B )
adalah operasi yang sangat tidak efisien - Anda menelurkan subproses melalui pemanggilanfork()
, kemudian memisahkan string dari konten$A
untuk menghasilkan daftar elemen (dalam hal ini ukuran satu), dan mengevaluasi setiap elemen sebagai bola (dalam hal ini satu yang mengevaluasi sendiri), kemudian menjalankan hasilnya sebagai perintah (dalam hal ini, perintah builtin).true
danfalse
berasal dari tempat lain, ada risiko bahwa mereka sebenarnya bisa mengandung konten selaintrue
ataufalse
, dan Anda bisa mendapatkan perilaku tak terduga hingga dan termasuk eksekusi perintah sewenang-wenang.A=1; B=1
danif (( A && B ))
- memperlakukannya sebagai angka - atau[[ $A && $B ]]
, yang memperlakukan string kosong sebagai false dan string non-kosong sebagai true.Menggunakan true / false menghapus beberapa ...
sumber
[[ "$0" =~ "bash" ]]
membuat skrip bekerja untuk saya.