Community코딩 & 개발github.com

Bash 린팅

사용자가 "bash 스크립트 린트", "shellcheck 실행", "셸 스크립트 포맷", "shfmt 사용", "shellcheck 오류 수정" 또는 셸 스크립트 린팅, 포맷팅, 코드 품질, pre-commit 훅에 대해 언급할 때 사용하는 스킬입니다.

Bash 린팅란 무엇인가요?

이 스킬은 ShellCheck와 shfmt를 통합하여 Bash 스크립트의 코드 품질을 보장합니다. ShellCheck는 정적 분석 도구로, 일반적인 코딩 오류, 보안 취약점, 베스트 프랙티스 위반을 탐지합니다. shfmt는 셸 스크립트의 일관된 포맷팅을 제공하여 가독성을 높입니다. 이 스킬은 로컬 개발 환경뿐만 아니라 pre-commit 훅, GitHub Actions, GitLab CI와 같은 CI/CD 파이프라인에도 통합할 수 있습니다. VS Code, Vim/Neovim과 같은 편집기와의 통합도 지원하여 실시간 린팅 및 포맷팅을 가능하게 합니다. 주요 기능으로는 ShellCheck 규칙 비활성화(disable), shfmt 포맷팅 옵션 설정, .editorconfig를 통한 프로젝트 차원의 포맷팅 규칙 적용 등이 있습니다. 이 스킬을 통해 개발자는 Bash 스크립트의 오류를 조기에 발견하고, 일관된 코딩 스타일을 유지하며, 코드 리뷰 시간을 단축할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/bash-development/skills/bash-lint

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Bash 린팅은(는) 무엇을 하나요?

ShellCheck와 shfmt를 통합한 Bash 스크립트 품질 보증

ShellCheck

설치

# Debian/Ubuntu
apt install shellcheck

# macOS
brew install shellcheck

# 소스에서 빌드
cabal update && cabal install ShellCheck

기본 사용법

# 단일 파일 검사
shellcheck script.sh

# 여러 파일 검사
shellcheck *.sh

# 특정 셸 방언 지정
shellcheck --shell=bash script.sh
shellcheck --shell=sh script.sh

# 특정 규칙 제외
shellcheck --exclude=SC2086 script.sh
shellcheck --exclude=SC2086,SC2046 script.sh

# 출력 형식
shellcheck --format=gcc script.sh    # GCC 스타일
shellcheck --format=json script.sh   # 도구 연동용 JSON
shellcheck --format=diff script.sh   # 통합 diff

일반적인 ShellCheck 코드

코드문제해결 방법
SC2086글로빙/분할 방지를 위해 따옴표 사용"$var"
SC2046명령어 치환을 따옴표로 감싸기"$(cmd)"
SC2006백틱 대신 $() 사용$(cmd)
SC2034변수가 사용되지 않음제거하거나 export
SC2155선언과 할당을 분리local var; var=$(...) 형식으로
SC2164cd ... || exit 사용cd 실패 처리
SC2181종료 상태를 직접 확인if cmd; then
SC2129쓰기 작업 그룹화 고려{ } > file 사용
SC1090소싱된 파일을 추적할 수 없음# shellcheck source=경로 사용
SC2154변수가 선언되지 않음초기화 또는 선언

ShellCheck 지시문

# 다음 줄에서만 비활성화
# shellcheck disable=SC2086
echo $unquoted_var

# 전체 파일에서 비활성화 (파일 상단)
# shellcheck disable=SC2086,SC2046

# 소싱할 파일의 경로 지정
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

# 셸 방언 지정
# shellcheck shell=bash

# 블록 비활성화 (지원 안 됨 - 줄 단위로 사용)

인라인 지시문 패턴

# 설명과 함께 특정 경고 비활성화
# shellcheck disable=SC2034 # 스크립트에서 소싱하여 사용하는 변수
readonly CONFIG_VERSION="1.0"

