用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/majiayu000/claude-skill-registry --skill shell-script-review命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
LLM token logprobs and calibration. Per-decision confidence, ECE, Brier, reliability diagrams, low-confidence triage.
Analyze LLM token logprobs and calibration. Use for per-decision confidence, ECE, Brier scores, reliability diagrams, and low-confidence triage.
回顾最近 N 天的 Claude Code 使用记录——扫描原始会话数据,按主题分组汇总"我都做了什么",并从个人操作系统视角输出模式、风险与增删建议。当用户说 /recap、"看看我这几天做了什么"、"回顾一下我最近的会话"、"这两天我用 claude 干了啥"、"活动回顾" 时使用。
基于 SOC 职业分类
正在显示 SKILL.md
| description | Skill for reviewing shell scripts with shell-neutral behavior with best efforts. |
| name | shell-script-review |
Currently, all the mainstream operating systems are using Bash as their default shell. However, many programmers like Zsh for its better interactive features.
Below we list several common different behaviors between Bash and Zsh, along with workarounds to write shell-neutral scripts that work in both shells.
if [ -f XXX ] then
...
fi
Suspecting everything itself is suspicious: If the file checked is a well committed file in this repo, DO NOT check for it existence at all!
If you are not sure, use git ls-files XXX to check if it is tracked by git.
Similarly for environment variables, check setup.sh and session-init.sh to see if these variables are always set by those scripts.
If so, DO NOT -z or -n check them!
arr=(apple banana cherry)
echo ${arr[0]} # apple
echo ${arr[1]} # banana
arr=(apple banana cherry)
echo ${arr[1]} # apple
echo ${arr[2]} # banana
#!/bin/bash # or #!/bin/zsh
[ -n "$ZSH_VERSION" ] && setopt KSH_ARRAYS
arr=(apple banana cherry)
echo ${arr[0]} # apple in both
for item in "${arr[@]}"; do
echo "$item"
done
Additionally, when parsing positional arguments, extract them to variables directly:
for item in "$@"; do
case $item in
--option)
option_value="$2"
shift 2
;;
*)
positional_args+=("$item")
shift
;;
esac
done
echo "$0" # /path/to/script.sh (or bash if sourced)
echo "${BASH_SOURCE[0]}" # /path/to/script.sh (always reliable)
echo "$0" # /path/to/script.sh (or function name if sourced!)
echo "${(%):-%x}" # /path/to/script.sh (reliable)
# BASH_SOURCE doesn't exist in zsh
A reliable way to get the script path in both shells:
#!/bin/bash
# Get script path reliably in both shells
if [ -n "$BASH_SOURCE" ]; then
SCRIPT_PATH="${BASH_SOURCE[0]}"
elif [ -n "$ZSH_VERSION" ]; then
SCRIPT_PATH="${(%):-%x}"
else
SCRIPT_PATH="$0"
fi
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
echo "Script location: $SCRIPT_DIR"
Another option is to reply on environment variables exported by setup.sh and we use
absolute paths based on those or absolute paths by git rev-parse.
var="one two three"
echo $var # one two three (3 arguments, split!)
echo "$var" # one two three (1 argument, safe)
for word in $var; do echo "$word"; done
# Outputs: one / two / three
var="one two three"
echo $var # one two three (1 argument, NO split by default!)
echo "$var" # one two three (1 argument)
for word in $var; do echo "$word"; done
# Outputs: one two three (as single item!)
# Need explicit splitting in zsh:
for word in ${=var}; do echo "$word"; done
# Outputs: one / two / three
#!/bin/bash
# Always quote variables for safety
var="one two three"
echo "$var"
# For intentional splitting, use arrays:
read -ra words <<< "$var"
for word in "${words[@]}"; do
echo "$word"
done
# Recursive glob needs enabling
shopt -s globstar
echo **/*.txt
# No ** support without the option
echo *.txt # Only current directory
# Recursive glob works by default
echo **/*.txt
# Advanced patterns
echo **/*.txt~*test* # Exclude files with 'test'
echo *.txt(.) # Only regular files
#!/bin/bash
# Option 1: Use find instead of globs
find . -name "*.txt" -type f
# Option 2: Enable globstar in bash, works in zsh by default
if [ -n "$BASH_VERSION" ]; then
shopt -s globstar
fi
echo **/*.txt
# Option 3: Stick to simple globs
echo *.txt
Bash:
# Indexed array
arr=(a b c)
echo ${arr[0]} # a
# Associative array
declare -A map
map[key1]="value1"
map[key2]="value2"
echo ${map[key1]} # value1
Zsh:
# Indexed array (1-based!)
arr=(a b c)
echo ${arr[1]} # a
# Associative array (different syntax)
typeset -A map
map=(key1 value1 key2 value2)
# OR
map[key1]="value1"
echo ${map[key1]} # value1
#!/bin/bash
# Force bash-compatible arrays in zsh
[ -n "$ZSH_VERSION" ] && setopt KSH_ARRAYS
# Now arrays work the same way
arr=(a b c)
echo ${arr[0]} # a in both
# For associative arrays, use bash syntax
declare -A map 2>/dev/null || typeset -A map # Works in both
map[key1]="value1"
echo ${map[key1]}
## PATH Variable
```zsh
local path="screwed"
echo $PATH # screwed
In zsh, $path is an array view of the PATH variable, which can lead to confusion.
In bash, $path is just a regular variable.
Solution: Always use $PATH for environment variable access, and avoid using $path as variable name!
#!/bin/bash as shebang (more portable)"$var" not $var"${arr[@]}" for array expansion$path as in zsh, it is different view of the sameting, $PATH