This might be a FAQ--happy to have the question closed if it's a dupe--but I'm not sure how to find it if so. I'd also be happy with an answer that simply told me how to find the relevant documentation on syntax. (man bash is an old friend.)

I wanted to name a shell script "f#":

dotnet fsi "$@"

This would function as a shortcut to run from the bash command line in order to start the executable for the F# programming language.

To my surprise, this works, even though "#" is a shell comment character. I can even pass arguments to the script:

$ f# hello.fsx
Hello World from F`

And I can embed the preceding command in a script and run the script without any trouble. (!)

It seems as if the rule is that "#" only introduces a comment if it's preceded by whitespace or is at the beginning of a line. Otherwise it's treated as a normal character in bash. Is that correct?

Are there non-obvious gotchas that could bite me later if I use "f#" as a script name?

  • 1
    Even [ is a program. The gotcha is that you now have to report this with a lot of the editors out there that misinterpret this for syntax highlighting - vim to start with and the extensions to hightlight the code in your edited answer. I am checking out if there are any real captchas...
    – le_top
    Mar 15 at 21:29
  • 1
    "Is that correct?" – Basically it is. POSIX shell, token recognition. # that starts a comment is covered by the rule number 9; this rule is tested only if none of the previous rules match. The rule number 8 is "if the previous character was part of a word, the current character shall be appended to that word". So # can start a comment only if "the previous character was part of a word" is false. In case of f# the # matches the rule number 8. Mar 15 at 21:44
  • 1
    Some more obvious cases: # also does not introduce a comment (even with preceding whitespace) when it is part of a string enclosed in single or double quotes; as the number of args $# (even unquoted and unbracketed); in the length operator in a parameter expansion ${#parameter}, in the parameter truncation operation ${value#word}; as a number base like 8#77; inside a shell pattern expression; in a shebang. It is an integral part of the syntax. Mar 15 at 21:47
  • 1
    Note that your f# is not part of any shell command. It is merely the name of a file. I can name my script ' ' (four spaces) and Bash is perfectly happy to find and execute it. Mar 15 at 21:51
  • 1
    @Paul_Pedant I think a shebang is a comment when interpreted by a shell. The kernel uses it, not a shell. Mar 15 at 21:52

2 Answers 2


In all sh-like shells, including all versions of bash and zsh, # only starts a comment when it's at the beginning of a word. That means it must be at the beginning of the script or nested shell (e.g. $(# this is a comment — the closing ) needs to be on a separate line), preceded by a blank character, or preceded by an operator character (one of &|;<>). f# is never f followed by a comment start.

There are places where # has a special meaning, but in bash, I can't think of any case where it does when it's part of a word that is not the first character, and bash is expecting a word. (It does of course have a special meaning when bash is expecting something different; for example you definitely can't have # as part of a variable name.) In zsh, # is a wildcard character if the (very often enabled) option extended_glob is set. There # wouldn't be problematic in an alias (aliases are expanded before globbing), but it would be problematic in a script name.

Note that this is just about the shell. Other tools may have problems with #: it's very common as a comment character in configuration files. For example, I'm not sure you can include a # in the expansion of a Git alias.

  • 1
    @roaima No, but that doesn't affect what I wrote (I thought when writing I'd have to mention that, but it didn't seem to affect any statement I made). Mar 16 at 10:49
  • Thanks Gilles. Your answer and @le_top's are both very helpful, in different ways. Somewhat arbitrarily choosing yours to mark as correct.
    – Mars
    Mar 16 at 20:03

The GNU Bash Reference Manual for Version 5.2 of September 2022 says that "a word beginning with # causes that word and all remaining characters on that line to be ignored". And a word is "A sequence of characters treated as a unit by the shell. Words may not include unquoted metacharacters." The '#' character is not part of metacharacters.

The documentation for bash 2.05 is not as precise, but according to my analysis of several version of the GNU source code up to bash 1.14.7, the '#' character can be part of a word, and therefore of 'f#'.

A lot of the current '/bin/sh' paths are actually bash shells. So there is not much risk there.

Gotchas would therefore not come from bash, but could some from other tools. For instance, there is an invalid BNF syntax for bash that could have misled implementations of other tools interpreting a bash script.

Bash V2 BNF extract:

<ALPHA> ::= a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|

<DIGIT> ::= 0|1|2|3|4|5|6|7|8|9

           | <NUMBER> <DIGIT>

<WORD> ::= <ALPHA>
         | <WORD> <ALPHA>
         | <WORD> '_'

The gotcha mainly is that there is some program that interprets any (unquoted) '#' as the start of a comment. The most "annoying" one might be a code style formatter such as beautysh which does handle it correctly, but others might not.

real gotcha is the styling in editors: vim considers a '#' inside a word as the start of a comment, and several other environements do as well. So you end up with a wrong color code for the arguments to your 'f#' interpreter. These syntax highlighters are wrong and they should not be too hard to fix individually, but there are quite a few of them... Some versions of vim 8.2 will color code as they should, other vim 8.2 versions do not - the difference is probably in one of the vim 8.2 patches.

As long as 'f#' is for personal use, or on systems that you can control you should be safe - for global (worldwide) use, I'ld be more careful - I would not be in favor of seeing this distributed in debian for instance.

  • I found a BNF description of bash where '#' can not be part of a word. I referenced that bash V2 BNF.
    – le_top
    Mar 15 at 23:04
  • The documentation for bash 2.05 says "When the shell reads input, it proceeds through a sequence of operations. If the input indicates the beginning of a comment, the shell ignores the comment symbol (`#'), and the rest of that line." - and this is said before talking about dividing the input in words and operators.
    – le_top
    Mar 15 at 23:11
  • 1
    Examining the yacc source code, it looks like even in bash 2.05 the '#' can be part of a word as long as it is not at the start of the word.
    – le_top
    Mar 15 at 23:34
  • Thanks le_top. Your answer and @Gilles'SO-stopbeingevil' are both very helpful, in different ways. I somewhat arbitrarily chose theirs as correct. Better if someone gets the points.
    – Mars
    Mar 16 at 20:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .