Cách thực hiện thao tác HOẶC logic trong kịch bản lệnh shell


571

Tôi đang cố gắng thực hiện kiểm tra điều kiện đơn giản, nhưng dường như nó không hoạt động.

Nếu $#bằng 0hoặc lớn hơn 1thì nói xin chào.

Tôi đã thử cú pháp sau đây nhưng không thành công:

if [ "$#" == 0 -o "$#" > 1 ] ; then
 echo "hello"
fi

if [ "$#" == 0 ] || [ "$#" > 1 ] ; then
 echo "hello"
fi

Cả hai đều làm việc cho tôi. Bạn đã chỉ định một vỏ trong dòng shebang ?
Jason McCreary

1
@Jason Tôi thực sự đã quên dòng shebang, nhưng tôi đã thử nó với nó ngay bây giờ và nó không hoạt động.
Dâu tây

25
>là chuyển hướng đầu ra trong sh / bash. Bây giờ bạn có thể có một tập tin được đặt tên 1.
mark4o

Để biết thông tin về so sánh Bash, xin vui lòng xem câu trả lời của tôi cho các câu hỏi trước đâyđây . Để biết thêm thông tin về dấu ngoặc, dấu ngoặc kép và dấu ngoặc kép, xem câu trả lời của tôi ở đây .
Tạm dừng cho đến khi có thông báo mới.

Nó không hoạt động khiến bạn gõ nhầm máy tính: sử dụng "$ #" == "0" hoặc $ # -eq 0
ETech

Câu trả lời:


987

Điều này sẽ làm việc:

#!/bin/bash

if [ "$#" -eq 0 ] || [ "$#" -gt 1 ] ; then
    echo "hello"
fi

Tôi không chắc liệu điều này có khác với các shell khác hay không nhưng nếu bạn muốn sử dụng <,>, bạn cần đặt chúng trong dấu ngoặc kép như vậy:

if (("$#" > 1))
 ...

2
Tôi không chắc nó có khác trong vỏ khác không nhưng trong bash, nếu bạn muốn sử dụng> hoặc <, bạn phải đặt chúng trong ngoặc kép như vậy: (("$ a" <"$ b"))
Mã hóa Quận

1
@Doug: Không phải là unix không sử dụng chúng, đó là bash và tất cả các shell khác mà tôi biết sử dụng chúng để chuyển hướng đầu vào / đầu ra.
Cascabel

56

Mã này hoạt động với tôi:

#!/bin/sh

argc=$#
echo $argc
if [ $argc -eq 0 -o $argc -eq 1 ]; then
  echo "foo"
else
  echo "bar"
fi

Tôi không nghĩ sh hỗ trợ "==". Sử dụng "=" để so sánh chuỗi và -eq để so sánh ints.

man test

để biết thêm chi tiết.


Tùy chọn cho lớn hơn là gì? Tài liệu chính thức cho tihs ở đâu?
Dâu tây

3
Nên -gtcho lớn hơn. Hoặc chỉ cần thay thế tất cả bằng [ $# -ne 1 ].
mark4o

Lớn hơn là -gt, xem câu trả lời của tôi. Các tài liệu chính thức là trong thử nghiệm người đàn ông như jbremnant đã chỉ ra.
Mã hóa quận

Cũng giống như một fyi cho người khác, tùy thuộc vào vỏ của bạn, hầu hết hỗ trợ == (bây giờ là một ngày) với tư cách là toán tử so sánh, tuy nhiên hầu hết thời gian nó giống như toán tử =. Tôi sẽ tưởng tượng rằng nếu bạn đang sử dụng -gt và -ne để so sánh thì sẽ tốt hơn nếu sử dụng -eq cho == hoặc = để giữ cho kiểu kịch bản của bạn nhất quán. Chúc mừng Bashing :)
jkdba

34

Nếu bạn đang sử dụng trạng thái mã thoát bash $? là biến, tốt hơn là làm điều này:

if [ $? -eq 4 -o $? -eq 8 ] ; then  
   echo "..."
fi

Bởi vì nếu bạn làm:

if [ $? -eq 4 ] || [ $? -eq 8 ] ; then  

Các phần bên trái của HOẶC làm thay đổi các $? biến, vì thế phần bên phải của HOẶC không có bản gốc $? giá trị.


2
$ # trả về số lượng đối số được truyền cho tập lệnh. Hữu ích cho việc kiểm tra sử dụng chính xác. Có vẻ như người hỏi đang sử dụng mã thoát.
Centimane

27

Đôi khi bạn cần sử dụng dấu ngoặc kép, nếu không, bạn sẽ gặp lỗi như quá nhiều đối số

if [[ $OUTMERGE == *"fatal"* ]] || [[ $OUTMERGE == *"Aborting"* ]]
  then
fi

1
Điều này rất hữu ích vì đó là điều duy nhất ở đây mà tôi thấy hiển thị một ví dụ về so sánh không nguyên, có một chút khác biệt về cú pháp.
Christopher Hunter

13

Nếu một tập lệnh bash

If [[ $input -gt number  ||  $input  -lt number  ]]
then 
    echo .........
else
    echo .........

fi

exit

7

bạn đã thử một cái gì đó như thế này:

if [ $# -eq 0 ] || [ $# -gt 1 ] 
then
 echo "$#"
fi

Vâng tôi có. Đó echolà xin chào ngay cả khi tôi có một đối số duy nhất.
Strawberry

Thứ hai $#có thể là giá trị trả về của thử nghiệm đầu tiên?
luckydonald

5

Từ tài liệu tham khảo Bash → 3.4.2 Các thông số đặc biệt

#
($ #) Mở rộng đến số lượng tham số vị trí theo số thập phân.

Do đó, $#sẽ luôn là 0 hoặc số nguyên lớn hơn.

Vì vậy, nếu bạn muốn làm điều gì đó bất cứ khi nào $#một trong hai là 0 hoặc lớn hơn 1, bạn chỉ cần phải kiểm tra xem $#là hay không là 1:

[ $# -eq 1 ] && echo "1 positional param" || echo "0 or more than 1"

Này sử dụng cú pháp:

[ condition ] && {things if true} || {things if false}

trong bash bạn có thể làm một cái gì đó như:[[ -n $A ]] && echo 1 || echo 2
premek.v

@ premek.v cảm ơn đã bình luận. Câu trả lời của tôi đã được giải thích rất tệ, tôi chỉ chỉnh sửa nó với hy vọng nó làm sáng tỏ hơn cho chủ đề.
fedorqui 'SO ngừng làm hại'

1

Và ở Bash

 line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
 vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
 echo "-------->"${line1}
    if [ -z $line1 ] && [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
   fi

HOẶC ở Bash

line1=`tail -3 /opt/Scripts/wowzaDataSync.log | grep "AmazonHttpClient" | head -1`
vpid=`ps -ef|  grep wowzaDataSync | grep -v grep  | awk '{print $2}'`
echo "-------->"${line1}
   if [ -z $line1 ] || [ ! -z $vpid ]
    then
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Process Is Working Fine"
    else
            echo `date --date "NOW" +%Y-%m-%d` `date --date "NOW" +%H:%M:%S` :: 
            "Prcess Hanging Due To Exception With PID :"${pid}
  fi
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.