Pertanyaan Apa perbedaan antara kurung ganda dan tunggal di bash?


Saya hanya ingin tahu apa sebenarnya perbedaannya

[[ $STRING != foo ]]

dan

[ $STRING != foo ]

adalah, selain itu yang terakhir adalah posix-compliant, ditemukan di sh dan yang pertama adalah ekstensi yang ditemukan di bash.


344
2017-08-09 21:11




stackoverflow.com/questions/13542832 - Ciro Santilli 新疆改造中心 六四事件 法轮功
Jika Anda juga bertanya-tanya tentang tidak menggunakan tanda kurung sama sekali, mis. dalam konteks suatu if pernyataan, lihat mywiki.wooledge.org/BashPitfalls#if_.5Bgrep_foo_myfile.5D - Kev
juga, Dari dokumen Ubuntu: wiki.ubuntu.com/… - radistao


Jawaban:


Ada beberapa perbedaan. Menurut saya, beberapa yang paling penting adalah:

  1. [ adalah builtin di Bash dan banyak cangkang modern lainnya. The builtin [ mirip dengan test dengan persyaratan tambahan penutupan ]. The builtins [ dan test meniru fungsinya /bin/[ dan /bin/test bersama dengan keterbatasan mereka sehingga skrip akan kompatibel ke belakang. Eksekutabel asli masih ada sebagian besar untuk kepatuhan POSIX dan kompatibilitas mundur. Menjalankan perintah type [ di Bash menunjukkan itu [ diinterpretasikan sebagai built-in secara default. (Catatan: which [ hanya mencari file yang dapat dieksekusi di PATH dan setara dengan type -p [)
  2. [[ tidak selaras, tidak akan selalu bekerja dengan apa pun /bin/sh menunjuk ke. Begitu [[ adalah opsi Bash / Zsh / Ksh yang lebih modern.
  3. Karena [[ dibangun ke shell dan tidak memiliki persyaratan warisan, Anda tidak perlu khawatir tentang pembagian kata berdasarkan pada IFS variabel mengacaukan variabel yang mengevaluasi string dengan spasi. Oleh karena itu, Anda tidak perlu memasukkan variabel dalam tanda kutip ganda.

Untuk sebagian besar, sisanya hanyalah sintaks yang lebih bagus. Untuk melihat lebih banyak perbedaan, saya merekomendasikan tautan ini ke jawaban FAQ: Apa perbedaan antara tes, [dan [[?. Bahkan, jika Anda serius tentang bash scripting, saya sarankan membaca keseluruhannya wiki, termasuk FAQ, Perangkap, dan Panduan. Bagian tes dari bagian panduan menjelaskan perbedaan-perbedaan ini juga, dan mengapa penulis (s) berpikir [[ adalah pilihan yang lebih baik jika Anda tidak perlu khawatir menjadi portabel. Alasan utamanya adalah:

  1. Anda tidak perlu khawatir tentang mengutip sisi kiri tes sehingga benar-benar dibaca sebagai variabel.
  2. Anda tidak harus melarikan diri kurang dari dan lebih besar dari < > dengan backslashes agar mereka tidak dievaluasi sebagai pengalihan masukan, yang dapat benar-benar mengacaukan beberapa hal dengan menimpa file. Ini kembali lagi ke [[ sedang dibangun. Jika [(tes) adalah program eksternal shell harus membuat pengecualian dalam cara mengevaluasi < dan > hanya jika /bin/test sedang dipanggil, yang tidak akan masuk akal.

261
2017-08-09 21:56



Terima kasih, tautan ke FAQ bash adalah apa yang saya cari (tidak tahu tentang halaman itu, terima kasih). - 0x89
Saya mengedit posting Anda dengan informasi ini, tetapi [dan pengujian dijalankan sebagai builtins. The builtins dirancang untuk menggantikan / bin / [dan / bin / tes tetapi diperlukan untuk mereproduksi keterbatasan binari juga. Jenis perintah ['memverifikasi bahwa builtin digunakan. 'Yang [' hanya mencari file yang dapat dieksekusi pada PATH dan setara dengan 'ketik -P [' - klynch


Pendeknya:

[adalah bash Dibangun

[[]] adalah bash Kata kunci

Kata kunci: Kata kunci cukup seperti bawaan, tetapi perbedaan utamanya adalah bahwa aturan penguraian khusus berlaku untuknya. Misalnya, [adalah bash builtin, sedangkan [[bash keyword]. Keduanya digunakan untuk menguji hal-hal, tetapi karena [[adalah kata kunci daripada builtin, itu manfaat dari beberapa aturan parsing khusus yang membuatnya lebih mudah:

  $ [ a < b ]
 -bash: b: No such file or directory
  $ [[ a < b ]]

Contoh pertama mengembalikan kesalahan karena bash mencoba untuk mengarahkan file b ke perintah [a]. Contoh kedua benar-benar melakukan apa yang Anda harapkan. Karakter <tidak lagi memiliki arti khusus dari operator File Redirection.

Sumber: http://mywiki.wooledge.org/BashGuide/CommandsAndArguments


108
2017-12-29 19:42



[ adalah perintah shell POSIX; itu tidak perlu dibangun. ] hanyalah sebuah argumen yang dicari oleh perintah itu, sehingga sintaksnya seimbang. Perintah adalah sinonim untuk test kecuali itu test tidak mencari penutupan ]. - Kaz
Lihat disini: pubs.opengroup.org/onlinepubs/009695399/utilities/test.html - Kaz


Perbedaan perilaku

Diuji dalam Bash 4.3.11:

  • POSIX vs Bash extension:

  • perintah biasa vs sihir

    • [ hanya perintah biasa dengan nama yang aneh.

      ] hanyalah sebuah argumen [ yang mencegah argumen lebih lanjut digunakan.

      Ubuntu 16.04 sebenarnya memiliki eksekusi untuk itu di /usr/bin/[ disediakan oleh coreutils, tetapi versi bash built-in diutamakan.

      Tidak ada yang diubah dengan cara Bash mem-parsing perintah.

      Khususnya, < adalah pengalihan, && dan || gabungkan beberapa perintah, ( ) menghasilkan subklon kecuali lolos \, dan ekspansi kata terjadi seperti biasa.

    • [[ X ]] adalah konstruksi tunggal yang membuatnya X diurai secara ajaib. <, &&, || dan () diperlakukan khusus, dan aturan pemisahan kata berbeda.

      Ada juga perbedaan lebih lanjut seperti = dan =~.

    Di Bashese: [ adalah perintah built-in, dan [[ adalah kata kunci: https://askubuntu.com/questions/445749/whats-the-difference-between-shell-builtin-and-shell-keyword

  • <

  • && dan ||

    • [[ a = a && b = b ]]: benar, logis dan
    • [ a = a && b = b ]: kesalahan sintaks, && diuraikan sebagai pemisah perintah AND cmd1 && cmd2 
    • [ a = a -a b = b ]: setara, tetapi tidak digunakan lagi oleh POSIX
    • [ a = a ] && [ b = b ]: Rekomendasi POSIX
  • (

    • [[ (a = a || a = b) && a = b ]]: Salah
    • [ ( a = a ) ]: kesalahan sintaks, () ditafsirkan sebagai subkulit
    • [ \( a = a -o a = b \) -a a = b ]: setara, tapi () sudah ditinggalkan oleh POSIX
    • ([ a = a ] || [ a = b ]) && [ a = b ] Rekomendasi POSIX
  • perpecahan kata

    • x='a b'; [[ $x = 'a b' ]]: benar, kutipan tidak diperlukan
    • x='a b'; [ $x = 'a b' ]: kesalahan sintaksis, meluas ke [ a b = 'a b' ]
    • x='a b'; [ "$x" = 'a b' ]: setara
  • =

    • [[ ab = a? ]]: benar, karena memang demikian pencocokan pola (* ? [ adalah sihir). Tidak gumpalan memperluas ke file di direktori saat ini.
    • [ ab = a? ]: a? glob mengembang. Jadi mungkin benar atau salah tergantung pada file di direktori saat ini.
    • [ ab = a\? ]: palsu, bukan ekspansi glob
    • = dan == sama di keduanya [ dan [[, tapi == adalah ekstensi Bash.
    • printf 'ab' | grep -Eq 'a.': EEP setara POSIX
    • [[ ab =~ 'ab?' ]]: salah, kehilangan sihir dengan ''
    • [[ ab? =~ 'ab?' ]]: benar
  • =~

    • [[ ab =~ ab? ]]: true, POSIX ekspresi reguler diperpanjang pertandingan, ? tidak meluas
    • [ a =~ a ]: kesalahan sintaks
    • printf 'ab' | grep -Eq 'ab?': Setara POSIX

Rekomendasi

Saya lebih suka selalu menggunakan [].

Ada POSIX yang setara untuk setiap [[ ]] membangun saya lihat.

Jika Anda menggunakan [[ ]] kamu:

  • kehilangan portabilitas
  • memaksa pembaca untuk mempelajari seluk-beluk ekstensi bash lain. [hanya perintah biasa dengan nama yang aneh, tidak ada semantik khusus yang terlibat.

61
2017-07-12 10:22



Bagaimana cara menggunakan printf 'ab' | grep -Eq 'ab?' dalam if [ … ]? - meeDamian
@meeDamian if ( printf 'ab' | grep -Eq 'a' ); then echo 'a'; fi. [] adalah perintah seperti itu grep. Itu () mungkin tidak diperlukan pada perintah itu saya tidak yakin: Saya menambahkannya karena |, tergantung pada bagaimana Bash mem-parsing sesuatu. Jika tidak ada | Saya yakin Anda bisa menulis dengan adil if cmd arg arg; then. - Ciro Santilli 新疆改造中心 六四事件 法轮功
@meeDamian ya, tidak perlu () kelihatannya: stackoverflow.com/questions/8965509/… - Ciro Santilli 新疆改造中心 六四事件 法轮功
Daftar yang bagus! Lihat juga: wiki.ubuntu.com/… - radistao


Berdasarkan pembacaan cepat dari bagian yang relevan dari manual, perbedaan utama tampaknya adalah == dan != operator cocok dengan pola, bukan string literal, dan juga ada =~ operator perbandingan regex.


4
2017-08-09 21:17





Braket Tunggal yaitu [] adalah POSIX shell compliant untuk menyertakan ekspresi kondisional.

Kurung ganda yaitu [[]] adalah versi yang disempurnakan (atau ekstensi) dari versi POSIX standar, ini didukung oleh bash dan shell lainnya (zsh, ksh).

Dalam bash, untuk perbandingan numerik yang kami gunakan eq, ne,lt dan gt, dengan kurung ganda untuk perbandingan yang bisa kita gunakan ==, !=, <, dan > secara harfiah.

  • [ adalah sinonim untuk perintah uji. Bahkan jika dibangun di shell itu menciptakan proses baru.
  • [[ adalah versi baru yang ditingkatkan, yang merupakan kata kunci, bukan program.

sebagai contoh:

[ var1 lt var2] #works
[ var1 < var2] #error: var2 No such file or directory 
[ var1 \< var2] #works with escape
[[ var1 < var2]] #works

3
2018-02-08 03:15