# 여러 코드 비활성화
# shellcheck disable=SC2086,SC2046
result=$(echo $var)

# 동적 경로에 대한 소스 지시문
# shellcheck source=/dev/null
source "${DYNAMIC_PATH}/config.sh"

shfmt

설치

# macOS
brew install shfmt

# Go 설치
go install mvdan.cc/sh/v3/cmd/shfmt@latest

# Snap
snap install shfmt

# 바이너리 다운로드
# https://github.com/mvdan/sh/releases 참조

기본 사용법

# 포맷팅하여 stdout으로 출력
shfmt script.sh

# 파일 자체를 포맷팅
shfmt -w script.sh

# 포맷팅 검사 (포맷팅 안 되었으면 exit 1)
shfmt -d script.sh

# 디렉토리 재귀적 포맷팅
shfmt -w .
shfmt -w scripts/

포맷팅 옵션

# 들여쓰기
shfmt -i 2 script.sh  # 2칸 공백 들여쓰기
shfmt -i 4 script.sh  # 4칸 공백 들여쓰기
shfmt -i 0 script.sh  # 탭 (기본값)

# 이진 연산자를 줄 시작에 배치
shfmt -bn script.sh

# switch/case 들여쓰기
shfmt -ci script.sh

# 리다이렉션 연산자 뒤에 공백 추가
shfmt -sr script.sh

# 열 정렬 유지
shfmt -kp script.sh

# 함수 여는 중괄호를 별도 줄에 배치
shfmt -fn script.sh

# 조합
shfmt -i 4 -ci -bn script.sh

설정 (.editorconfig)

# .editorconfig
[*.sh]
indent_style = space
indent_size = 4
shell_variant = bash
binary_next_line = true
switch_case_indent = true
space_redirects = true

변환 예시

shfmt 적용 전:

if [ -f "$file" ];then
echo "exists"
fi

for i in 1 2 3;do
    process $i
done

shfmt -i 4 -ci 적용 후:

if [ -f "$file" ]; then
    echo "exists"
fi

for i in 1 2 3; do
    process $i
done

Pre-commit 통합

.pre-commit-config.yaml

repos:
  - repo: https://github.com/koalaman/shellcheck-precommit
    rev: v0.9.0
    hooks:
      - id: shellcheck
        args: ["--severity=warning"]

  - repo: https://github.com/scop/pre-commit-shfmt
    rev: v3.7.0-1
    hooks:
      - id: shfmt
        args: ["-i", "4", "-ci", "-w"]

  # 대안: 로컬 훅
  - repo: local
    hooks:
      - id: shellcheck
        name: shellcheck
        entry: shellcheck
        language: system
        types: [shell]
        args: ["--severity=warning", "-x"]

      - id: shfmt
        name: shfmt
        entry: shfmt
        language: system
        types: [shell]
        args: ["-i", "4", "-ci", "-w"]

Pre-commit 실행

# 훅 설치
pre-commit install       # 또는: prek install

# 모든 파일에 대해 실행
pre-commit run --all-files       # 또는: prek run --all-files

# 특정 훅 실행
pre-commit run shellcheck --all-files
pre-commit run shfmt --all-files

# 특정 파일에 대해 실행
pre-commit run --files script.sh

CI/CD 통합

GitHub Actions

name: Shell 린트

on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: ShellCheck 실행
        uses: ludeeus/action-shellcheck@master
        with:
          severity: warning

      - name: shfmt로 포맷팅 검사
        uses: mvdan/github-action-shfmt@master
        with:
          flags: -d -i 4 -ci

GitLab CI

shellcheck:
  image: koalaman/shellcheck-alpine:stable
  script:
    - find . -name "*.sh" -exec shellcheck {} +

shfmt:
  image: mvdan/shfmt:latest
  script:
    - shfmt -d -i 4 -ci .

일반적인 문제 수정

SC2086: 분할 방지를 위해 따옴표 사용

