SuperAPI AI 工具集

shell-portability

编程与开发

查看项目

更新于 10-16 02:04

技能介绍

用途

Shell 脚本可移植性(shell-portability)是一份面向 Shell 脚本编写的技能资料,适用于需要让脚本在不同系统、不同 Shell 或不同环境中运行的场景。其核心目标是帮助开发者处理 POSIX 兼容性与平台差异,使脚本具备跨平台能力。

主要能力

Shebang 选择

资料给出两种 shebang 写法:

  • Bash 脚本:#!/usr/bin/env bash,被描述为对 bash 脚本最可移植,可在 Linux、macOS、BSD 上工作。
  • POSIX Shell 脚本:#!/bin/sh,用于最大可移植性,仅使用 POSIX 特性。

Bash 与 POSIX 差异

资料从四个方面对比:

  • 数组:Bash 可用 declare -a items=("one" "two" "three") 与 for item in "${items[@]}";POSIX 则使用位置参数或空格分隔字符串,如 set -- one two three 配合 for item in "$@"。
  • Test 语法:Bash 使用扩展 test [[ "$var" == "value" ]];POSIX 使用基础 test [ "$var" = "value" ]。
  • 字符串操作:Bash 支持正则匹配 [[ "$input" =~ ^[0-9]+$ ]];POSIX 使用 case 或外部工具判断,例如 case "$input" in *[!0-9]*|'') echo "not numeric" ;; *) echo "numeric" ;; esac。
  • 算术:Bash 使用算术展开 (( count++ )) 与 if (( count > 10 ));POSIX 使用 count=$((count + 1)) 与 if [ "$count" -gt 10 ]。

平台差异

资料列举了 macOS 与 Linux 的常见差异及可移植写法:

  • date 命令:GNU(Linux)使用 date -d "yesterday" +%Y-%m-%d;BSD(macOS)使用 date -v-1d +%Y-%m-%d。可移植做法是先通过 date --version 判断是否为 GNU date,再分别调用。
  • sed 差异:GNU sed 使用 sed -i 's/old/new/g' file.txt;BSD sed 需要备份扩展名 sed -i '' 's/old/new/g' file.txt。可移植做法是重定向到临时文件再移动,或封装 sed_inplace 函数,通过 sed --version 判断后分别调用。
  • readlink 差异:GNU readlink 支持 readlink -f /path/to/link;BSD/macOS 默认没有 -f 选项。资料给出 resolve_path 函数,优先使用 greadlink,其次 realpath,最后回退到 cd "$(dirname "$path")" && pwd -P。

环境检测

资料提供三个检测函数:

  • 操作系统检测 detect_os:通过 uname -s 判断 Linux、macOS、Windows(MINGW/CYGWIN/MSYS)、FreeBSD 或 unknown,并据此选择安装命令(如 apt-get install 或 brew install)。
  • 架构检测 detect_arch:通过 uname -m 映射为 amd64、arm64、arm 或 unknown。
  • Shell 检测 detect_shell:根据 $BASH_VERSION、$ZSH_VERSION 判断 bash、zsh 或 sh。

可移植模式

资料给出若干可移植写法:

  • 读取文件:while IFS= read -r line || [ -n "$line" ]; do ... done < "$file",其中 || [ -n "$line" ] 用于处理没有结尾换行的文件。
  • 临时文件:make_temp 函数优先使用 mktemp,否则回退到 /tmp/tmp.$$.$RANDOM。
  • 命令存在性检查:has_command 函数使用 command -v "$1" >/dev/null 2>&1,并示例在 curl 与 wget 之间选择。
  • 字符串包含:contains 函数使用 case "$1" in *"$2"*) return 0 ;; *) return 1 ;; esac。

ShellCheck 兼容

资料说明在有意使用非可移植特性时,可用 # shellcheck disable=SC2039 等指令禁用警告,并建议注释说明原因。同时给出测试多种 Shell 时的指令写法,如 # shellcheck shell=bash 或 # shellcheck shell=sh。

使用方式

该技能以参考文档形式提供,使用者在编写 Shell 脚本时按需查阅对应章节,将示例代码或函数模式应用到自己的脚本中。资料未提供安装命令或调用接口。

适用场景

  • 需要跨 Linux、macOS、BSD 等平台运行的 Shell 脚本。
  • 需要在 bash 与 POSIX sh 之间做兼容取舍的脚本。
  • 需要处理 date、sed、readlink 等命令平台差异的脚本。
  • 需要在脚本中检测操作系统、架构或当前 Shell 的场景。
  • 需要编写可移植的文件读取、临时文件、命令检查等通用逻辑的场景。

限制

资料未说明该技能的运行环境要求、依赖版本、授权方式或收费信息。示例代码仅覆盖资料中列出的差异点,未涵盖所有可能的平台或 Shell 差异。