14

I’d like to embed comments like this

ls -l \
-a \
# comment here
-h \
-t . 

But it seems that’s not possible. Maybe some other variant does exist? Putting a comment right after the backslash or ending a comment with a backslash doesn’t help.

Diti
  • 1,454
  • 3
  • 23
  • 38
tijagi
  • 1,124
  • 1
  • 13
  • 31

8 Answers8

13

The posts above do not have a direct solution. However, there is a direct solution that's actually mentioned in even older posts: How to put a line comment for a multi-line command and Commenting in a Bash script.

The solution I like best is:

ls -l `# long format` \
-a `# all files` \
-h `# human readable` \
-t `# time sort`

You will need both the accent grave (`) quotation and the octothorpe (#) to indicate the comment. Use them before the backslash.

LC-datascientist
  • 1,960
  • 1
  • 18
  • 32
10

As far as I know, it is not possible, for Bash tries to follow to POSIX guidelines and other standards. Especially:

If a <newline> follows the backslash, the shell shall interpret this as line continuation. The backslash and <newline>s shall be removed before splitting the input into tokens. Since the escaped <newline> is removed entirely from the input and is not replaced by any white space, it cannot serve as a token separator.
Shell Command Language, 2.2.1 Escape Character (Backslash)

Thus, it is not possible because of how the shell parser works:

  • A line starting with # is a comment, and nothing after gets evaluated (including a trailing \)
  • A \ that is not at the end of a line, is not a line skip.

In your script:

ls -l \
-a \
# comment here
-h \
-t .

The comment line is replaced with nothing (i.e. it has no token); and since the command, so far, is valid, and as a newline is met (… -a ↵), the shell runs the ls -l -a command, then the -h -t . command (and does not find a -h binary in your $PATH, so it stops right there.)

Diti
  • 1,454
  • 3
  • 23
  • 38
  • In your last paragraph, the newline that was met is at the end of the comment instead of after "-a \" I think. – spkersten May 11 '14 at 12:19
  • @spkersten That is true, I have not been clear enough (I used a space character to represent a newline, but I should have used ↵ instead.) Thanks! – Diti May 11 '14 at 12:33
7

You can do something like this with an array, which doesn't require continuation characters:

ls_cmd=(
  ls
  -l  # long form
  -a  # show hidden files
  -h  # human-readable sizes
  -t  # sort by time
  .
)

"${ls_cmd[@]}" # run the command from the array

...but for the general case, the answer is no.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
2

Not directly, buy you can put such comments in an array assignment. (This also allows you to split the arguments across multiple lines without using line continuation.)

cmd_options=(
  -l
  -a
   # comment here
  -h
  -t .
)
ls "${cmd_options[@]}" 
chepner
  • 497,756
  • 71
  • 530
  • 681
2

In that situation I usually go with something like

ls -l  -a  -h  -t .  
#  |   |   |   time sort
#  |   |   human readable
#  |   all files
#  long format

or I use the long form of the argument when they exist e.g. --human-readable rather than -h.

damienfrancois
  • 52,978
  • 9
  • 96
  • 110
  • 2
    Now imagine that your actual command line consists of multiple parameters with long names each taking a string, so the whole command takes several lines. – tijagi May 11 '14 at 20:04
  • @tijagi In such case I would assign the parameters by groups to variables with meaningful names as is often done in Makefile for instance. You can then interleave variable assignments with comments. – damienfrancois May 11 '14 at 20:11
1

...and it can be done after pipes:

echo "Hello beautiful" | \
# Display match only:
grep -o beautiful

But, otherwise... no.

Todd Partridge 'Gen2ly'
  • 2,258
  • 2
  • 19
  • 18
0

I don't think you can do this directly, because the comment removal is done before than the back-slash line concatenation, so this does not work

# commenting \
seveal lines

The obvious solution is to use # on every line:

# commenting
# seveal lines

If you want to be creative you can use a dirty trick:

: 'This is almost
a multiline comment'

Not actually a comment, but it does nothing, other than changing the exit code to 0.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
0

it's not possible. Because the backslash is a line continuator and the comment a single character which makes everything on its right ignored until end of line:

ls \
# -l \
-h

the -l will get ignored, the ls command executed and the -h considered as a new command.

Because in C-like languages you have comments with boundaries: /* */ it's possible to place those between token in expression that uses line continuation.

zmo
  • 24,463
  • 4
  • 54
  • 90