Bash, cảnh báo không đối số và quyết định trường hợp


110

Tôi đang học bash.

Tôi muốn thực hiện một tập lệnh đơn giản, khi không đưa ra các đối số, sẽ hiển thị một số thông báo. Và khi tôi đưa ra các numers dưới dạng đối số, tùy thuộc vào giá trị, nó thực hiện điều này hay cách khác.

Tôi cũng muốn biết các gợi ý về hướng dẫn sử dụng trực tuyến tốt nhất cho người mới bắt đầu trong bash

Cảm ơn

Câu trả lời:


176
if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 0
fi

case "$1" in
    1) echo 'you gave 1' ;;
    *) echo 'you gave something else' ;;
esac

Các chi tiết Bash-Scripting Guide là khá tốt. Bất chấp cái tên của nó, nó xử lý những điều cơ bản.


RE: "thoát 0". Tôi không biết liệu việc thoát khỏi kịch bản có phải là điều anh ấy nghĩ đến hay không. Nhưng có, đó là một hướng dẫn tuyệt vời.
Trampas Kirk

Tôi đã hiểu "và" là "nếu không", giả định rằng thông báo sẽ là một số văn bản trợ giúp. Nhưng tôi chắc chắn rằng Werner có thể tìm ra những gì dòng nào và liệu anh ta muốn nó :)
Thomas

cảm ơn, tất nhiên! và điều cuối cùng, làm cách nào để tôi có thể tắt các thông báo lỗi ib script, vì vậy chúng không được hiển thị cho shell?
Mở đường vào

Ý bạn là lỗi xảy ra từ một chương trình cụ thể mà bạn đang gọi? Bạn có thể đặt > /dev/nullvà / hoặc 2> /dev/nullsau đó gửi các luồng lỗi chuẩn và / hoặc chuẩn của nó vào quên lãng.
Thomas

4
Nếu bạn coi một đối số bị thiếu là điều gì đó không tốt (chẳng hạn như tập lệnh sau đó không thể thực hiện thành công), hãy trả về giá trị khác 0 ( exit 1). Có những quy ước khác về mã trả lại / mã thoát mà bạn có thể tìm thấy trực tuyến nhanh chóng, nhưng điểm quan trọng là nó không được bằng 0, điều này cho thấy sự thành công.
Felix

25

Nếu chỉ quan tâm đến việc bỏ qua nếu thiếu một đối số cụ thể, thì Thay thế tham số là rất tốt:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

11

Thí dụ

 if [ -z "$*" ]; then echo "No args"; fi

Kết quả

No args

Chi tiết

-z là toán tử một ngôi cho độ dài của chuỗi bằng không. $*là tất cả các đối số. Các dấu ngoặc kép là để an toàn và đóng gói nhiều đối số nếu có.

Sử dụng man bashvà tìm kiếm ( / key) cho "một ngôi" để biết thêm các toán tử như thế này.


7
Một vấn đề (nhỏ) với điều này là nó không phân biệt giữa chuyển không có đối số và chuyển một chuỗi rỗng làm đối số. Điều đó có thể quan trọng trong một số ngữ cảnh. Sử dụng [$ # -eq 0] người ta có thể xử lý đúng cả hai trường hợp.
Idelic

1
Ah, sự tinh tế của (ba) lập trình sh ... Đây là lý do tại sao tôi ghét nó.
Thomas,

1
nghĩ -znhư mizzing
Ray Foss

4

Cũ nhưng tôi có lý do để làm lại câu trả lời bây giờ nhờ một số nhầm lẫn trước đó:

if [[ $1 == "" ]] #Where "$1" is the positional argument you want to validate 

 then
 echo "something"
 exit 0

fi

Điều này sẽ lặp lại "Something" nếu không có đối số vị trí $ 1. Tuy nhiên, nó không xác thực rằng $ 1 chứa thông tin cụ thể.


$#rõ ràng là số nguyên của số đối số; nó sẽ là "0", và bạn sẽ lặp lại "something" ngay cả khi không có đối số nào, hoặc nó sẽ là một số dương nào đó và bạn sẽ echo "something" một cách chính xác. Nhưng bản thân séc sẽ không bao giờ thực hiện bất cứ điều gì, bất kể đầu vào hoặc thiếu đầu vào mà bạn sử dụng - nó sẽ luôn báo cáo $#có chứa một giá trị. Vì vậy, điều này là hoàn toàn sai và sẽ không bao giờ hoạt động như đã tuyên bố.
eschwartz

Bạn có hoàn toàn tích cực về điều đó? Tôi có một số tập lệnh hoạt động như dự định bằng cách sử dụng định dạng chính xác này. Sau khi đọc phản hồi của bạn, tôi thậm chí đã kiểm tra lại cả hai trận đấu và thiếu nó. $ # sẽ không chứa giá trị nếu không được chỉ định, nếu không có đối số vị trí để khớp với giá trị từng có # trong kịch bản của bạn. Không có nghĩa lý gì tại sao bash sẽ giả định một giá trị trong một đối số vị trí không có ở đó.
Ryan Smith,

Hãy thử echo $#làm nội dung của tập lệnh /tmp/test.sh, sau đó chạy nó trong / bin / bash cũng như / bin / sh (hoặc / bin / dash và bất kỳ triển khai shell nào khác mà bạn có sẵn. /tmp/test.shSẽ lặp lại "0" tới bảng điều khiển, theo ý muốn /bin/dash /tmp/test.sh. Mặt khác, /tmp/test.sh foosẽ lặp lại "1" và /tmp/test.sh first secondsẽ lặp lại "2".
eschwartz

Theo như man bash, trong phần "Tham số Đặc biệt", "Trình bao xử lý một số tham số đặc biệt. Các tham số này chỉ có thể được tham chiếu; không được phép gán cho chúng.", Và "# Mở rộng thành số tham số vị trí ở dạng thập phân." Nó cũng được POSIX ủy quyền như được mô tả trong pubs.opengroup.org/onlinepubs/9699919799/utilities/…
eschwartz Ngày

Xin lỗi có vẻ như đã có thông tin sai lệch! Ý tôi là # như một trình giữ chỗ cho đối số vị trí cụ thể (ví dụ: $ 2 nếu bạn muốn nói đến đối số thứ hai) chứ không phải theo nghĩa đen $ #. Sau khi xem xét phần trên của bạn, bạn hoàn toàn chính xác, $ # theo nghĩa đen sẽ luôn giải quyết số đối số. Xin lỗi vì sự nhầm lẫn.
Ryan Smith
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.