# shellcheck.awk version 1 # lint a shell script using shellcheck.net # depends on curl and json2tsv being in your path function gettemp( result, retval) { while ((cmd_mktemp | getline) > 0) { retval = $0 } result = close(cmd_mktemp) if (result != 0) { print "Error: mktemp failed exit status: " result exit } if (length(retval) == 0) { print "Error: mktemp failed, no tmpfile" exit } return retval } function main( cmd, code, col, col2, curlcfg, jsout, level, line, line2, message, script, scout) { if (ARGC < 2) { print "Usage: shellcheck.awk [script.sh]" exit } curlcfg = gettemp() jsout = gettemp() scout = gettemp() script = ARGV[1] printf "--connect-timeout 10\n" > curlcfg printf "--max-redirs 0\n" >> curlcfg printf "--proto =https\n" >> curlcfg printf "--show-error\n" >> curlcfg printf "--silent\n" >> curlcfg printf "--url %s\n", api_url >>curlcfg printf "--form script=<\"%s\"\n", script >>curlcfg printf "--output %s\n", jsout >>curlcfg close(curlcfg) cmd = sprintf("%s -K %s 2>&1", cmd_curl, curlcfg) system(cmd) cmd = sprintf("%s <%s >%s 2>&1", cmd_json2tsv, jsout, scout) system(cmd) FS = "\t" while ((getline 0) { if ($1 == "[]" && $2 == "o" && code > 0) { printMsg(script, code, col, col2, line, line2, level, message) code = 0 col = 0 col2 = 0 level = "" line = 0 line2 = 0 message = "" } else if ($1 == "[].code" && $2 == "n") { code = $3 } else if ($1 == "[].column" && $2 == "n") { col = $3 } else if ($1 == "[].endColumn" && $2 == "n") { col2 = $3 } else if ($1 == "[].level" && $2 == "s") { level = $3 } else if ($1 == "[].line" && $2 == "n") { line = $3 } else if ($1 == "[].endLine" && $2 == "n") { line2 = $3 } else if ($1 == "[].message" && $2 == "s") { message = $3 } } close(scout) if (code > 0) { printMsg(script, code, col, col2, line, line2, level, message) } unlink(curlcfg) unlink(jsout) unlink(scout) return } function printMsg(script, code, col, col2, line, line2, level, message) { if (line == line2) { printf "Line %d:\n", line } else { printf "Lines %d-%d:\n", line, line2 } NR = 0 while ((getline 0) { NR++ if (NR >= line && NR <= line2) { print } } close(script) printf "%s^-- (%s): %s\n", repeat(" ", col - 1), level, message printf "https://www.shellcheck.net/wiki/SC%d\n\n", code return } function repeat(str, count, retval) { if (count > 0) { retval = sprintf("%" count "s", " ") gsub(/ /, str, retval) } return retval } function unlink(name) { system(cmd_rm " " name) return } BEGIN { api_url = "https://www.shellcheck.net/shellcheck.php" cmd_curl = "/usr/bin/curl" cmd_json2tsv = "json2tsv" cmd_mktemp = "/bin/mktemp" cmd_rm = "rm" main() }