(
or )
inside [[..]]
SH-1029You don't have to -- and can't -- escape (
or )
inside a [[ .. ]]
expression like you do in [ .. ]
. It is recommended remove the escaping.
Trying to escape something that has no special meaning when escaped. The backslash will simply be ignored here. If the backslash was supposed to be literal, it is recommended to enclose it in a single quote or escape it. If you wanted it to expand to something, rewrite the expression to use printf
(or in bash, $'\t'
).
SH-1017The script uses Windows/DOS style \r\n
line terminators instead of UNIX style \n
terminators. The additional \r
aka ^M
aka carriage return
characters will be treated literally, and result in all sorts of strange bugs and messages. You can verify this with cat -v yourfile
and see whether or not each line ends with a ^M
.
tab
, linefeed
or cariage return
might be expected SH-1012Detected a \t
, \n
or \r
in a context where they just become regular letters t
, n
or r
. Most likely, it was intended as a tab
, linefeed
or carriage return
. To generate such characters (plus other less common ones including \a
, \f
and octal escapes) , use printf
as in the example. The exception is for linefeeds
that would be stripped by command substitution; in these cases, use a literal quoted linefeed instead.
[ .. ]
is not a part of shell syntax SH-1014It is recommended to remove indentation before end token (or use <<-
and indent with tabs). The here document delimiter will not be recognized if it is indented.
( .. )
to group conditions SH-1026[ .. ]
should not be used to group subexpressions inside [[ .. ]]
or [ .. ]
statements. For [[ .. ]]
, use regular parentheses. For [ .. ]
, either use escaped parentheses, or preferably rewrite the expression into multiple [ .. ]
joined with &&
, ||
and { ..; }
groups. The latter is preferred because [ .. ]
is undefined for more than 4 arguments in POSIX.
The highlighted line in the code contains a unicode quote. It is recommended to delete and retype it if a quote was intended.
Variables that are declared but not used for anything should be removed.
expr
statement SH-2003According to POSIX: > The expr utility has a rather difficult syntax [...] In many cases, the arithmetic and string features provided as part of the shell command language are easier to use than their equivalents in expr. Newly written scripts should avoid expr in favor of the new features within the shell.
By default, xargs
interprets spaces and quotes in an unsafe and unexpected way. Whenever it's used, it should be used with -0
or --null
to split on \0
bytes, and find
should be made to output \0
separated filenames. POSIX does not require find
or xargs
to support null terminators, so you can also use find -exec <command> +
.
$
to make it a literal SH-1135The script appears to be closing a double quoted string for the sole purpose of making a dollar sign $
literal. This will work, but a better way is to escape it with a backslash. This allows the double quoted string to continue uninterrupted, thereby reducing the visual noise of stopping and starting quotes in the middle of a shell word.
Some languages use the syntax $array[index]
to access an index of an array, but a shell will interpret this as $array
followed by the unrelated literal string (or glob) [index]
. Here, curly braces are needed to tell the shell that the square brackets are part of the expansion.
a/b*c
with a*c/b
SH-2017${#variable}
SH-2000Consider using ${#variable}
to get the number of characters in a variable. This is the same result as "$( echo "$variable" | wc -m )"
when "$variable"
only contains single-byte characters, it's also the same as "$( echo "$variable" | wc -c )"
This is a companion issue for SH-1078
which is triggered by unclosed strings. The quote here is interpreted as the closing quote for the previous string, but appears suspicious due to the character next to it.
\
SH-1101\\
is used before the line break to break a line. But, if there are spaces after the backslash, the escape will apply to the space instead of the line break, and the command will not continue on the next line.
ls | grep
SH-2010Parsing ls is generally a bad idea because the output is fragile and human readable. To better handle non-alphanumeric filenames, use a glob. If you need more advanced matching than a glob can provide, use a for loop.
echo
SH-2005Consider using cmd
instead of echo $(cmd)
.