# 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 <scout) > 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 <script) > 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()
}