diff --git a/SC2026.md b/SC2026.md index 3fbb4ce..b60eb75 100644 --- a/SC2026.md +++ b/SC2026.md @@ -1,24 +1,37 @@ -## Consider using grep -c instead of grep|wc. +## This word is outside of quotes. Did you intend to 'nest '"'single quotes'"' instead'? ### Problematic code: - grep foo | wc -l + alias server_uptime='ssh $host 'uptime -p'' ### Correct code: - grep -c foo + alias server_uptime='ssh $host '"'uptime -p'" ### Rationale: -This is purely a stylistic issue. `grep` can count lines without piping to `wc`. +In the first case, the user has four single quotes on a line, wishfully hoping that the shell will match them up as outer quotes around a string with literal single quotes: -Note that in many cases, this number is only used to see whether there are matches (i.e. `> 0`). In these cases, it's better and more efficient to use `grep -q` and check its exit status: + v--------match--------v + alias server_uptime='ssh $host 'uptime -p'' + ^--match--^ - if grep -q pattern file - then - echo "The file contains the pattern" - fi +The shell, meanwhile, always terminates single quoted strings at the first possible single quote: + + v---match--v + alias server_uptime='ssh $host 'uptime -p'' + ^^ + +Which is the same thing as `alias server_uptime='ssh $host uptime' -p`. + +There is no way to nest single quotes. However, single quotes can be placed literally in double quotes, so we can instead concatenate a single quoted string and a double quoted string: + + v--match---v + alias server_uptime='ssh $host '"'uptime -p'" + ^---match---^ + +This results in an alias with embedded single quotes. ### Exceptions -If you e.g. want to count characters instead of lines, and you actually care about the number and not just whether it's greater than 0. \ No newline at end of file +None. \ No newline at end of file