Nhận xét kịch bản shell multiline - làm thế nào để làm việc này?


92

Gần đây, tôi tình cờ thấy một loại bình luận nhiều dòng mà tôi chưa từng thấy trước đây - đây là một ví dụ về kịch bản:

echo a
#
: aaa 
: ddd 
#
echo b

Điều này dường như làm việc, thậm chí vimcú pháp làm nổi bật nó. Phong cách bình luận này được gọi là gì và làm thế nào để tôi tìm thêm thông tin về nó?


1
Điều gì nếu bạn thay vì bọc mã của bạn vào chức năng để nhận xét nó? CommentedOutBlock() { echo "test"; }
Buksy

Câu trả lời:


135

Đó không phải là một bình luận nhiều dòng. #là một nhận xét dòng duy nhất. :(dấu hai chấm) hoàn toàn không phải là một nhận xét, mà là một lệnh tích hợp sẵn về cơ bản là NOP , một hoạt động null không có gì ngoại trừ trả về true, như true(và do đó đặt $?thành 0 làm hiệu ứng phụ). Tuy nhiên, vì nó là một lệnh, nó có thể chấp nhận các đối số và vì nó bỏ qua các đối số của nó, nên trong hầu hết các trường hợp, nó hoạt động bề ngoài như một nhận xét. Vấn đề chính với loại bùn này là các đối số vẫn được mở rộng, dẫn đến một loạt các hậu quả không lường trước được. Các đối số vẫn bị ảnh hưởng bởi lỗi cú pháp, chuyển hướng vẫn được thực hiện nên : > filesẽ cắt bớt file: $(dangerous command)thay thế sẽ vẫn chạy.

Các ngạc nhiên cách nhất hoàn toàn an toàn để chèn chú thích trong kịch bản shell là với #. Dính vào đó ngay cả đối với các bình luận nhiều dòng. Không bao giờ cố gắng (ab) sử dụng :cho ý kiến. Không có cơ chế nhận xét đa dòng chuyên dụng trong shell tương tự như dạng dấu gạch chéo /* */trong các Cngôn ngữ giống như ngôn ngữ.


Để hoàn thiện, nhưng không phải vì nó được khuyến nghị thực hành, tôi sẽ đề cập rằng có thể sử dụng tài liệu ở đây để thực hiện "nhận xét" nhiều dòng:

: <<'end_long_comment'
This is an abuse of the null command ':' and the here-document syntax
to achieve a "multi-line comment".  According to the POSIX spec linked 
above, if any character in the delimiter word ("end_long_comment" in 
this case) above is quoted, the here-document will not be expanded in 
any way.  This is **critical**, as failing to quote the "end_long_comment" 
will result in the problems with unintended expansions described above. 
All of this text in this here-doc goes to the standard input of :, which 
does nothing with it, hence the effect is like a comment.  There is very 
little point to doing this besides throwing people off.  Just use '#'.
end_long_comment

29
+1 rất quan trọng để giữ các dấu ngoặc đơn trên <<dòng - tắt thay thế và mở rộng.
glenn jackman

4
Và như một lưu ý thêm, việc điền vào các tập lệnh shell :cho những thứ nên là bình luận sẽ khiến mức tiêu thụ RAM / CPU tăng thêm. Nó sẽ không có ý nghĩa đối với những thứ đơn giản trên máy tính để bàn của bạn, nhưng nếu đó là thứ được thực hiện hàng trăm hoặc hàng nghìn lần một giây, bạn sẽ không làm gì cả, rất nhanh .
bahamat

3
@bahamat: nếu bạn thực hiện một cái gì đó hàng trăm hoặc hàng nghìn lần một giây, tôi hy vọng bạn sẽ không viết nó vào vỏ ... = /
7heo.tk

1
Đôi khi, sử dụng tiện ích null cho nhiều dòng văn bản có thể hữu ích. Bắt đầu nhận xét với : <<=cutviệc có thể viết POD bằng các tập lệnh shell, xem ví dụ này để biết chi tiết . Điều này làm cho nó có thể sử dụng perldoc script.sh. Tuy nhiên, nhận xét nhiều dòng được hiển thị trong câu trả lời này là thứ chắc chắn phải là một khối nhận xét (mỗi dòng bắt đầu bằng # ).
cơ bản

Đây là một cuộc thảo luận thú vị về heredocs, được sử dụng cho cả bình luận và các trường hợp sử dụng thú vị khác (thậm chí bao gồm cả việc tạo tập lệnh dynaimc): tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz

28

Đó không phải là bất kỳ phong cách bình luận. các :built-in lệnh thực hiện hoàn toàn không có gì; nó đang bị lạm dụng để bình luận ở đây.

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

25

Trong vỏ sớm, đại tràng là cách duy nhất để tạo bình luận.

Tuy nhiên, đó không phải là một nhận xét đúng, bởi vì dòng được phân tích cú pháp chính xác giống như bất kỳ lệnh nào khác được phân tích cú pháp và điều đó có thể có tác dụng phụ. Ví dụ:

: ${a:=x} # assigns the value 'x' to the variable, 'a'

: $(command) # executes 'command'

(Đôi khi dấu hai chấm chỉ được sử dụng cho mục đích gọi các tác dụng phụ đó, nhưng sau đó nó không được sử dụng như một nhận xét.)

Đôi khi thuận tiện khi sử dụng dấu hai chấm để nhận xét một phần của tập lệnh:

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'

Đây là một công cụ tiết kiệm thời gian tuyệt vời so với trước mỗi dòng #, đặc biệt nếu việc bình luận chỉ là tạm thời.


2
Phương pháp bình luận trích dẫn đơn đó không hoạt động trên bất kỳ phần nào của tập lệnh mà chính nó sử dụng dấu ngoặc đơn. Và nếu bạn đang sử dụng các trích dẫn ở bất cứ đâu gần như bạn muốn, điều đó có nghĩa là bạn sẽ có các trích dẫn hợp pháp được rắc khắp toàn bộ kịch bản. Nó đơn giản hơn nhiều khi chỉ sử dụng bất kỳ trình soạn thảo tử tế nào cho phép bạn chặn các bình luận theo dòng.
jw013

Bạn hoàn toàn đúng rằng nó sẽ chỉ hoạt động nếu không có dấu ngoặc đơn trong phần trích dẫn. Tuy nhiên, một kịch bản không cần phải có nhiều trích dẫn. Khi xem qua một vài đoạn script của tôi, tôi thấy chúng tương đối thưa thớt và nhiều cái có thể được thay thế bằng dấu ngoặc kép.
Chris FA Johnson

Việc lựa chọn trích dẫn đơn hoặc trích dẫn kép khó có thể bị ảnh hưởng bởi một điều gì đó tầm thường và không liên quan vì liệu văn bản của tập lệnh của bạn có phải là một chuỗi trích dẫn đơn hợp lệ hay không. Dấu ngoặc đơn được sử dụng để ngăn chặn việc mở rộng, trong khi dấu ngoặc kép cho phép mở rộng nhất định và yêu cầu phân tích thêm. Đây là tiêu chí thực sự để xác định nên sử dụng.
jw013

Đây là cách tốt nhất để làm điều đó. Tuyệt vời cho các khối tài liệu nhỏ. Tôi thích nó hơn /* */và ugh, đừng để tôi bắt đầu <!-- -->!
alex xám

1

Nếu bình luận của bạn ở cuối đoạn script, bạn có thể làm như thế này:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
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.