Hợp lý VÀ trong một kịch bản bash


10

Tôi có một iftập lệnh bash của mình phải kiểm tra xem EITHER của 2 tệp có tồn tại hay không, nếu chúng không tồn tại thì nó sẽ khớp với tiếng vang.

Mã tôi có:

if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Nhưng điều này dường như không hoạt động vì một số lý do.

Tôi chắc chắn 110% rằng 2 tập tin này không tồn tại. Tôi không nhận được bất kỳ lỗi nào, nó chỉ không nhập if.

Tôi chưa quen với bash scripting nên tôi không chắc điều gì có thể sai.


Tôi không nghĩ bất kỳ câu trả lời nào được đăng thực sự giải quyết câu hỏi. Điều gì xảy ra khi bạn thử các bài kiểm tra cá nhân? Làm [[ ! -f /etc/.../... ]]; echo $?cho mỗi.
jw013

Cảnh báo : [[ -f xxx ]]trả về true nếu xxx tồn tại là tệp thông thường (hoặc liên kết tượng trưng đến tệp thông thường). Nó sẽ trả về false nếu nó không tồn tại hoặc nếu nó không thể biết nó tồn tại hay không hoặc nó tồn tại nhưng không phải là một tệp thông thường (thư mục, đường ống, thiết bị, ổ cắm ...) hoặc nếu đó là một liên kết tượng trưng đối với một tệp không tồn tại hoặc nó không thể biết nó tồn tại hay không hoặc không phải là một tệp thông thường ... [[ -e $file ]] || [[ -L $file ]]gần với thử nghiệm tồn tại hơn. ls -d -- "$file" > /dev/null 2>&1thậm chí còn gần hơn Và như một quy luật, loại thử nghiệm này dẫn đến điều kiện chủng tộc. Có lẽ có một cách khác.
Stéphane Chazelas

Câu trả lời:


12

Nếu bạn muốn hoặc sau đó bạn muốn OR, không AND.

if [[ ! -f /etc/benchmarking/code ]] || [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
  • Điều này sẽ phù hợp nếu một hoặc cả hai tập tin bị thiếu.
  • Mã của bạn sẽ chỉ in matchnếu cả hai không tồn tại.

Nhưng , bạn nói:

Tôi chắc chắn 110% rằng 2 tập tin này không tồn tại. Tôi không nhận được bất kỳ lỗi nào, nó chỉ không nhập nếu.

Vì vậy, tuyên bố của bạn mâu thuẫn với chính nó. Ít nhất một trong những tệp đó phải tồn tại, nếu bạn đang chạy mã đó .

Nếu bạn muốn xem cách ifđánh giá của bạn , hãy chạy nó với -x.

#!/bin/bash -x
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi

Sau đó, bạn sẽ thấy việc thực hiện.

$ ./test.sh
+ [[ ! -f /etc/benchmarking/code ]]
+ [[ ! -f /etc/benchmarking/code.class ]]
+ echo match
match
$ 

Tôi muốn nó lặp lại "khớp" nếu không có tệp nào tồn tại, nếu một tệp tồn tại thì nó không in trùng khớp. Tôi sẽ thử nó với -x
Peppercat101

Trong trường hợp đó, mã gốc của bạn sẽ ổn. Và thực sự nó làm việc cho tôi.
bahamat

3

Không nên như thế này sao? A là một tập tin hoặc B là một tập tin, sau đó blabla.

if [[ -f /etc/benchmarking/code ]] || [[ -f /etc/benchmarking/code.class ]]; 
then  
  echo "match"
fi

3

Điều này cũng có thể làm việc cho những gì bạn đang cố gắng làm. Dấu ngoặc đơn không được sử dụng phổ biến ngày nay với bash, nhưng đây vẫn là một tùy chọn. Sử dụng '-o' thực sự là một thao tác "HOẶC" và "!" phủ nhận điều kiện.

var=/etc/benchmarking/code
[ ! -f ${var} -o -f {var}.class ] && echo "match"

Đừng bao giờ sử dụng [trong bash. Bên cạnh đó, tôi không thấy cách này trả lời câu hỏi.
jw013

[ ! -f ${var} -a ! -f {var}.class ] && echo "match"nó nên Nhiệm vụ là: nếu họ (cả hai) không tồn tại thì nên echo match.
hschou

0

Mã của bạn đáp ứng yêu cầu của bạn: nó sẽ in matchvới điều kiện là nó không thể tìm thấy một trong hai tệp.

Do đó, lý do matchkhông được in là ở nơi khác. Bạn nên xác nhận rằng khối mã đang được đạt tới, điều bạn có thể làm bằng cách bao quanh nó với một vài thông báo gỡ lỗi. Ví dụ, như thế này:

echo '@ About to enter if...fi block'
if [[ ! -f /etc/benchmarking/code ]] && [[ ! -f /etc/benchmarking/code.class ]]; then
 echo "match"
fi
echo '@ Finished if...fi block'

Sở thích thông thường của tôi là gỡ lỗi các tin nhắn để đi đến stderr để tránh làm gián đoạn luồng dữ liệu đến thiết bị xuất chuẩn , nhưng tôi đã tránh điều đó ở đây vì bạn nói bạn là người mới bắt đầu. Đây là một ví dụ cho thấy cách bạn có thể viết vào thiết bị xuất chuẩn :

echo '@ About to enter if...fi block' >&2
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.