So sánh chuỗi trong bash. [[: không tìm thấy


164

Tôi đang cố gắng để so sánh các chuỗi trong bash. Tôi đã tìm thấy một câu trả lời về cách làm điều đó trên stackoverflow . Trong kịch bản tôi đang thử, tôi đang sử dụng mã được gửi bởi Adam trong câu hỏi được đề cập:

#!/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

Tôi cũng đã thử cách tiếp cận từ ubuntuforums mà bạn có thể tìm thấy trong bài viết thứ 2

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

Trong cả hai trường hợp tôi đều nhận được lỗi:

[[: not found

Tôi đang làm gì sai?


Tôi có thể làm sai, nhưng sử dụng một dấu ngoặc vuông duy nhất luôn làm việc cho tôi.
Markus Unterwaditzer

1
Không /bin/bash --versionin gì?
themel

4
[sẽ không hoạt động trong trường hợp này, vì nó không hỗ trợ các mẫu.
Ansgar Wiechers

Câu trả lời:


156

[[là một bash-dựng sẵn. Bạn /bin/bashdường như không phải là một bash thực tế.


nếu tôi gõ: gõ '[[' i get [[là một từ khóa shell
user1581900

5
Bạn có nhận được kết quả tương tự khi bạn chạy /bin/bash -c "type [["?
Ansgar Wiechers

42
Điều này xảy ra với tôi vì tôi quên thêm #!/bin/bashvào đầu tập tin của mình
morphatic

12
Xảy ra với tôi bởi vì tôi chạy kịch bản với sh, rất nhiều cho sự thất vọng. Bây giờ tôi chỉ phải làm lại mọi thứ tôi đã hoàn thành trước khi tìm thấy câu trả lời này.
Louis Loudog Trottier

174

Làm thế nào bạn đang chạy tập lệnh của bạn? Nếu bạn đã làm với

$ sh myscript

bạn nên thử:

$ bash myscript

hoặc, nếu tập lệnh có thể thực thi được:

$ ./myscript

shbash là hai vỏ khác nhau . Mặc dù trong trường hợp đầu tiên bạn chuyển tập lệnh của mình làm đối số cho trình thông dịch sh, nhưng trong trường hợp thứ hai, bạn quyết định dòng đầu tiên mà trình thông dịch sẽ được sử dụng.


tôi đã được phép từ chối theo cách này. với sudo ./myscript lệnh của nó không được tìm thấy
user1581900

11
làm chmod + x myscript , sau đó chạy lại, bạn không cần sudo
Akos K

2
Làm thế nào bạn đang gọi cho bạn kịch bản?
Akos K

như bạn đã nói thông thường tôi gọi nó bằng '$ sh myscipt.sh'. Lần thứ 2 sau khi thực hiện chmod + x myscript.sh tôi đã gọi nó bằng ./myscript.sh
user1581900

5
Lỗi được dự kiến ​​khi bạn chạy tập lệnh thông qua sh myscript.sh, vì /bin/shmô phỏng trình bao Bourne [[không phải là phần dựng sẵn. Tuy nhiên, chạy tập lệnh thông qua ./script.shsẽ không gây ra lỗi, vì trong trường hợp đó, shebang sẽ gây ra /bin/bashđược sử dụng.
Ansgar Wiechers

81

Là dòng đầu tiên trong kịch bản của bạn:

#!/bin/bash

hoặc là

#!/bin/sh

Shell sh tạo ra thông báo lỗi này, không phải bash


1
Dòng đầu tiên cũng bị thiếu đối với tôi tạo ra lỗi mà tác giả đã đề cập!
Ẩn danh

13

Tôi gặp vấn đề này khi cài đặt Heroku Toolbelt

Đây là cách tôi giải quyết vấn đề

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

Như bạn có thể thấy, / bin / sh là một liên kết đến "dash" (không phải bash) và [[là bash cú pháp cú pháp. Vì vậy, tôi chỉ cần thay thế liên kết đến / bin / bash. Cẩn thận sử dụng rm như thế này trong hệ thống của bạn!

$ sudo rm /bin/sh
$ sudo ln -s /bin/bash /bin/sh

6
Ghi đè mặc định shcho bản phân phối của bạn là IMHO không thông minh. Một shell được chạy với shnên hoạt động với dash; nếu không, đó là một lỗi trong tập lệnh. Nếu bạn cần bashcác tính năng, sử dụng bash, không sh.
tripleee

4
Điều này nghe có vẻ khủng khiếp
MrVaykadji

2
Tôi đồng ý, đó chỉ là một cách giải quyết xấu xí. Một cách giải quyết tương tự nhưng tốt hơn sẽ là sử dụng update-alternatives(trong debian-dựa trên linux) như justinconover.wordpress.com/2012/05/14/, nhưng cuối cùng, nó sẽ giống nhau.
jperelli

13

Như @Ansgar đã đề cập, [[là một bashism, tức là được tích hợp vào Bash và không có sẵn cho các shell khác. Nếu bạn muốn tập lệnh của bạn được di động, sử dụng [. So sánh cũng sẽ cần một cú pháp khác: thay đổi ==thành =.


Đã kiểm tra một chút với Ubuntu 16.04 và (sh ->) dash 0.5.8-2.1ubfox2 và thấy rằng [hoạt động tốt khi kết hợp với "-eq" và tương tự. Thông tin tương tự về các toán tử so sánh cho bối cảnh này có thể được tìm thấy ở đây: stackoverflow.com/questions/10849297/ mẹo - Tôi tiếp tục tìm hiểu về toán tử đánh giá (()) như được đề xuất trong liên kết tiếp theo nhưng dường như không thành công cho những thay đổi xâm lấn tối thiểu của tôi / hoặc / nó sẽ cần một mức độ thay đổi mã sâu hơn nhiều. softpanorama.org/Scripting/Shellorama/Control_ cấu trúc / từ
Alexander Stohr

3

Chỉ định bash thay vì sh khi chạy tập lệnh. Cá nhân tôi nhận thấy chúng khác nhau dưới Ubuntu 12.10:

bash script.sh arg0 ... argn


CÁi này đã sửa nó giúp tôi!
Djamillah
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.