Cách để tạo ra các bình luận đa dòng trong Bash?


226

Gần đây tôi đã bắt đầu nghiên cứu kịch bản shell và tôi muốn có thể nhận xét một tập hợp các dòng trong một kịch bản shell. Ý tôi là giống như trong trường hợp của C / Java:

/* comment1
   comment2 
   comment3
*/`

Làm thế nào tôi có thể làm điều đó?


2
Bạn có thể sử dụng hàm băm như: # đây là một nhận xét.
Mohammad Tayyab

1
Tôi biết nhưng đó là một chút rắc rối cho multiline.
Enes Malik Turhan

2
Cần lưu ý rằng các câu trả lời dưới đây yêu cầu rằng :phải nằm trong cột đầu tiên (không có khoảng trắng hàng đầu) trong dòng.
ty

Câu trả lời:


394

Sử dụng : 'để mở và 'đóng.

Ví dụ:

: '
This is a
very neat comment
in bash
'

27
:( và cũng bổ sung một lượng lớn khả năng không đọc và nguồn lỗi tiềm năng. IMHO tốt hơn là chỉ sử dụng nhiều #s và không bao giờ ...
jm666

51
@ jm666 IMHO Không bao giờ là một ý tưởng tốt để sử dụng từ bao giờ khi bạn không có ý tưởng của tất cả các trường hợp sử dụng.
Mùa đông

19
để giải thích: :là tốc ký truetruekhông xử lý bất kỳ tham số nào. (trang hướng dẫn:SYNOPSIS true [ignored command line arguments]
phil294

46
Khoảng cách giữa :'rất quan trọng
becko

23
Tôi đã sửa đổi điều này một chút cho các khối mã để tôi có thể dễ dàng bật hoặc tắt mã. Thay đổi của tôi là sử dụng # 'trên dòng cuối cùng thay vì trích dẫn duy nhất. Bằng cách này, tôi có thể đặt một #dòng trên dòng đầu tiên để kích hoạt khối mã. Xóa dòng #trên đầu tiên để hủy kích hoạt mã.
JohnMudd

131

Bình luận đa dòng trong bash

: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines.  Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2 
comment3
END_COMMENT

4
Điều này hoạt động, hiện đang chấp nhận câu trả lời không (đối với tôi).
Freek

5
Có lẽ đáng lưu ý rằng đây không phải là một bình luận. Đây là một di truyền được chuyển hướng đến lệnh NOP dưới dạng một chuỗi nhiều dòng. Trích dẫn duy nhất là quan trọng để vô hiệu hóa giải quyết các biến và lệnh.
Nux

1
@Fux cần thêm không gian
mazs

Tôi đã thử nghiệm điều này trong một tập lệnh bash đơn giản chạy qua dòng shebang, #! / Bin / bash trong Debian và nó đã thất bại. Tôi đang thử từng câu trả lời trên trang này và tất cả đều thất bại cho đến khi tôi đến câu trả lời dưới đây. Vì họ thất bại, tôi bỏ phiếu cho họ và bỏ phiếu cho người thực sự chạy đúng.
PyTis

1
Bài kiểm tra tốt trong ví dụ của bạn. Việc dẫn đầu :là không cần thiết. Chỉ cần bắt đầu với <<.
wvducky

34

Tôi đang cập nhật bài đăng này dựa trên các bình luận và câu trả lời khác, vì vậy các bình luận trước ngày 22 tháng 5 năm 2020 có thể không còn được áp dụng.

Bash không cung cấp cú pháp dựng sẵn cho nhận xét nhiều dòng nhưng có những bản hack sử dụng cú pháp bash hiện có "xảy ra để làm việc ngay bây giờ".

Cá nhân tôi nghĩ đơn giản nhất (nghĩa là ít ồn ào nhất, kỳ lạ nhất, dễ gõ nhất, rõ ràng nhất) là sử dụng HEREDOC được trích dẫn, nhưng hãy làm rõ những gì bạn đang làm và sử dụng cùng một dấu HEREDOC ở mọi nơi:

<<'### BLOCK COMMENT'
line 1
line 2

line 3
line 4
### BLOCK COMMENT

Trích dẫn một lần đánh dấu HEREDOC tránh một số tác dụng phụ phân tích cú pháp vỏ, chẳng hạn như các phần phụ kỳ lạ sẽ gây ra sự cố hoặc đầu ra và thậm chí phân tích cú pháp của chính điểm đánh dấu. Vì vậy, các trích dẫn đơn cho phép bạn tự do hơn trên điểm đánh dấu nhận xét đóng. Ví dụ: phần sau sử dụng hàm băm ba loại gợi ý nhận xét nhiều dòng trong bash. Điều này sẽ sụp đổ kịch bản nếu dấu ngoặc đơn không có. Ngay cả khi bạn xóa ###, FOO{}tập lệnh sẽ bị lỗi (hoặc gây ra sự thay thế xấu được in nếu không set -e) nếu nó không dành cho các dấu ngoặc đơn:

set -e

<<'### BLOCK COMMENT'
something something ${FOO{}} something
more comment
### BLOCK COMMENT

ls

Tất nhiên bạn có thể chỉ cần sử dụng

set -e

<<'###'
something something ${FOO{}} something
more comment
###

ls

nhưng ý định của điều này chắc chắn ít rõ ràng hơn đối với một độc giả không quen thuộc với mánh khóe này.

Ngày nay, bất kỳ trình soạn thảo tốt nào cũng cho phép bạn nhấn ctrl- / hoặc tương tự, để bỏ / bình luận lựa chọn. Mọi người chắc chắn hiểu điều này:

# something something ${FOO{}} something
# more comment
# yet another line of comment

mặc dù phải thừa nhận, điều này gần như không thuận tiện như nhận xét khối ở trên nếu bạn muốn điền lại đoạn văn của mình.

Chắc chắn có những kỹ thuật khác, nhưng dường như không có cách nào "thông thường" để làm điều đó. Sẽ thật tuyệt nếu ###>###<có thể được thêm vào bash để chỉ ra bắt đầu và kết thúc khối bình luận, có vẻ như nó có thể khá đơn giản.


1
Ah, cái này dễ / đủ sạch để nhớ!
Thamme Gowda

1
Như các ghi chú trả lời trước đó, ngoài các backquote, chuỗi $ (...) cũng sẽ được mở rộng vì cả hai dạng đều là lệnh thay thế.
Perl Ancar

"Cả hai đều là hack để họ có thể phá vỡ các kịch bản trong tương lai." Bạn có thể mở rộng về điều này? Mặc dù hack về mặt ngữ nghĩa, về mặt cú pháp, chúng là hợp lệ và không nên phá vỡ trong tương lai, trừ khi bash quyết định đi điên cuồng và phá vỡ heredocs.
Perl Ancar

@perlancar Nếu chúng tôi đồng ý rằng hack là giải pháp sử dụng tính năng ngôn ngữ / lib hoàn toàn không liên quan đến vấn đề (như sử dụng heredoc để nhận xét hoặc sử dụng tham số trên lệnh không làm gì cả true), thì ngay cả khi chúng không Không có nguy cơ phá vỡ (cách tiếp cận heredoc không, nhưng phiên bản đại tràng thì có), 1) các bản hack vẫn che giấu ý định: không có dòng đầu tiên gợi ý về nhận xét đa dòng, hầu hết sẽ gãi đầu tự hỏi rằng mã đó đang làm gì; và 2) có các góc tối bất ngờ (như phải nhân đôi trích dẫn, trích dẫn dấu hiệu di truyền trong một số trường hợp nhất định, v.v.).
Oliver

@Oliver: Nếu không được trích dẫn, các biến có thể có tác dụng phụ khó chịu. Hãy tưởng tượng rằng bạn đã nhúng vào di sản của mình - tạo ra một chuỗi như ${FOO:=bar}hoặc ${FOO{}}. Cái đầu tiên có thể có tác dụng phụ để tạo và thiết lập biến FOO, cái thứ hai sẽ gây ra lỗi thay thế xấu ; cả hai hiệu ứng bạn sẽ không mong đợi từ một bình luận thực sự.
dùng1934428

24

Sau khi đọc các câu trả lời khác ở đây, tôi đã đưa ra câu trả lời dưới đây, IMHO làm cho nó thực sự rõ ràng đó là một nhận xét. Đặc biệt thích hợp cho thông tin sử dụng trong tập lệnh:

<< ////

Usage:
This script launches a spaceship to the moon. It's doing so by 
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.

////

Là một lập trình viên, chuỗi các dấu gạch chéo ngay lập tức đăng ký trong não tôi dưới dạng một nhận xét (mặc dù các dấu gạch chéo thường được sử dụng cho các nhận xét dòng).

Tất nhiên, "////"chỉ là một chuỗi; số lượng dấu gạch chéo trong tiền tố và hậu tố phải bằng nhau.


3
Tôi gần như đã bỏ lỡUsage:
RNA

Bổ sung tuyệt vời cho câu trả lời trên. Thành thật mà nói, tôi nghĩ rằng bạn có thể đã chỉnh sửa câu trả lời ở trên và thêm câu này vào, thay vì trả lời riêng.
PyTis

Có một vài câu trả lời "ở trên" (tùy theo thứ tự sắp xếp của bạn). Và, bằng cách trả lời riêng tôi muốn giải thích lý do đằng sau chuỗi tôi đã chọn.
noamtm

<< EOF ... EOF
tôi mingzhi

5

ý kiến ​​của bạn về điều này là gì?

function giveitauniquename()
{
  so this is a comment
  echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
  the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
  only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
  1, for #((
  2, this #wouldn't work either
  function giveitadifferentuniquename()
  {
    echo nestable
  }
}

xin chào, không có ý định như một câu hỏi, hơn là một câu trả lời cho câu hỏi ban đầu
Imre

IMO không tốt. Nó đòi hỏi bình luận phải được phân tích cú pháp dưới dạng mã shell, khá hạn chế.
dùng1934428

3

Đây là cách tôi thực hiện bình luận đa dòng trong bash.

Cơ chế này có hai ưu điểm mà tôi đánh giá cao. Một là ý kiến ​​có thể được lồng nhau. Khác là các khối có thể được kích hoạt bằng cách bình luận ra dòng bắt đầu.

#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A

Trong ví dụ trên, khối "B" được nhận xét, nhưng các phần của khối "A" không phải là khối "B" không được nhận xét.

Chạy ví dụ đó sẽ tạo ra kết quả này:

foo {
./example: line 5: fn: command not found
foo }
can't happen

3

Tôi đã thử câu trả lời đã chọn, nhưng thấy khi tôi chạy tập lệnh shell có nó, toàn bộ điều này đã được in ra màn hình (tương tự như cách máy tính xách tay jupyter in ra mọi thứ trong '''xx'''ngoặc kép) và cuối cùng có thông báo lỗi. Nó không làm gì cả, nhưng: đáng sợ . Sau đó, tôi nhận ra trong khi chỉnh sửa nó rằng dấu ngoặc đơn có thể trải dài trên nhiều dòng. Vì vậy, .. chỉ cần gán khối cho một biến.

x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"

ls -l
date

'

Chỉ cần không cần gán nó cho một biến, đó một tác dụng phụ mà chúng tôi không mong đợi từ một 'bình luận'. Thay thế x=bằng a : và bạn có tác dụng tương tự mà không có tác dụng phụ. Hạn chế duy nhất là bình luận sau đó không được chứa một trích dẫn. Đó là lý do tại sao tôi thích cách sử dụng một trích dẫn: Với điều này, người bình luận có thể chọn một chuỗi kết thúc phù hợp theo ý muốn.
dùng1934428

2

Giải pháp đơn giản, không nhiều thông minh:

Tạm thời chặn một phần của tập lệnh:

if false; then
    while you respect syntax a bit, please
    do write here (almost) whatever you want.
    but when you are
    done # write
fi

Một phiên bản tinh vi một chút:

time_of_debug=false # Let's set this variable at the beginning of a script

if $time_of_debug; then # in a middle of the script  
    echo I keep this code aside until there is the time of debug!
fi

-2

# Tôi thích sự lười biếng và đơn giản. Tôi sẽ sử dụng # với một cách giải quyết hài hước:

1 BÁO CHÍ:] tìm ctrl + F hoặc cmd + F hoặc bất cứ điều gì [để kích hoạt chức năng tìm

2 sử dụng biểu thức chính trong trường tìm như: (^.+)

3 thay thế bằng: # $1hoặc nếu bạn thích#$1


# Lưu ý: bạn có thể không có ba bước trong trình chỉnh sửa của mình. Trong trường hợp đó, hãy sử dụng công cụ regex trực tuyến (không thể đề xuất một công cụ ở đây vì lý do chính sách):

  1. Chọn, sao chép văn bản mọi lúc mọi nơi và dán nó vào công cụ regex trực tuyến
  2. Sử dụng (^.+)như biểu thức chính quy và #$1hoặc #\1thay thế
  3. Chọn, sao chép văn bản và dán lại nơi bạn bắt đầu

# Thưởng thức băm của bạn!


Ngày nay, nhiều biên tập viên có phím nóng ctrl+/sẽ bật hoặc tắt nhận xét, thậm chí cho nhiều dòng. Nó cũng có thể thay đổi ký tự nhận xét dựa trên ngôn ngữ bạn đang sử dụng.
ninMonkey
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.