Community寫作與編輯github.com

Jamie-BitFlight/bash-portability

當使用者詢問「POSIX 相容性」、「可攜式 Shell 腳本」、「跨 Shell 相容性」、「Bash 特性」、Shebang 選擇,或提及要編寫能在不同 Shell(bash、sh、dash、zsh)或不同系統上執行的腳本時,應使用此技能。

bash-portability 是什麼?

這個技能提供撰寫可攜式 POSIX 相容腳本的完整指南,並協助開發者決定何時應利用 Bash 特有的功能來提升程式碼品質。它涵蓋 Shebang 選擇(`#!/usr/bin/env bash`、`#!/bin/sh`、`#!/bin/bash`)及其適用場景,並以特徵矩陣清楚列出 POSIX 與 Bash 在陣列、`[[ ]]`、`(( ))`、`local`、`<<<` 等功能的差異。支援 POSIX 的模式包含條件判斷(`[ ]` 搭配適當引號)、大小寫轉換(`tr`)、子字串操作(`expr` / `cut`)、檔案讀取與命令替換。當可攜性非必要時,也說明 Bash 專屬功能如 `[[ ]]`、陣列、參數展開、Here Strings 與 Process Substitution 如何提升程式碼品質。此外,技能包含偵測 Shell 類型的程式碼片段、常見可攜性陷阱(如 `echo` vs `printf`、變數賦值、Export 語法、不用陣列的列舉操作),並提供可攜性決策指南,協助開發者在最小系統與完整 Bash 環境之間做出最佳選擇。這套指南適用於 Claude Code、Cursor 等 AI 代理工具,也適用於任何撰寫 Shell 腳本的開發者。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Jamie-BitFlight/claude_skills/tree/main/plugins/bash-development/skills/bash-portability

Installed? Explore more 寫作與編輯 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Bash 可攜性

撰寫可攜式 POSIX 相容腳本,並了解何時善用 Bash 特定功能的指南。

Shebang 選擇

Bash 腳本使用 #!/usr/bin/env bash

#!/usr/bin/env bash

原因: 搜尋 PATH 中的 bash,可在 bash 位於不同位置的系統上運作。

POSIX 腳本使用 #!/bin/sh

#!/bin/sh

原因: 當不需要 Bash 功能時,達到最大可攜性。在許多系統上,/bin/sh 是 dash 或其他 POSIX Shell。

必要時使用絕對路徑

#!/bin/bash

僅在以下情況使用: 系統需求保證 bash 的位置,或安全政策要求絕對路徑。

POSIX 與 Bash 功能對照表

功能POSIXBash建議
[[ ]]否是POSIX 請用 [ ]
(( ))否是POSIX 請用 [ ] 搭配 -eq 等
陣列否是改用位置參數或檔案
local部分是通常安全
${var,,}否4+POSIX 請用 tr
<<<否是使用 `echo
=~ 正則表達式否是使用 grep 或 expr
source否是使用 .(點)命令
function f()否是僅使用 f()
$'...'否是使用 printf
{1..10}否是使用 seq 或 while 迴圈

POSIX 相容模式

條件判斷

# POSIX - 使用 [ ] 並正確引號
if [ -f "$file" ]; then
    echo "檔案存在"
fi

# 字串比較
if [ "$var" = "value" ]; then
    echo "符合"
fi

# 數字比較
if [ "$num" -gt 10 ]; then
    echo "更大"
fi

# 複合條件
if [ -f "$file" ] && [ -r "$file" ]; then
    echo "可讀取的檔案"
fi

大小寫轉換(POSIX)

# 轉小寫
lower=$(echo "$string" | tr '[:upper:]' '[:lower:]')

# 轉大寫
upper=$(echo "$string" | tr '[:lower:]' '[:upper:]')

子字串操作(POSIX)

# 取得子字串 - 使用 expr 或 cut
substr=$(expr "$string" : '.\(.\)')  # 第4-8個字元
substr=$(echo "$string" | cut -c4-8)

# 字串長度
length=$(expr length "$string")
length=${#string}  # 這其實是 POSIX 的

讀取檔案(POSIX)

# 逐行讀取
while IFS= read -r line; do
    echo "$line"
done < "$file"

# 讀取整個檔案(不使用 cat)
content=$(cat "$file")  # cat 是 POSIX 的

命令替換

# 現代語法(即使在 POSIX 中也較佳)
result=$(command)

# 傳統語法(避免使用)
result=`command`

# 巢狀(為何現代語法更好)
result=$(echo $(date))      # 清晰
result=`echo \`date\``      # 跳脫噩夢

