ESLint Blog

ESLint now officially supports linting of shell scripts

Read the original on eslint.org ↗

Back in July of 2024 we announced our plan to make ESLint a more general-purpose linter capable of linting any language. Since then, we’ve added official support for JSON, Markdown, and CSS. Today, we’re happy to add shell scripts to that list with the introduction of the @eslint/shell plugin.

Shell linting with @eslint/shell

The @eslint/shell plugin is an officially supported language plugin for ESLint. It provides parsing for shell scripts, a set of rules inspired by ShellCheck, and a recommended configuration. To use it, install it from npm:

npm install @eslint/shell -D
1
Copy code to clipboard

Then add the recommended configuration to your eslint.config.js:

import { defineConfig } from "eslint/config";
import shell from "@eslint/shell";

export default defineConfig([
    {
        plugins: { shell },
        extends: ["shell/recommended"],
    },
]);
123456789
Copy code to clipboard

The recommended configuration uses Bash and enables rules that catch common problems, such as unquoted expansions, unused variables, and unsafe read usage. You can also configure the plugin manually and choose a shell dialect:

import { defineConfig } from "eslint/config";
import shell from "@eslint/shell";

export default defineConfig([
    {
        files: ["**/*.sh"],
        plugins: { shell },
        language: "shell/posix",
        rules: {
            "shell/no-backticks": "error",
            "shell/no-unquoted-expansions": "error",
        },
    },
]);
1234567891011121314
Copy code to clipboard

The plugin supports Bash, POSIX sh, and MirBSD Korn shell (mksh). Its rules cover issues such as legacy command substitutions, iterating over ls output, unquoted expansions, and variables in printf format strings. For the complete list of rules and configuration options, see the README.

Have an idea for a rule? Open an issue.

Creating custom rules

The @eslint/shell plugin parses shell scripts into an ESTree-style syntax tree, which ESLint rules can traverse just as they do for JavaScript. This means you can write custom rules to enforce the conventions that matter to your project. The parser is built on mvdan-sh, the parser used by shfmt. You can explore the shell syntax tree in the ESLint Code Explorer.

Conclusion

Shell scripts are an important part of many projects, from build and release automation to local development tools. With @eslint/shell, you can lint shell scripts alongside the rest of your code using ESLint’s configuration system and familiar rule APIs.

With the addition of shell support, ESLint continues to grow into a versatile tool capable of linting many kinds of source files. We hope this plugin helps you find issues in your scripts and makes it easier to maintain consistent quality across your projects.

As a reminder, ESLint is an independent open source project maintained by a group of volunteers in their spare time. If you enjoy using ESLint, please talk to your company about sponsoring the project.