Cara membuat komentar multiline di Bash?

226

Saya baru-baru ini mulai mempelajari skrip shell dan saya ingin dapat mengomentari serangkaian baris dalam skrip shell. Maksud saya seperti dalam kasus C / Java:

/* comment1
   comment2 
   comment3
*/`

Bagaimana saya bisa melakukan itu?

Enes Malik Turhan
sumber
2
Anda dapat menggunakan hash seperti: #ini adalah komentar.
Mohammad Tayyab
1
Saya tahu tetapi sedikit merepotkan untuk multiline.
Enes Malik Turhan
2
Perlu dicatat bahwa jawaban di bawah ini mensyaratkan bahwa :berada di kolom pertama (tidak ada spasi utama) di baris.
ty

Jawaban:

394

Gunakan : 'untuk membuka dan 'menutup.

Sebagai contoh:

: '
This is a
very neat comment
in bash
'
Vegas
sumber
27
:( dan juga menambahkan sejumlah besar un-read-kemampuan dan sumber bug potensial. IMHO lebih baik hanya menggunakan beberapa #s dan tidak pernah ini ...
jm666
51
@ jm666 IMHO Tidak pernah ada ide bagus untuk menggunakan kata tidak pernah ketika Anda tidak tahu semua kasus penggunaan.
Musim dingin
19
untuk menjelaskan: :adalah singkatan untuk truedan truetidak memproses parameter apa pun. (halaman manual:SYNOPSIS true [ignored command line arguments]
phil294
46
Ruang antara :dan 'penting
becko
23
Saya memodifikasi ini sedikit untuk blok kode sehingga saya dapat dengan mudah mengaktifkan atau menonaktifkan kode. Perubahan saya adalah menggunakan # 'pada baris terakhir dan bukan pada kutipan tunggal. Dengan cara ini saya dapat meletakkan satu #di baris pertama untuk mengaktifkan blok kode. Hapus #baris pertama untuk menonaktifkan kode.
JohnMudd
131

Komentar multiline dalam 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
David Okwii
sumber
4
Ini berfungsi, jawaban yang diterima saat ini tidak (untuk saya).
Freek
5
Mungkin perlu dicatat bahwa ini bukan komentar per se. Ini adalah heredoc yang dialihkan ke perintah NOP sebagai string multi-line. Kutipan tunggal penting untuk menonaktifkan penyelesaian variabel dan perintah.
Nux
1
@Freek perlu menambahkan ruang
mazs
Saya menguji ini dalam skrip bash sederhana yang berjalan melalui baris shebang itu, #! / Bin / bash di Debian dan gagal. Saya mencoba setiap jawaban pada halaman ini, dan semuanya gagal sampai saya mendapatkan jawaban di bawah. Karena mereka gagal, saya memilih mereka, dan memilih yang benar-benar berjalan dengan baik.
PyTis
1
Tes yang baik dalam contoh Anda. Pemimpin :tidak perlu. Mulai saja dengan <<.
wisbucky
34

Saya memperbarui posting ini berdasarkan komentar dan jawaban lain, jadi komentar sebelum 22 Mei 2020 mungkin tidak berlaku lagi.

Bash tidak menyediakan sintaks bawaan untuk komentar multi-baris tetapi ada hack menggunakan sintaks bash yang ada yang "kebetulan bekerja sekarang".

Secara pribadi saya pikir yang paling sederhana (yaitu paling tidak berisik, paling aneh, paling mudah untuk mengetik, paling eksplisit) adalah dengan menggunakan HEREDOC yang dikutip, tetapi jelaskan apa yang Anda lakukan, dan gunakan penanda HEREDOC yang sama di mana-mana:

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

line 3
line 4
### BLOCK COMMENT

Mengutip penanda HEREDOC tunggal menghindari beberapa efek samping penguraian shell, seperti penggantian yang aneh yang akan menyebabkan kerusakan atau keluaran, dan bahkan penguraian penanda itu sendiri. Jadi tanda kutip tunggal memberi Anda lebih banyak kebebasan pada penanda komentar buka-tutup. Sebagai contoh, berikut ini menggunakan hash tiga jenis saran multi-line di bash. Ini akan merusak skrip jika tanda kutip tunggal tidak ada. Bahkan jika Anda menghapus ###, FOO{}skrip tersebut akan macet (atau menyebabkan substitusi buruk dicetak jika tidak set -e) jika bukan karena tanda kutip tunggal:

set -e

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

ls

Anda tentu saja bisa menggunakan

set -e

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

ls

tetapi niat ini jelas kurang jelas bagi pembaca yang tidak terbiasa dengan tipuan ini.

Saat ini setiap editor yang baik memungkinkan Anda untuk menekan ctrl- / atau yang serupa, untuk membatalkan komentar. Semua orang pasti mengerti ini:

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

walaupun harus diakui, ini hampir tidak nyaman seperti komentar blok di atas jika Anda ingin mengisi ulang paragraf Anda.

Pasti ada teknik lain, tetapi sepertinya tidak ada cara "konvensional" untuk melakukannya. Akan lebih baik jika ###>dan ###<dapat ditambahkan ke bash untuk menunjukkan awal dan akhir dari blok komentar, sepertinya itu bisa sangat mudah.

Oliver
sumber
1
Ah, ini mudah / cukup bersih untuk diingat!
Thamme Gowda
1
Seperti yang dicatat oleh jawaban sebelumnya, selain dari backquotes, urutan $ (...) juga akan diperluas karena kedua formulir adalah substitusi perintah.
Perl Ancar
"Keduanya adalah hack sehingga mereka dapat memecahkan skrip di masa depan." Bisakah Anda mengembangkan ini? Meskipun hack semantik, sintaksis mereka valid dan tidak boleh rusak di masa depan, kecuali bash memutuskan untuk mengamuk dan merusak heredocs.
Perl Ancar
@perlancar Jika kami setuju bahwa peretasan adalah solusi yang menggunakan fitur bahasa / lib yang sama sekali tidak terkait dengan masalah (seperti menggunakan heredoc untuk komentar, atau menggunakan parameter pada perintah do-nothing like true), maka bahkan jika mereka tidak 't mengambil risiko melanggar (pendekatan heredoc tidak, tetapi versi usus besar tidak), 1) peretasan masih mengaburkan niat: tanpa baris pertama mengisyaratkan tentang komentar multiline, sebagian besar akan menggaruk-garuk kepala mereka bertanya-tanya apa yang dilakukan kode itu; dan 2) memiliki sudut gelap yang tidak terduga (seperti harus menggandakan penawaran, mengutip penanda heredoc dalam kasus-kasus tertentu, dll).
Oliver
@Liver: Jika tidak dikutip, variabel dapat memiliki efek samping yang buruk. Bayangkan Anda telah menyematkan heredoc Anda - sebuah string seperti ${FOO:=bar}atau ${FOO{}}. Yang pertama mungkin memiliki efek samping untuk membuat dan mengatur variabel FOO, yang kedua akan meningkatkan kesalahan substitusi yang buruk ; kedua efek yang tidak Anda harapkan dari komentar nyata.
user1934428
24

Setelah membaca jawaban lain di sini saya datang dengan di bawah ini, yang IMHO membuatnya sangat jelas itu adalah komentar. Sangat cocok untuk info penggunaan dalam skrip:

<< ////

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.

////

Sebagai seorang programmer, urutan garis miring segera mendaftar di otak saya sebagai komentar (meskipun garis miring biasanya digunakan untuk komentar garis).

Tentu saja, "////"hanya string; jumlah garis miring pada awalan dan akhiran harus sama.

noamtm
sumber
3
Saya hampir melewatkanUsage:
RNA
Tambahan yang bagus untuk jawaban di atas. Sejujurnya, saya pikir Anda bisa mengedit jawaban di atas, dan menambahkan ini, daripada menjawab secara terpisah.
PyTis
Ada beberapa jawaban "di atas" (tergantung pada urutan pesanan Anda). Dan, dengan menjawab secara terpisah saya ingin menjelaskan alasan di balik string yang saya pilih.
noamtm
<< EOF ... EOF
l mingzhi
5

apa pendapatmu tentang ini?

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
  }
}
Imre
sumber
halo, tidak dimaksudkan sebagai pertanyaan, bukan jawaban untuk pertanyaan asli
Imre
IMO tidak bagus. Ini membutuhkan komentar untuk dapat diuraikan sebagai kode shell, yang cukup ketat.
user1934428
3

Inilah cara saya melakukan komentar multiline di bash.

Mekanisme ini memiliki dua keunggulan yang saya hargai. Salah satunya adalah bahwa komentar dapat disarangkan. Yang lain adalah bahwa blok dapat diaktifkan hanya dengan mengomentari garis awal.

#!/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

Dalam contoh di atas, blok "B" dikomentari, tetapi bagian-bagian dari blok "A" yang bukan blok "B" tidak dikomentari.

Menjalankan contoh itu akan menghasilkan output ini:

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

Saya mencoba jawaban yang dipilih, tetapi menemukan ketika saya menjalankan skrip shell memilikinya, semuanya dicetak ke layar (mirip dengan bagaimana notebook jupyter mencetak semuanya dalam '''xx'''tanda kutip) dan ada pesan kesalahan pada akhirnya. Itu tidak melakukan apa-apa, tetapi: menakutkan . Kemudian saya menyadari ketika mengeditnya bahwa tanda kutip tunggal dapat menjangkau beberapa baris. Jadi .. mari kita tetapkan saja blok ke variabel.

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

ls -l
date

'
Nikhil VJ
sumber
Hanya tidak perlu menetapkannya ke variabel, yang merupakan efek samping yang tidak kita harapkan dari 'komentar'. Ganti x=dengan a : dan Anda memiliki efek yang sama tanpa efek samping. Satu-satunya kelemahan adalah bahwa komentar maka tidak boleh mengandung satu kutipan. Itu sebabnya saya lebih suka menggunakan heredoc yang dikutip: Dengan ini, komentator dapat memilih string terminasi yang sesuai keinginannya.
user1934428
2

Solusi sederhana, tidak terlalu pintar:

Memblokir sementara bagian skrip:

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

Versi yang agak canggih:

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
xerostomus
sumber
-2

# Saya suka kemalasan dan kesederhanaan. Saya akan menggunakan # dengan solusi lucu:

1 PRESS:] temukan ctrl + F atau cmd + F atau apa pun [untuk memicu fungsi temukan

2 gunakan regex di bidang temukan seperti: (^.+)

3 ganti dengan: # $1atau jika Anda suka#$1


# Catatan: Anda mungkin tidak memiliki tiga langkah di editor Anda. Dalam hal itu gunakan alat regex online (tidak dapat menyarankan satu di sini karena alasan kebijakan):

  1. Pilih, salin teks di manapun Anda berada dan tempel di alat regex online
  2. Gunakan (^.+)sebagai regex dan #$1atau #\1sebagai pola substitusi
  3. Pilih, salin teks dan tempel kembali ke tempat Anda memulai

# Nikmati hash Anda!

AMDP
sumber
Saat ini banyak editor memiliki hotkey ctrl+/yang akan mengaktifkan atau menonaktifkan komentar, bahkan untuk beberapa baris. Itu juga dapat mengubah karakter komentar berdasarkan bahasa yang Anda gunakan.
ninMonkey