Chân đế trong điều kiện if: tại sao tôi nhận được lỗi cú pháp mà không có khoảng trắng?


17

Tôi đang sử dụng tập lệnh dưới đây để di chuyển hai ngày trở lại khi tập lệnh chạy vào lúc bắt đầu hai ngày trong năm và cũng kiểm tra ngày đầu tiên và ngày thứ hai hàng tháng và quay lại hai ngày.

if [$month="01"] && [$day="01"];
then
    date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
if [$month="01"] && [$day="02"];
then
         date="$last_month/$yes_day/$last_year"
      fulldate="$last_month/$yes_day/$last_year"
else
   if [ $day = "01" ];
then
    date="$last_month/$yes_day/$year"
            fulldate="$year$last_month$yes_day"
else
        if [ $day = "02" ];
then
    date="$last_month/$yes_day/$year"
        fulldate="$year$last_month$yes_day"
else
    date="$month/$yes_day/$year"
        fulldate="$year$month$yes_day"
                fi
               fi
              fi
fi

Nhưng xấu của tôi là nhận được thông báo lỗi dưới đây

Etime_script.sh: line 19: [06=01]: command not found
Etime_script.sh: line 24: [06=01]: command not found

1
Các câu trả lời đã cho là đúng; bạn cần khoảng trắng sau [. Ngoài ra, xem xét các eliftuyên bố; nó sẽ giúp bạn dọn dẹp mọi thứ Ngoài ra, dấu chấm phẩy sau câu lệnh if là không cần thiết, nhưng cũng không phải là không chính xác, chỉ là lạ.
Shawn J. Goff

@ ShawnJ.Goff Chúng là cần thiết nếu bạn nối dòng tiếp theo ( if [ ... ]; then), vì vậy không có gì bất thường.
goldilocks

@goldilocks, vâng, đó là phong cách ưa thích của tôi. Lý do không bình thường là vì anh ta không làm điều đó.
Shawn J. Goff

Câu trả lời:


27

[không phải là metacharacter cũng không phải là toán tử điều khiển (thậm chí không phải là từ dành riêng; tương tự ]) vì vậy nó cần khoảng trắng xung quanh nó. Nếu không vỏ "nhìn thấy" lệnh [01=01]thay vì lệnh [với các thông số riêng biệt 01, =, 01, và ]. Mỗi toán tử và toán hạng cần phải là một đối số riêng cho [lệnh, vì vậy khoảng trắng cũng cần thiết xung quanh các toán tử.

if [ "$month" = "01" ]

[$month="01"]là một mẫu ký tự đại diện khớp với bất kỳ ký tự nào trong $monthhoặc "01. Nếu nó không phù hợp với bất cứ điều gì, nó sẽ để lại một mình.

Nếu có dấu chấm phẩy sau dấu ngoặc đóng, bạn không cần khoảng trắng trước dấu chấm phẩy, vì dấu chấm phẩy luôn là một phần của mã thông báo riêng biệt.

if [ "$month" = "01" ]; then

Điều tương tự cũng xảy ra với cú pháp ngoặc kép của bash (và ksh's và zsh).

Nhiều hơn một điều kiện

Có hai cách để kết hợp các điều kiện:

  1. trong [

  2. với [các lệnh riêng biệt kết hợp với &&hoặc||

Nhóm với dấu ngoặc có lẽ dễ dàng hơn trong [.

if [ "$month" = "01" -a "$day" = "01" ] # -a for and, -o for or

if [ "$month" = "01" ] && [ "$day" = "01" ]

Điều đầu tiên nên tránh vì nó không đáng tin cậy (ví dụ thử với month='!'). Các vấn đề với nội dung biến lạ có thể tránh được bằng cách sử dụng chuỗi an toàn (nếu có) trước tiên; hoặc bằng cách sử dụng [[/ ]]thay vì [/ ]:

if [ "01" = "$month" -a "01" = "$day" ]

Làm thế nào chúng ta có thể khớp hai điều kiện trong if, như giá trị tháng == giá trị ngày nếu [$ tháng = "01"] && [$ day = "01"]; Tôi đang mong đợi 01 && 01 đúng sau đó in các điều kiện bên dưới hoặc chuyển sang tuyên bố khác
Kumar1

@AshokSanganahalli Tôi đã mở rộng câu trả lời của mình.
Hauke ​​Laging

1
[khi -a/ -okhông được sử dụng luôn đáng tin cậy với các vỏ tuân thủ POSIX. Không có lợi thế nào trong việc sử dụng -a/-ohơn &&/||. Tôi chắc chắn sẽ không khuyến khích việc sử dụng nó. Lưu ý rằng đó [[không phải là POSIX.
Stéphane Chazelas

4

Một cách khác để viết nó:

case $month:$day in
  (01:0[12])
    date="$last_month/$yes_day/$last_year"
    fulldate="$last_month/$yes_day/$last_year"
    ;;
  (*:0[12])
    date="$last_month/$yes_day/$year"
    fulldate="$year$last_month$yes_day"
    ;;
  (*)
    date="$month/$yes_day/$year"
    fulldate="$year$month$yes_day"
esac

1
+1 cho casetuyên bố. Nếu bạn có nhiều hơn một elif, có lẽ bạn nên sử dụng case.
HalosGhost

-1

Vì vậy, đây là câu trả lời của bạn:

if [ $var1 == $var2 ];
 then
    echo "bla bla"
fi

Vì vậy, bạn phải đặt "khoảng trắng" giữa dấu ngoặc vuông và biến / giá trị.


không tôi HƯỚNG DẪN, vì như tôi đã yêu cầu kịch bản di chuyển trở lại hai ngày khi kịch bản chạy vào lúc bắt đầu hai ngày trong năm và cũng kiểm tra ngày đầu tiên và ngày thứ hai hàng tháng và chuyển hai ngày trở lại nghĩa là ở đây nếu [$ tháng = "01"] && [$ day = "01"] chúng tôi giả sử khớp với tháng "01" và ngày đầu tiên "01" đúng, chuyển sang sau đó hoặc chuyển sang điều kiện khác
Kumar1

1
@AshokSanganahalli: Tôi không biết điều này có liên quan như thế nào, nhưng điều kiện IF của bạn không hoạt động vì bạn không có "khoảng trống" giữa dấu ngoặc vuông và giá trị
Neven

@AshokSanganahalli Thường không phải là một ý tưởng tốt cho những người ở cấp độ kỹ năng của bạn để tranh chấp sửa chữa từ những người rõ ràng hiểu rõ hơn mà không ít nhất là đưa ra gợi ý thử. Nếu dự đoán của bạn là đúng thì bạn sẽ không phải hỏi ở đây, phải không?
Hauke ​​Laging

4
-1 cho các biến không được trích dẫn và sử dụng ==thay vì tiêu chuẩn =.
Stéphane Chazelas

2
Câu hỏi không được gắn thẻ bash. Toán tử so sánh đẳng thức trong lệnh aka tiêu chuẩn[test=. [nếu để kiểm tra, nó không thực hiện bất kỳ nhiệm vụ nào vì vậy không cần phải định hướng. Một số [triển khai hỗ trợ ==như một phần mở rộng so với tiêu chuẩn, nhưng không phải tất cả. Vỏ của Bourne, ash's, posh' s [s hoặc /bin/[của một số hệ thống ví dụ thì không. ==đã được thêm vào bởi ksh, tôi cho rằng tính nhất quán với cùng một toán tử trong (( ... ))cấu trúc mới của nó (có cả = và ==, nhưng nó không có tiêu chuẩn)
Stéphane Chazelas
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.