Choose the shell for ShellCheck
Tell ShellCheck which shell a script targets with -s bash or -s sh. Without a shebang it cannot tell, and as sh it flags every Bash-only feature as SC3xxx.
ShellCheck either complains that it cannot tell which shell the script is for, or accepts Bash features in a script that must run under /bin/sh.
printf 'if [[ -n $1 ]]; then echo hi; fi\n' > check.sh
shellcheck -f gcc check.sh
echo "no shebang: status $?"
shellcheck -f gcc -s sh check.sh
echo "-s sh: status $?"
shellcheck -f gcc -s bash check.sh
echo "-s bash: status $?"check.sh:1:1: error: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive. [SC2148]
no shebang: status 1
check.sh:1:4: warning: In POSIX sh, [[ ]] is undefined. [SC3010]
-s sh: status 1
-s bash: status 0ShellCheck decides how to read a script from the shebang or a # shellcheck shell= directive. When there is neither, it reports SC2148 and still checks as Bash. -s sets the dialect directly: sh applies POSIX rules, so [[ ]] is reported as undefined in POSIX sh (SC3010), and bash accepts it. The codes are listed on the ShellCheck wiki. The gcc format prints one line per finding, which is easy to read in a log.
-s overrides the shebang, so a script with #!/bin/bash checked with -s sh is judged by the wrong rules. Better to fix the shebang, or add the directive in the file. -s dash and -s ksh also exist, and the checks for portability cover syntax but not whether the commands a script calls behave the same everywhere. The output is from ShellCheck 0.9.0.