Don't use variables in the printf format string. Use printf "..%s.." "$foo". Open
printf "_____\nComparing logfile $log_number to baseline 0...\n"
- Read upRead up
- Exclude checks
Don't use variables in the printf format string. Use printf "..%s.." "$foo".
Problematic code:
printf "Hello, $NAME\n"
Correct code:
printf "Hello, %s\n" "$NAME"
Rationale:
printf
interprets escape sequences and format specifiers in the format string. If variables are included, any escape sequences or format specifiers in the data will be interpreted too, when you most likely wanted to treat it as data. Example:
coverage='96%'
printf "Unit test coverage: %s\n" "$coverage"
printf "Unit test coverage: $coverage\n"
The first printf writes Unit test coverage: 96%
.
The second writes bash: printf: `\': invalid format character
Exceptions
Sometimes you may actually want to interpret data as a format string, like in:
hexToAscii() { printf "\x$1"; }
hexToAscii 21
or when you have a pattern in a variable:
filepattern="file-%d.jpg"
printf -v filename "$filepattern" "$number"
These are valid use cases with no useful rewrites. Please [[ignore]] the warnings with a [[directive]].
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Use ./*glob* or -- *glob* so names with dashes won't become options. Open
log_number=$(ls *.ninja_log | cut -d'.' -f1 | sort -rn | head -n 1)
- Read upRead up
- Exclude checks
Use ./*glob* or -- *glob* so names with dashes won't become options.
Problematic code:
rm *
Correct code:
rm ./*
or
rm -- *
Rationale
Since files and arguments are strings passed the same way, programs can't properly determine which is which, and rely on dashes to determine what's what.
A file named -f
(touch -- -f
) will not be deleted by the problematic code. It will instead be interpreted as a command line option, and rm
will even report success.
Using ./*
will instead cause the glob to be expanded into ./-f
, which no program will treat as an option.
Similarly, --
by convention indicates the end of options, and nothing after it will be treated like flags (except for some programs possibly still special casing -
as e.g. stdin).
Note that changing *
to ./*
in GNU Tar parameters will add ./
prefix to path names in the created archive. This may cause subtle problems (eg. to search for a specific file in archive, the ./
prefix must be specified as well). So using -- *
is a safer fix for GNU Tar commands.
For more information, see "Filenames and Pathnames in Shell: How to do it Correctly".
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Use find instead of ls to better handle non-alphanumeric filenames. Open
log_number=$(ls *.ninja_log | cut -d'.' -f1 | sort -rn | head -n 1)
- Read upRead up
- Exclude checks
Use find instead of ls to better handle non-alphanumeric filenames.
Problematic code:
ls -l | grep " $USER " | grep '\.txt$'
Correct code:
find . -maxdepth 1 -name '*.txt' -user "$USER"
Rationale:
ls
is only intended for human consumption: it has a loose, non-standard format and may "clean up" filenames to make output easier to read.
Here's an example:
$ ls -l
total 0
-rw-r----- 1 me me 0 Feb 5 20:11 foo?bar
-rw-r----- 1 me me 0 Feb 5 2011 foo?bar
-rw-r----- 1 me me 0 Feb 5 20:11 foo?bar
It shows three seemingly identical filenames, and did you spot the time format change? How it formats and what it redacts can differ between locale settings, ls
version, and whether output is a tty.
ls
can usually be substituted for find
if it's the filenames you're after.
If trying to parse out any other fields, first see whether stat
(GNU, OS X, FreeBSD) or find -printf
(GNU) can give you the data you want directly.
Exceptions:
If the information is intended for the user and not for processing (ls -l ~/dir | nl; echo "Ok to delete these files?"
) you can ignore this error with a [[directive]].
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Unexpected trailing spaces found. Open
# Create and change to .build_profiling dir
- Exclude checks
Unexpected trailing spaces found. Open
# Create and change to product_string dir
- Exclude checks