值得使用的 Bash 特有功能

當可攜性不是必要條件時,這些 Bash 功能可提升程式碼品質:

擴展測試 [[ ]]

# 模式比對
[[ "$file" == *.txt ]]

# 正則表達式比對
[[ "$input" =~ ^[0-9]+$ ]]

# 不用擔心單詞分割
[[ -f $file ]]  # 引號可選(但仍建議使用)

# 內部邏輯運算子
[[ -f "$file" && -r "$file" ]]

陣列

# 索引陣列
declare -a files=()
files+=("one.txt")
files+=("two.txt")
for f in "${files[@]}"; do
    process "$f"
done

# 關聯陣列(Bash 4+)
declare -A config
config[host]="localhost"
config[port]="8080"

參數展開

# 預設值
"${var:-default}"

# 大小寫轉換(Bash 4+)
"${var,,}"  # 小寫
"${var^^}"  # 大寫

# 子字串
"${var:0:10}"  # 前10個字元
"${var: -5}"   # 後5個字元

# 搜尋/取代
"${var//old/new}"

Here Strings

# Bash
read -r var <<< "input string"

# POSIX 等價寫法
var=$(echo "input string")

Process Substitution

# Bash - 比較兩個命令的輸出
diff <(sort file1) <(sort file2)

# POSIX 等價寫法(使用暫存檔)
sort file1 > /tmp/sorted1
sort file2 > /tmp/sorted2
diff /tmp/sorted1 /tmp/sorted2

偵測 Shell 類型

# 檢查是否在 Bash 中執行
if [ -n "${BASH_VERSION:-}" ]; then
    echo "正在 Bash 中執行"
fi

# 檢查 Bash 版本以使用特定功能
if [ "${BASH_VERSINFO[0]:-0}" -ge 4 ]; then
    echo "可使用 Bash 4+"
fi

# 通用 Shell 偵測
case "${SHELL##*/}" in
    bash) echo "bash" ;;
    zsh)  echo "zsh" ;;
    *)    echo "其他" ;;
esac

可攜式工具函式

程式碼範例

可攜性決策指南

使用 POSIX 當:

  • 腳本在最小系統(容器、嵌入式)上執行
  • 目標包含 dash、ash 或 busybox sh
  • 需要最大相容性
  • 腳本是系統初始化的一部分

使用 Bash 當:

  • 目標系統保證有 bash
  • 需要陣列、關聯陣列或正則表達式
  • 需要複雜的字串操作
  • 程式碼清晰度顯著提升
  • 需要互動式功能

常見可攜性陷阱

echo 與 printf

# 有問題 - 行為因系統而異
echo -n "不換行"
echo -e "帶\t定位字元"

# 可攜式
printf '%s' "不換行"
printf '帶\t定位字元\n'

變數賦值

# 所有地方都可運作
var="value"

# 在某些 Shell 上可能失敗
var = "value"  # 等號周圍的空格是錯誤的

Export 賦值

# POSIX - 分開的命令
var="value"
export var

# Bash/現代 - 合併(大部分地方可運作)
export var="value"

不使用陣列的類陣列操作

# 使用位置參數
set -- "item1" "item2" "item3"
for item in "$@"; do
    echo "$item"
done

# 或使用 IFS 分割
items="item1:item2:item3"
IFS=':' read -r item1 item2 item3 <<EOF
$items
EOF

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-lint

This skill should be used when the user asks to "lint bash script", "run shellcheck", "format shell script", "use shfmt", "fix shellcheck errors", or mentions shell script linting, formatting, code quality, or pre-commit hooks for bash.

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-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).

相關技能