it-swarm.com.de

Kommentieren in einem Bash-Skript

Wie kann ich die einzelnen Zeilen der folgenden Zeilen eines Skripts kommentieren?

   cat ${MYSQLDUMP} | \
   sed '1d' | \
   tr ",;" "\n" | \
   sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
   sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
   sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
   tr "\n" "," | \
   sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \
   sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

Wenn ich versuche, einen Kommentar hinzuzufügen, sagen Sie " cat $ {MYSQLDUMP} |\#Output MYSQLDUMP File ", erhalte ich:

Löschen: nicht gefunden

Kann man hier oder wegen "| \" einen Kommentar abgeben?

130
BassKozz

Dies hat zwar einen gewissen Aufwand, aber technisch beantwortet es Ihre Frage:

echo abc `#Put your comment here` \
     def `#Another chance for a comment` \
     xyz, etc.

Und speziell für Pipelines gibt es eine saubere Lösung ohne zusätzlichen Aufwand:

echo abc |        # Normal comment OK here
     tr a-z A-Z | # Another normal comment OK here
     sort |       # The pipelines are automatically continued
     uniq         # Final comment

Siehe Stapelüberlauf-Frage So setzen Sie einen Zeilenkommentar für einen mehrzeiligen Befehl.

164
DigitalRoss

Der nachfolgende Backslash muss das letzte Zeichen in der Zeile sein, damit er als Fortsetzungsbefehl interpretiert werden kann. Danach sind keine Kommentare oder gar Leerzeichen erlaubt.

Sie sollten Kommentarzeilen zwischen Ihren Befehlen einfügen können

# output MYSQLDUMP file
cat ${MYSQLDUMP} | \
# simplify the line
sed '/created_at/d' | \
# create some newlines
tr ",;" "\n" | \
# use some sed magic
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
# more magic
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
# even more magic
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
tr "\n" "," | \
# I hate phone numbers in my output
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \ 
# one more sed call and then send it to the CSV file
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}
34
mob

Wie DigitalRoss hervorgehoben hat, ist der nachfolgende Backslash nicht erforderlich, wenn die Zeile in | endet. Und Sie können Kommentare in eine Zeile einfügen, die einem | folgt:

 cat ${MYSQLDUMP} |         # Output MYSQLDUMP file
 sed '1d' |                 # skip the top line
 tr ",;" "\n" | 
 sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' |
 sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' |
 sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' |
 tr "\n" "," |
 sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' |   # hate phone numbers
 sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}
5
mob

Der Backslash entgeht dem # und interpretiert es als wörtliches Zeichen anstelle eines Kommentarzeichens.

4
tobiasvl

$IFS Kommentar hacks

Dieser Hack verwendet parameter extension on $IFS, um Wörter in Befehlen zu trennen:

$ echo foo${IFS}bar
foo bar

Ähnlich:

$ echo foo${IFS#comment}bar
foo bar

Auf diese Weise können Sie einen Kommentar in eine Befehlszeile mit der Einstellung eingeben:

$ echo foo${IFS# Comment here} \
> bar
foo bar

der Kommentar muss jedoch vor der Fortsetzung von \ erfolgen.

Beachten Sie, dass die Parametererweiterung im Kommentar ausgeführt wird:

$ ls file
ls: cannot access 'file': No such file or directory
$ echo foo${IFS# This command will create file: $(touch file)}bar
foo bar
$ ls file
file

Seltene Ausnahme

Der einzige seltene Fall, dass dies fehlschlägt, ist, wenn $IFS zuvor mit dem genauen Text begonnen wurde, der über die Erweiterung (dh nach dem #-Zeichen) entfernt wird:

$ IFS=x
$ echo foo${IFS#y}bar
foo bar
$ echo foo${IFS#x}bar
foobar

Beachten Sie, dass die letzte Variable foobar kein Leerzeichen enthält, um das Problem darzustellen.

Da $IFS standardmäßig nur Leerzeichen enthält, ist es extrem unwahrscheinlich, dass Sie auf dieses Problem stoßen.


Dank an @ pjhsches Kommentar der diese Antwort ausgelöst hat. 

3
Tom Hale

Zusätzlich zu den Beispielen von DigitalRoss gibt es hier ein weiteres Formular, das Sie verwenden können, wenn Sie $() anstelle von Backticks _`_ bevorzugen.

_echo abc $(: comment) \
     def $(: comment) \
     xyz
_

Natürlich können Sie die Doppelpunktsyntax auch bei Backticks verwenden:

_echo abc `: comment` \
     def `: comment` \
     xyz
_

Zusätzliche Bemerkungen

Der Grund, warum $(#comment) nicht funktioniert, liegt darin, dass _#_ den Rest der Zeile als Kommentar behandelt, einschließlich der schließenden Klammern: _comment)_. Die Klammern werden also niemals geschlossen.

Backticks werden anders analysiert und erkennen das schließende Backtick auch nach einem _#_.

1
wisbucky

Hier ist ein Bash-Skript, das die Ideen und Idiome mehrerer vorangegangener Kommentare kombiniert, um Beispiele mit Inline-Kommentaren mit der allgemeinen Form ${__+ <comment text>} bereitzustellen. 

Im Speziellen

  • <comment text> kann mehrzeilig sein 
  • <comment text> ist nicht um Parameter erweitert
  • es werden keine Unterprozesse erzeugt (Kommentare sind also effizient)

Es gibt eine Einschränkung für <comment text>, nämlich unausgeglichene geschweifte Klammern '}' und Klammern ')' müssen geschützt werden (d. H. '\}' und '\)').

Es gibt eine Anforderung für die lokale Bash-Umgebung:

  • der Parametername __ muss nicht gesetzt sein

Jeder andere syntaktisch gültige bash-Parametername wird anstelle von __ verwendet, vorausgesetzt, der Name hat keinen festgelegten Wert.

Ein Beispielskript folgt

# provide bash inline comments having the form
#     <code> ${__+ <comment>} <code> 
#     <code> ${__+ <multiline
#                   comment>} <code>

# utility routines that obviate "useless use of cat"
function bashcat { printf '%s\n' "$(</dev/stdin)"; }
function scat { 1>&2 bashcat; exit 1; }

# ensure that '__' is unset && remains unset
[[ -z ${__+x} ]] &&  # if '__' is unset
  declare -r __ ||   # then ensure that '__' remains unset 
  scat <<EOF         # else exit with an error
Error: the parameter __='${__}' is set, hence the
  comment-idiom '\${__+ <comment text>}' will fail
EOF

${__+ (example of inline comments)
------------------------------------------------
the following inline comment-idiom is supported
    <code> ${__+ <comment>} <code> 
    <code> ${__+ <multiline
                  comment>} <code> 
(advisory) the parameter '__' must NOT be set;
  even the null declaration __='' will fail
(advisory) protect unbalanced delimiters \} and \) 
(advisory) NO parameter-expansion of <comment> 
(advisory) NO subprocesses are spawned
(advisory) a functionally equivalent idiom is 
    <code> `# <comment>` <code> 
    <code> `# <multiline
               comment>` <code>
however each comment spawns a bash subprocess
that inelegantly requires ~1ms of computation 
------------------------------------------------}
0
John Sidles