flymake-shell works with any shell of your choice. Default it uses Bash.

This doesn’t actually seem to do anything for me. Can you give an example of some code that would cause an error to crop up? I tried some “fi” without if, but it does nothing.

It does work for me but the “-n” option doesn’t find all errors. For example, exit “” is syntactically correct but exit needs an argument which you will not be told.

    ;;; Flymake Shell mode
    (require 'flymake)
    (defcustom flymake-shell-of-choice
      "Path of shell.")
    (defcustom flymake-shell-arguments
      (list "-n")
      "Shell arguments to invoke syntax checking.")
    (defconst flymake-allowed-shell-file-name-masks
      '(("\\.sh$" flymake-shell-init))
      "Filename extensions that switch on flymake-shell mode syntax checks.")
    (defcustom flymake-shell-err-line-pattern-re
      '(("^\\(.+\\): line \\([0-9]+\\): \\(.+\\)$" 1 2 nil 3))
      "Regexp matching JavaScript error messages.")
    (defun flymake-shell-init ()
      (let* ((temp-file (flymake-init-create-temp-buffer-copy
             (local-file (file-relative-name
                          (file-name-directory buffer-file-name))))
        (list flymake-shell-of-choice (append flymake-shell-arguments (list local-file)))))
    (defun flymake-shell-load ()
      (setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks flymake-allowed-shell-file-name-masks))
      (setq flymake-err-line-patterns (append flymake-err-line-patterns flymake-shell-err-line-pattern-re))
      (flymake-mode t)
      (local-set-key (kbd "C-c d") 'flymake-display-err-menu-for-current-line))
    (provide 'flymake-shell)
    ;;; flymake-shell.el ends here

You may want to invoke flymake-shell when sh-mode loads.

    (require 'flymake-shell)
    (add-hook 'sh-mode-hook 'flymake-shell-load)