Điểm của bash Null-toán tử là gì: hung, dấu hai chấm?


13

Điểm của toán tử "null" trong tập lệnh BASH là gì? Tôi hiểu rằng nó được sử dụng như một trình giữ chỗ theo iflệnh khi bạn không có gì để nói, nhưng cần một lệnh để cho phép chương trình chạy đúng. Nhưng sử dụng tổng thể cho nó là gì? Khi nào bạn sẽ sử dụng nó? Khi nào nó có ý nghĩa để sử dụng nó?



1
Lý do bạn trích dẫn là một điều khá quan trọng. Tại sao bạn cần nhiều hơn?
terdon

Câu trả lời:


16

Đôi khi nó hữu ích để cho phép mở rộng tham số tác dụng phụ xảy ra.

Ví dụ: đặt giá trị mặc định

read -p "Enter your name: " name
: ${name:=John Doe}  # if the user entered an empty string
echo "$name"

2
Bạn có thể giải thích từng ký hiệu như thế nào dòng thứ hai hoạt động?
Ruslan

Đọc về mở rộng :lệnhtham số trong hướng dẫn bash.
glenn jackman

4
Để phác thảo những gì @glennjackman đang tham chiếu, dòng thứ hai gọi lệnh null :, và ${name:="John Doe"}sẽ được mở rộng, khiến cho việc chuyển nhượng diễn ra vì nó được đọc như là một đối số cho :. Nếu không có: shell sẽ cố chạy "John Doe" dưới dạng một lệnh hoặc giá trị $namenếu nó đã được đặt
ngay sau

13

Bạn cũng có thể sử dụng nó cho các vòng lặp vô tận:

while : ; do 
   # ....
done

4
Nhưng có lẽ while truedễ đọc hơn, bởi vì (a) nó sử dụng ít dấu câu hơn và (b) nó giống với các ngôn ngữ có nguồn gốc C hơn.
wchargein

9

Bạn có thể sử dụng nó để tạo một tệp mà không cần chạy chương trình ::

: > /path/to/file

Điều này cực kỳ nhanh hơn touch /path/to/file (vì nó không yêu cầu chạy touchchương trình) và có thể dễ mang theo hơn một chút so với chỉ đơn giản

> /path/to/file

có vẻ như hoạt động trên nhiều hệ thống. Tương tự, nó có thể được sử dụng để kiểm tra xem bạn có quyền truy cập ghi vào tệp hay không :

if { : >> /path/to/file;} 2> /dev/null
then
    echo "writeable"
else
    echo "write permission denied"
fi

mặc dù điều này, cũng có thể được thực hiện mà không có :. Hãy cẩn thận:

  • Điều này không kiểm tra xem các tập tin đã tồn tại. Nếu không, nó sẽ tạo tập tin nếu nó có quyền làm như vậy.
  • Nếu tập tin không tồn tại và tập lệnh của bạn không có quyền tạo tập tin này, điều này sẽ báo cáo quyền viết giấy bị từ chối.

(Xem câu hỏi được liên kết để biết lý do tại sao điều này đáng tin cậy hơn if [ -w /path/to/file ].)


5

Cách trở lại, trong Unix V6 và Thompson Shell, :thực sự đã được sử dụng như một phần của gototuyên bố. Theo hướng dẫn , ban đầu nó xuất hiện trong phiên bản 3 của Unix:

Toàn bộ tệp lệnh được tìm kiếm cho một dòng bắt đầu bằng a: là ký tự không trống đầu tiên, theo sau là một hoặc nhiều khoảng trống, sau đó là nhãn. Nếu một dòng như vậy được tìm thấy, goto định vị lại tệp lệnh-offset cho dòng sau khi nhãn và thoát. Điều này làm cho vỏ chuyển sang dòng có nhãn.

Ngày nay, bashnó được sử dụng như một nhà điều hành không hoạt động, mang lại thành công. Thật vậy, nếu bạn nhìn vào mã nguồn , bạn sẽ thấy cả hai true:sử dụng cùng một chức năng int colon_builtin(), bên dưới. Không có :lệnh không dựng sẵn, và /bin/truethực sự là một lệnh khá lớn cho những gì nó làm.

:có thể được sử dụng ở bất cứ đâu trueđược sử dụng, ví dụ như trong command_that_can_fail || true, mặc dù điều đó có thể gây nhầm lẫn cho những người không phải là chuyên gia. Đọc thêm về nó ở đây .


3

Bạn có thể sử dụng nó trong bài kiểm tra tích cực của một iflệnh khi bạn chỉ muốn làm điều gì đó ở phía tiêu cực. Ví dụ:

if [[ True == False ]]; then
    :
else
    echo "true <> flase"
fi

Không có :bash sẽ tạo ra một lỗi cú pháp.

Đây là một ví dụ đơn giản. Nói chung, bạn sẽ sử dụng một kỹ thuật như vậy trong mã hóa sơ bộ khi bạn chưa viết đoạn mã đó và chỉ cần một cái gì đó không tạo ra lỗi.


Câu trả lời tốt, mặc dù ban đầu có thể không rõ ràng, nhưng điều này hữu ích nhất với một lệnh thực tế trong điều kiện kiểm tra, chẳng hạn if pgrep firefox >/dev/null ; then : ; else echo "Firefox not running"; fisẽ chỉ hiển thị lỗi nếu firefox không chạy. Nói cách khác, khi bạn cần làm gì đó chỉ khi lệnh có lỗi. Theo một cách nào đó thì điều này tương đương với pgrep firefox || echo "Firefox not running", mặc dù dễ đọc hơn và cho phép nhiều lệnh hơn
Sergiy Kolodyazhnyy

0

Tôi chỉ sử dụng nó trong một tập lệnh với các lệnh SSH để giữ cho tập lệnh không bị lỗi.

Trong trường hợp này, tôi muốn xem liệu người dùng có thể kết nối với một bộ máy chủ hay không. Nếu kết nối ổn, máy chủ từ xa sẽ lặp lại OK. Nếu kết nối không thành công, SSH sẽ phản hồi với lỗi. Tuy nhiên, tôi muốn tập lệnh của mình thoát bằng 0 và không phải giá trị của lệnh SSH nếu thất bại. Vì vậy, về cơ bản, tôi bẫy lỗi SSH bằng cách OR nó ||với lệnh null :. Trông như thế này:

#!/bin/bash
for i in $(cat servers.txt); do
    echo -n "$i "; 
    ssh user@${i} 'echo OK' || :; 
done

Bằng cách đó, tôi nhận được đầu ra từ SSH nhưng không phải mã lỗi:

....
swl06 ok
swl07 ok
swl08 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
swl09 ok
swl10 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
....
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.