- Lint:
pre-commit run --all-files(runs shellcheck, shfmt, whitespace checks) - Format:
pre-commit run shfmt --all-files - Test single file: No specific test runner; use shellcheck directly:
shellcheck path/to/script.sh - Full test suite: Run pre-commit hooks:
pre-commit install && pre-commit run --all-files
- Use
#!/bin/bashshebang - Enable strict mode:
set -eat script start - Use
localfor function variables - Functions: lowercase with underscores, e.g.,
path_remove() - Error handling: Check command success with
|| { echo "error"; exit 1; }
- Indentation: Tabs (4 spaces) for most files, spaces (4) for Python
- Line endings: LF (Unix)
- Encoding: UTF-8
- Final newline: Required
- Trim whitespace: Yes
- JSON/YAML/Markdown: 2 spaces indentation
- Functions: snake_case (e.g.,
path_append,yaml2json) - Variables: lowercase with underscores
- Environment variables: UPPERCASE
- Files: lowercase with hyphens for scripts
- Shared configs: Use
~/.shell_commons/*.shfor bash/zsh common functionality - Numbering: Use prefix numbers for load order (e.g.,
05-lang.sh,20-path_and_manpath.sh,50-crap_terminals.sh) - Categories: Separate by function - language setup, PATH/MANPATH, terminal fixes
- Sourcing: Both shells source all
.shfiles in~/.shell_commons/
- Use full paths in PATH modifications
- Check directory existence:
[[ -d ${path} ]] && PATH="$(path_prepend "${path}" "${PATH}")" - Prefer local installations over system-wide
- Use
set -efor script failure on errors - Check command availability:
hash command 2>/dev/null || { echo "install command first"; exit 1; } - Provide clear error messages with context