{"id":10311,"date":"2018-06-21T15:56:01","date_gmt":"2018-06-21T13:56:01","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=10311"},"modified":"2018-09-14T08:34:21","modified_gmt":"2018-09-14T06:34:21","slug":"shell-scripte-ueberpruefen-mit-shellcheck-auch-auf-dem-raspberry-pi-moeglich","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=10311","title":{"rendered":"Shell Scripte \u00fcberpr\u00fcfen mit ShellCheck auch auf dem Raspberry Pi (Zero W) in 5 Minuten m\u00f6glich und auch JUnit via xslt"},"content":{"rendered":"<p>Mit <a href=\"https:\/\/github.com\/koalaman\/shellcheck\/blob\/master\/README.md#user-content-gallery-of-bad-code\" rel=\"noopener\" target=\"_blank\">shellcheck<\/a> kann man gut Shell Scripte \u00fcberpr\u00fcfen.Das kann man einfach online, \u00fcber diese GUI <a href=\"https:\/\/www.shellcheck.net\" rel=\"noopener\" target=\"_blank\">www.shellcheck.net<\/a> ausprobieren oder aber auch installieren. <\/p>\n<p>F\u00fcr den Raspberry Pi gibt es schon ein installations Packet, deshalb ist die Installation mit<\/p>\n<pre class=\"lang:default decode:true \" >\r\nsudo apt install shellcheck\r\n# Testen welche Version installiert wurde#\r\n# version: 0.4.4\r\n<\/pre>\n<p>schnell erledigt.<\/p>\n<p>Das ist nun nicht gerade die aktuelle Version 0.5.0 aber immerhin. Ein selbst compilieren kommt f\u00fcr den Pi nicht infrage, da ShellCheck in <a href=\"https:\/\/de.wikipedia.org\/wiki\/Haskell_(Programmiersprache)\" rel=\"noopener\" target=\"_blank\">Haskell<\/a> programmiert ist und da f\u00fcr den compile mind. 2GB RAM ben\u00f6tigt werden, der Pi hat aber je nach Version max. 1GB.<\/p>\n<p>Nun kann leicht eine Script Datei \u00fcberpr\u00fcft werden, mit Aufruf <\/p>\n<p><strong>shellcheck SCRIPT.sh<\/strong>. Hier mal zwei Beispiele:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05.png\" alt=\"\" width=\"1186\" height=\"385\" class=\"aligncenter size-full wp-image-10313\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05.png 1186w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05-300x97.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05-768x249.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.27.05-1024x332.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><br \/>\n<!--more--><\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39.png\" alt=\"\" width=\"1278\" height=\"297\" class=\"aligncenter size-full wp-image-10315\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39.png 1278w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39-300x70.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39-768x178.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-14.25.39-1024x238.png 1024w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/a><\/p>\n<p>Ok, komme nun auch in die <a href=\"https:\/\/github.com\/koalaman\/shellcheck\/blob\/master\/README.md#user-content-gallery-of-bad-code\" rel=\"noopener\" target=\"_blank\">user-content-gallery-of-bad-code<\/a> \ud83d\ude09 Hier sind \u00fcbrigens <a href=\"https:\/\/github.com\/koalaman\/shellcheck\/wiki\/SC1000\" rel=\"noopener\" target=\"_blank\">alle Rules<\/a> mit Beispielen rechts in der Navi-Leiste zu finden.<\/p>\n<p><strong>JUnit<\/strong><\/p>\n<p>ShellCheck hat keinen JUnit XML Formatter. Aber man kann im Checkstyle XML Format die Meldungen ausgeben. Z.B.<\/p>\n<p><strong>shellcheck -f checkstyle script.sh<\/strong><\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;?xml version='1.0' encoding='UTF-8'?&gt;\r\n&lt;checkstyle version='4.3'&gt;\r\n&lt;file name='dump1090.sh' &gt;\r\n&lt;error line='26' column='11' severity='warning' message='Use cd ... &amp;#124;&amp;#124; exit in case cd fails.' source='ShellCheck.SC2164' \/&gt;\r\n&lt;error line='27' column='19' severity='info' message='Double quote to prevent globbing and word splitting.' source='ShellCheck.SC2086' \/&gt;\r\n&lt;error line='27' column='30' severity='error' message='The order of the 2&amp;#62;&amp;#38;1 and the redirect matters. The 2&amp;#62;&amp;#38;1 has to be last.' source='ShellCheck.SC2069' \/&gt;\r\n&lt;\/file&gt;\r\n&lt;\/checkstyle&gt;<\/pre>\n<p>Diese Ausgabe kann nun mit dem vorhandenen <a href=\"https:\/\/github.com\/koalaman\/shellcheck\/wiki\/JUnit\" rel=\"noopener\" target=\"_blank\">checkstyle2junit.xslt<\/a> transformiert werden. Dazu muss auch noch <strong>xmlstarlet<\/strong> installiert werden:<\/p>\n<p><strong>sudo apt-get install xmlstarlet<\/strong><\/p>\n<p>Nun k\u00f6nnen wir den XML Output \u00fcber das XSLT convertieren um JUnit XML zu erhalten:<\/p>\n<p><strong><br \/>\nshellcheck -f checkstyle script.sh  | xmlstarlet tr checkstyle2junit.xslt<\/strong><\/p>\n<p>Und wir erhalten die Testsuite mit Testcase &#8230;<\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;testsuite tests=\"1\" failures=\"3\"&gt;\r\n&lt;testcase classname=\"dump1090.sh\" name=\"dump1090.sh\"&gt;\r\n&lt;failure type=\"ShellCheck.SC2164\"&gt;Line 26: Use cd ... || exit in case cd fails.&lt;\/failure&gt;\r\n&lt;failure type=\"ShellCheck.SC2086\"&gt;Line 27: Double quote to prevent globbing and word splitting.&lt;\/failure&gt;\r\n&lt;failure type=\"ShellCheck.SC2069\"&gt;Line 27: The order of the 2&amp;gt;&amp;amp;1 and the redirect matters. The 2&amp;gt;&amp;amp;1 has to be last.&lt;\/failure&gt;\r\n&lt;\/testcase&gt;\r\n&lt;\/testsuite&gt;<\/pre>\n<p>Hier die Datei in der JUnit View:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-15.05.38.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-15.05.38.png\" alt=\"\" width=\"204\" height=\"324\" class=\"aligncenter size-full wp-image-10321\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-15.05.38.png 204w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2018\/06\/Bildschirmfoto-2018-06-20-um-15.05.38-189x300.png 189w\" sizes=\"auto, (max-width: 204px) 100vw, 204px\" \/><\/a><\/p>\n<p><strong>JSON<\/strong><\/p>\n<p>Die Ausgabe im JSON Format geht nat\u00fcrlich auch. Z.b. mit<\/p>\n<p><strong>shellcheck -f json script.sh<\/strong><\/p>\n<pre class=\"lang:default decode:true \" >[{\"file\":\"dump1090.sh\",\"line\":26,\"column\":11,\"level\":\"warning\",\"code\":2164,\"message\":\"Use cd ... || exit in case cd fails.\"},{\"file\":\"dump1090.sh\",\"line\":27,\"column\":19,\"level\":\"info\",\"code\":2086,\"message\":\"Double quote to prevent globbing and word splitting.\"},{\"file\":\"dump1090.sh\",\"line\":27,\"column\":30,\"level\":\"error\",\"code\":2069,\"message\":\"The order of the 2&gt;&amp;1 and the redirect matters. The 2&gt;&amp;1 has to be last.\"}]<\/pre>\n<p>oder besser formatiert:<\/p>\n<pre class=\"lang:default decode:true \" >[\r\n\t{\r\n\t\t\"file\": \"dump1090.sh\",\r\n\t\t\"line\": 26,\r\n\t\t\"column\": 11,\r\n\t\t\"level\": \"warning\",\r\n\t\t\"code\": 2164,\r\n\t\t\"message\": \"Use cd ... || exit in case cd fails.\"\r\n\t},\r\n\t{\r\n\t\t\"file\": \"dump1090.sh\",\r\n\t\t\"line\": 27,\r\n\t\t\"column\": 19,\r\n\t\t\"level\": \"info\",\r\n\t\t\"code\": 2086,\r\n\t\t\"message\": \"Double quote to prevent globbing and word splitting.\"\r\n\t},\r\n\t{\r\n\t\t\"file\": \"dump1090.sh\",\r\n\t\t\"line\": 27,\r\n\t\t\"column\": 30,\r\n\t\t\"level\": \"error\",\r\n\t\t\"code\": 2069,\r\n\t\t\"message\": \"The order of the 2&gt;&amp;1 and the redirect matters. The 2&gt;&amp;1 has to be last.\"\r\n\t}\r\n]<\/pre>\n<p><strong>GCC<\/strong><\/p>\n<p>Auch das GCC Format ist m\u00f6glich:<\/p>\n<p><strong>shellcheck -f gcc script.sh<\/strong><\/p>\n<pre class=\"lang:default decode:true \" >\r\n\r\ndump1090.sh:26:11: warning: Use cd ... || exit in case cd fails. [SC2164]\r\ndump1090.sh:27:19: note: Double quote to prevent globbing and word splitting. [SC2086]\r\ndump1090.sh:27:30: error: The order of the 2&gt;&amp;1 and the redirect matters. The 2&gt;&amp;1 has to be last. [SC2069]\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Mit shellcheck kann man gut Shell Scripte \u00fcberpr\u00fcfen.Das kann man einfach online, \u00fcber diese GUI www.shellcheck.net ausprobieren oder aber auch installieren. F\u00fcr den Raspberry Pi gibt es schon ein installations Packet, deshalb ist die Installation mit sudo apt install shellcheck # Testen welche Version installiert wurde# # version: 0.4.4 schnell erledigt. Das ist nun nicht &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=10311\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eShell Scripte \u00fcberpr\u00fcfen mit ShellCheck auch auf dem Raspberry Pi (Zero W) in 5 Minuten m\u00f6glich und auch JUnit via xslt\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[220,808,79,1023,2752,2658],"tags":[3310,999,3314,1257,55,1397,862,3313,3311,194,3312],"class_list":["post-10311","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-linux-2","category-programmierung","category-raspberry-pi","category-raspberry-pi-zero-w","category-test-thema","tag-bourne","tag-check","tag-haskell","tag-json","tag-junit","tag-script","tag-shell","tag-shellcheck","tag-syntax","tag-test-2","tag-ueberpruefung"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/10311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=10311"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/10311\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=10311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=10311"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=10311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}