# 나쁜 예
echo $var

# 좋은 예
echo "$var"
printf '%s\n' "$var"

SC2155: 선언과 할당 분리

# 나쁜 예 - 종료 상태를 가림
local var=$(some_command)

# 좋은 예
local var
var=$(some_command)

SC2164: cd || exit 사용

# 나쁜 예
cd "$dir"
rm -rf *

# 좋은 예
cd "$dir" || exit 1
rm -rf *

# 또는 서브쉘 사용
(cd "$dir" && rm -rf *)

SC2181: 종료 상태 직접 확인

# 나쁜 예
command
if [ $? -eq 0 ]; then

# 좋은 예
if command; then

SC1090/SC1091: 소스 관련 문제

# 동적 소스에 지시문 추가
# shellcheck source=/dev/null
source "$DYNAMIC_PATH/lib.sh"

# 또는 실제 경로 지정
# shellcheck source=./lib/functions.sh
source "$SCRIPT_DIR/lib/functions.sh"

편집기 통합

VS Code

Timon Wong의 "ShellCheck" 확장 프로그램을 설치하세요.

// settings.json
{
    "shellcheck.enable": true,
    "shellcheck.run": "onSave",
    "shellcheck.executablePath": "shellcheck",
    "editor.formatOnSave": true,
    "[shellscript]": {
        "editor.defaultFormatter": "foxundermoon.shell-format"
    }
}

Vim/Neovim

" ALE 사용
let g:ale_linters = {'sh': ['shellcheck']}
let g:ale_fixers = {'sh': ['shfmt']}
let g:ale_sh_shfmt_options = '-i 4 -ci'

" coc.nvim 사용
" coc-sh 확장 설치

모범 사례

  1. ShellCheck를 조기에 실행 - 편집기와 CI에 통합
  2. 문제를 수정하고, 억제하지 마세요 - 타당한 이유 없이 비활성화 금지
  3. 비활성화한 경우 문서화 - 규칙을 비활성화한 이유를 설명
  4. 심각도 수준 사용 - CI에서는 --severity=warning 사용
  5. 일관된 포맷팅 - pre-commit에서 shfmt 사용
  6. 도구 버전 고정 - CI/pre-commit에서 버전을 고정

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Jamie-BitFlight/agentskill-kaizen-meta-docs

Agentskill kaizen plugin documentation index. Load when needing to read about cross-platform notes, improvement plans, or DuckDB integration.

Jamie-BitFlight/bash-51-features

Bash 5.1 release features and improvements with practical examples. Use when working with Bash 5.1 features, epoch time variables, redirection enhancements, or when user asks about Bash 5.1 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-52-features

Bash 5.2 release features and improvements with practical examples. Use when working with Bash 5.2 features, variable handling enhancements, readline improvements, or when user asks about Bash 5.2 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-53-features

Bash 5.3 release features and improvements with practical examples. Use when working with Bash 5.3 features, new command substitution, GLOBSORT, loadable builtins, or when user asks about Bash 5.3 changes, new features, or version-specific capabilities.

Jamie-BitFlight/bash-development

This skill should be used when the user asks to "write a bash script", "create a shell script", "implement bash function", "parse arguments in bash", "handle errors in bash", or mentions bash development, shell scripting, script templates, or modern bash patterns.

Jamie-BitFlight/bash-logging

This skill should be used when the user asks to "add logging to bash script", "colorize output", "implement log levels", "CI/CD sections", "terminal colors in bash", or mentions logging functions, emoji output, collapsible CI sections, or shlocksmith.

Jamie-BitFlight/bash-portability

This skill should be used when the user asks about "POSIX compatibility", "portable shell scripts", "cross-shell compatibility", "bashisms", "shebang selection", or mentions writing scripts that work on different shells (bash, sh, dash, zsh) or different systems.

Jamie-BitFlight/bash-testing

