Perbandingan string dalam bash. [[: tidak ditemukan

166

Saya mencoba membandingkan string dalam bash. Saya sudah menemukan jawaban tentang cara melakukannya di stackoverflow . Dalam skrip yang saya coba, saya menggunakan kode yang dikirimkan oleh Adam dalam pertanyaan yang disebutkan:

#!/bin/bash
string='My string';

if [[ "$string" == *My* ]]
then
  echo "It's there!";
fi

needle='y s'
if [[ "$string" == *"$needle"* ]]; then
  echo "haystack '$string' contains needle '$needle'"
fi

Saya juga mencoba pendekatan dari ubuntuforums yang dapat Anda temukan di pos ke-2

if [[ $var =~ regexp ]]; then
  #do something
fi

Dalam kedua kasus saya menerima kesalahan:

[[: not found

Apa yang saya lakukan salah?

pengguna1581900
sumber
Saya mungkin salah melakukannya, tetapi menggunakan braket persegi tunggal selalu berhasil untuk saya.
Markus Unterwaditzer
1
Apa yang /bin/bash --versiondicetak?
themel
4
[tidak akan berfungsi dalam kasus ini, karena tidak mendukung pola.
Ansgar Wiechers

Jawaban:

158

[[adalah bash-builtin. /bin/bashTampaknya Anda bukan bash yang sebenarnya.

Dari komentar:

Tambahkan #!/bin/bashdi bagian atas file

Ansgar Wiechers
sumber
jika saya mengetik: ketik '[[' i get [[adalah kata kunci shell
user1581900
5
Apakah Anda mendapatkan hasil yang sama saat berlari /bin/bash -c "type [["?
Ansgar Wiechers
43
Ini terjadi pada saya karena saya lupa menambahkan #!/bin/bashdi bagian atas file saya
morphatic
12
Kebetulan saya karena saya menjalankan skrip dengan sh, banyak frustrasi. Sekarang saya hanya perlu mengulang semua yang saya undid sebelum menemukan jawaban ini.
Louis Loudog Trottier
174

Bagaimana Anda menjalankan skrip Anda? Jika Anda melakukannya dengan

$ sh myscript

Kamu harus mencobanya:

$ bash myscript

atau, jika skrip dapat dieksekusi:

$ ./myscript

sh dan bash adalah dua cangkang yang berbeda . Sementara dalam kasus pertama Anda menyerahkan skrip Anda sebagai argumen ke penerjemah sh, dalam kasus kedua Anda memutuskan baris pertama penerjemah mana yang akan digunakan.

Akos K
sumber
saya mendapat izin yang ditolak dengan cara ini. dengan sudo ./myscript perintahnya tidak ditemukan
user1581900
11
lakukan chmod + x myscript , lalu jalankan lagi, Anda tidak perlu sudo
Akos K
2
Bagaimana Anda memohon naskah Anda?
Akos K
seperti yang kamu katakan. biasanya saya menyebutnya dengan '$ sh myscipt.sh'. 2nd time setelah melakukan chmod + x myscript.sh saya menyebutnya dengan ./myscript.sh
user1581900
5
Kesalahan diharapkan ketika Anda menjalankan skrip melalui sh myscript.sh, karena /bin/shmengemulasi shell Bourne di mana [[bukan builtin. Namun, menjalankan skrip via ./script.shseharusnya tidak menghasilkan kesalahan, karena dalam hal itu shebang harus menyebabkan /bin/bashdigunakan.
Ansgar Wiechers
81

Apakah baris pertama dalam skrip Anda:

#!/bin/bash

atau

#!/bin/sh

shell sh menghasilkan pesan kesalahan ini, bukan bash

Wiley
sumber
1
Baris pertama juga hilang karena saya membuat kesalahan yang penulis sebutkan!
Anonim
14

Saya memiliki masalah ini ketika menginstal Heroku Toolbelt

Inilah cara saya memecahkan masalah

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 ago 15  2012 /bin/sh -> dash

Seperti yang Anda lihat, / bin / sh adalah tautan ke "dash" (bukan bash), dan [[ini adalah bash sintaksis gula. Jadi saya baru saja mengganti tautan ke / bin / bash. Hati-hati menggunakan rm seperti ini di sistem Anda!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh
Jperelli
sumber
6
Mengganti default shuntuk distro Anda adalah IMHO yang keliru. Shell yang dijalankan dengan shharus bekerja dengan dash; jika tidak, itu bug dalam skrip. Jika Anda membutuhkan bashfitur, gunakan bash, bukan sh.
tripleee
4
ini kedengarannya mengerikan tbh
MrVaykadji
2
Saya setuju, itu hanya solusi buruk. Solusi yang serupa tetapi lebih baik adalah menggunakan update-alternatives(di debian-based-linux) seperti ini justinconover.wordpress.com/2012/05/14/… tetapi pada akhirnya, itu akan sama.
jperelli
13

Seperti yang disebutkan @Ansgar, [[adalah bashism, yaitu dibangun ke dalam Bash dan tidak tersedia untuk shell lainnya. Jika Anda ingin skrip Anda portabel, gunakan [. Perbandingan juga membutuhkan sintaks yang berbeda: ubah ==menjadi =.

Amedee Van Gasse
sumber
Memeriksa sedikit dengan Ubuntu 16.04 dan (sh ->) dash 0.5.8-2.1ubuntu2 dan menemukan bahwa [berfungsi dengan baik dalam kombinasi dengan "-eq" dan sejenisnya. Informasi serupa tentang operator pembanding untuk konteks ini dapat ditemukan di sini: stackoverflow.com/questions/10849297/... - Saya lebih lanjut berdiskusi dengan operator evaluasi (()) seperti yang direkomendasikan dalam tautan berikutnya tetapi tampaknya gagal untuk perubahan invasif minimal saya / atau / itu membutuhkan tingkat perubahan kode yang jauh lebih dalam. softpanorama.org/Scripting/Shellorama/Control_structures/…
Alexander Stohr
3

Tentukan bash alih-alih sh saat menjalankan skrip. Saya pribadi memperhatikan mereka berbeda di bawah ubuntu 12.10:

bash script.sh arg0 ... argn

Tautan kecil
sumber
Ini memperbaikinya untukku!
Djamillah