This skill should be used when the user asks to "test bash script", "write shell tests", "use shunit2", "use shellspec", "create test suite for bash", or mentions unit testing, test frameworks, mocking, or test-driven development for shell scripts.

Jamie-BitFlight/brainstorming-skill

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or when users request help with ideation, marketing, and strategic planning. Explores user intent, requirements, and design before implementation using research-validated prompt patterns.

Jamie-BitFlight/clang-format

Configure clang-format code formatting. Use when: user mentions clang-format or .clang-format, analyzing code style/patterns, creating/modifying formatting config, troubleshooting formatting, brace styles/indentation/spacing/alignment/pointer alignment, or codifying conventions.

Jamie-BitFlight/commitlint

When setting up commit message validation for a project. When project has commitlint.config.js or .commitlintrc files. When configuring CI/CD to enforce commit format. When extracting commit rules for LLM prompt generation. When debugging commit message rejection errors.

Jamie-BitFlight/conventional-commits

When writing a git commit message. When task completes and changes need committing. When project uses semantic-release, commitizen, git-cliff. When choosing between feat/fix/chore/docs types. When indicating breaking changes. When generating changelogs from commit history.

Jamie-BitFlight/dasel-reference

Use when querying, modifying, or converting JSON, YAML, TOML, XML, CSV, HCL, or INI with dasel v3. Complete reference for selectors, functions, conditionals, variables, spread operator, type casting, and format-specific patterns.

Jamie-BitFlight/data-exploration

Use when exploring unknown structured data files with dasel v3 — discover schema, list keys, find nested values, sample arrays, identify data types across JSON, YAML, TOML, XML, CSV, HCL, INI formats

Jamie-BitFlight/data-transformation

Use when modifying, converting, or transforming structured data with dasel v3 — in-place mutations, format conversion, batch operations, array manipulation, object construction, and merge patterns across JSON, YAML, TOML, XML, CSV, HCL, INI

Jamie-BitFlight/delegate

Decompose substantive work into phases, dispatch each phase to a sub-agent, and adjudicate what comes back. Use whenever a request asks for implementation, investigation, a fix, a review, or any change to files — including small ones — and whenever you are about to read source or run a diagnostic yourself instead of handing it off. Also use when a report from a sub-agent needs judging, when a phase needs re-dispatching, or when a user names one instance of a pattern. Does not apply when your own prompt begins "Your ROLE_TYPE is sub-agent." — then follow references/sub-agent-contract.md instead.

Jamie-BitFlight/enterprise-hibernate-hbm

Dasel v3 query patterns for Hibernate .hbm.xml mapping files — entity-table binding, Java property-to-column extraction, one-to-many set/list/bag relationship tracing, many-to-one foreign key discovery, batch scanning across 60+ HBM files. Use when querying Hibernate ORM class mappings, extracting schema metadata from Java persistence layer, or auditing entity-column relationships in enterprise legacy codebases.

Jamie-BitFlight/enterprise-installanywhere

Dasel v3 query patterns for InstallAnywhere .iap_xml installer definitions — use when querying action sequences, discovering variables, resolving platform conditions, navigating panels, or comparing installer variants. Files are 2.5+ MB, 65,000+ lines — too large for context reads, requires structural dasel queries.

Jamie-BitFlight/enterprise-maven-pom

Dasel v3 selector patterns for Maven POM XML files — use when querying dependency versions, filtering by groupId or scope, extracting module hierarchy from parent POMs, or detecting version conflicts across enterprise multi-module Java projects. Load this skill when working with pom.xml files using dasel.

Jamie-BitFlight/enterprise-spring-xml

Dasel v3 selectors for Spring bean factory XML — use when querying any Spring ApplicationContext XML for bean discovery, dependency wiring, JMS destination mapping, property injection extraction, or cross-bean reference tracing. Load this skill before writing dasel selectors against Spring bean XML files (applicationContext.xml, *_beans.xml, spring-*.xml).

관련 스킬