claude-cac 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cac +127 -136
- package/package.json +1 -1
package/cac
CHANGED
|
@@ -10,7 +10,7 @@ VERSIONS_DIR="$CAC_DIR/versions"
|
|
|
10
10
|
# ━━━ utils.sh ━━━
|
|
11
11
|
# ── utils: 颜色、读写、UUID、proxy 解析 ───────────────────────
|
|
12
12
|
|
|
13
|
-
CAC_VERSION="1.1.
|
|
13
|
+
CAC_VERSION="1.1.7"
|
|
14
14
|
|
|
15
15
|
_read() { [[ -f "$1" ]] && tr -d '[:space:]' < "$1" || echo "${2:-}"; }
|
|
16
16
|
_die() { printf '%b\n' "$(_red "error:") $*" >&2; exit 1; }
|
|
@@ -1195,20 +1195,20 @@ _ensure_initialized() {
|
|
|
1195
1195
|
mkdir -p "$CAC_DIR" "$ENVS_DIR" "$VERSIONS_DIR"
|
|
1196
1196
|
|
|
1197
1197
|
# Always sync JS hooks + dns-guard (they update with cac versions)
|
|
1198
|
-
#
|
|
1199
|
-
|
|
1200
|
-
#
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1198
|
+
# Find the real package directory — npm creates symlinks:
|
|
1199
|
+
# ~/.nvm/.../bin/cac → ../lib/node_modules/claude-cac/cac
|
|
1200
|
+
# relay.js and fingerprint-hook.js live alongside the real cac script
|
|
1201
|
+
local _self_dir=""
|
|
1202
|
+
local _cac_bin; _cac_bin="$(command -v cac 2>/dev/null || true)"
|
|
1203
|
+
if [[ -n "$_cac_bin" ]] && [[ -L "$_cac_bin" ]]; then
|
|
1204
|
+
local _link; _link="$(readlink "$_cac_bin")"
|
|
1205
|
+
[[ "$_link" != /* ]] && _link="$(dirname "$_cac_bin")/$_link"
|
|
1206
|
+
_self_dir="$(cd "$(dirname "$_link")" && pwd)"
|
|
1207
|
+
fi
|
|
1208
|
+
# Fallback: directory of the running script
|
|
1209
|
+
if [[ -z "$_self_dir" ]] || [[ ! -f "$_self_dir/relay.js" ]]; then
|
|
1210
|
+
_self_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
|
|
1211
|
+
fi
|
|
1212
1212
|
[[ -f "$_self_dir/fingerprint-hook.js" ]] && cp "$_self_dir/fingerprint-hook.js" "$CAC_DIR/fingerprint-hook.js"
|
|
1213
1213
|
[[ -f "$_self_dir/relay.js" ]] && cp "$_self_dir/relay.js" "$CAC_DIR/relay.js"
|
|
1214
1214
|
_write_dns_guard_js 2>/dev/null || true
|
|
@@ -1694,16 +1694,16 @@ cmd_relay() {
|
|
|
1694
1694
|
# ━━━ cmd_check.sh ━━━
|
|
1695
1695
|
# ── cmd: check ─────────────────────────────────────────────────
|
|
1696
1696
|
|
|
1697
|
-
#
|
|
1697
|
+
# 检测本地代理软件冲突
|
|
1698
1698
|
_check_proxy_conflict() {
|
|
1699
|
-
local proxy="$1" proxy_ip="$2"
|
|
1699
|
+
local proxy="$1" proxy_ip="$2" verbose="$3"
|
|
1700
1700
|
local proxy_hp; proxy_hp=$(_proxy_host_port "$proxy")
|
|
1701
1701
|
local proxy_host="${proxy_hp%%:*}"
|
|
1702
1702
|
|
|
1703
1703
|
local os; os=$(_detect_os)
|
|
1704
1704
|
local conflicts=()
|
|
1705
1705
|
|
|
1706
|
-
#
|
|
1706
|
+
# 检测 TUN 模式进程
|
|
1707
1707
|
local tun_procs="clash|mihomo|sing-box|surge|shadowrocket|v2ray|xray|hysteria|tuic|nekoray"
|
|
1708
1708
|
local running
|
|
1709
1709
|
if [[ "$os" == "macos" ]]; then
|
|
@@ -1711,29 +1711,22 @@ _check_proxy_conflict() {
|
|
|
1711
1711
|
else
|
|
1712
1712
|
running=$(ps -eo comm 2>/dev/null | grep -iE "$tun_procs" || true)
|
|
1713
1713
|
fi
|
|
1714
|
-
|
|
1715
1714
|
if [[ -n "$running" ]]; then
|
|
1716
1715
|
local proc_names
|
|
1717
1716
|
proc_names=$(echo "$running" | grep -ioE "$tun_procs" | sort -u | head -3)
|
|
1718
|
-
|
|
1719
|
-
conflicts+=("检测到本地代理进程: $(echo "$proc_names" | tr '\n' ' ')")
|
|
1720
|
-
fi
|
|
1717
|
+
[[ -n "$proc_names" ]] && conflicts+=("本地代理进程: $(echo "$proc_names" | tr '\n' ' ')")
|
|
1721
1718
|
fi
|
|
1722
1719
|
|
|
1723
|
-
#
|
|
1720
|
+
# 检测 TUN 网卡
|
|
1724
1721
|
if [[ "$os" == "macos" ]]; then
|
|
1725
1722
|
local tun_count
|
|
1726
1723
|
tun_count=$(ifconfig 2>/dev/null | grep -cE '^utun[0-9]+' || echo 0)
|
|
1727
|
-
|
|
1728
|
-
conflicts+=("检测到多个 TUN 网卡 (${tun_count} 个),可能有代理软件启用了 TUN 模式")
|
|
1729
|
-
fi
|
|
1724
|
+
[[ "$tun_count" -gt 3 ]] && conflicts+=("TUN 网卡 ${tun_count} 个")
|
|
1730
1725
|
elif [[ "$os" == "linux" ]]; then
|
|
1731
|
-
|
|
1732
|
-
conflicts+=("检测到 tun0 网卡,可能有代理软件启用了 TUN 模式")
|
|
1733
|
-
fi
|
|
1726
|
+
ip link show tun0 >/dev/null 2>&1 && conflicts+=("检测到 tun0")
|
|
1734
1727
|
fi
|
|
1735
1728
|
|
|
1736
|
-
#
|
|
1729
|
+
# 检测系统代理(macOS)
|
|
1737
1730
|
if [[ "$os" == "macos" ]]; then
|
|
1738
1731
|
local net_service
|
|
1739
1732
|
net_service=$(networksetup -listallnetworkservices 2>/dev/null | grep -iE 'Wi-Fi|Ethernet|以太网' | head -1 || true)
|
|
@@ -1741,172 +1734,170 @@ _check_proxy_conflict() {
|
|
|
1741
1734
|
local sys_http_proxy
|
|
1742
1735
|
sys_http_proxy=$(networksetup -getwebproxy "$net_service" 2>/dev/null || true)
|
|
1743
1736
|
if echo "$sys_http_proxy" | grep -qi "Enabled: Yes"; then
|
|
1744
|
-
local sys_host
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
[[ -n "$sys_host" ]] && conflicts+=("系统 HTTP 代理已开启: ${sys_host}:${sys_port}")
|
|
1737
|
+
local sys_host; sys_host=$(echo "$sys_http_proxy" | awk '/^Server:/{print $2}')
|
|
1738
|
+
local sys_port; sys_port=$(echo "$sys_http_proxy" | awk '/^Port:/{print $2}')
|
|
1739
|
+
[[ -n "$sys_host" ]] && conflicts+=("系统代理: ${sys_host}:${sys_port}")
|
|
1748
1740
|
fi
|
|
1749
1741
|
fi
|
|
1750
1742
|
fi
|
|
1751
1743
|
|
|
1752
|
-
#
|
|
1744
|
+
# 检测双重代理
|
|
1753
1745
|
local direct_ip
|
|
1754
1746
|
direct_ip=$(curl -s --noproxy '*' --connect-timeout 5 https://api.ipify.org 2>/dev/null || true)
|
|
1755
1747
|
if [[ -n "$direct_ip" ]] && [[ -n "$proxy_ip" ]] && [[ "$direct_ip" == "$proxy_ip" ]]; then
|
|
1756
|
-
conflicts+=("
|
|
1748
|
+
conflicts+=("出口 IP 与直连相同,可能被拦截")
|
|
1757
1749
|
fi
|
|
1758
1750
|
|
|
1759
|
-
#
|
|
1751
|
+
# 无冲突
|
|
1760
1752
|
if [[ ${#conflicts[@]} -eq 0 ]]; then
|
|
1761
|
-
echo "$(_green "✓") 未检测到代理冲突"
|
|
1762
1753
|
return 0
|
|
1763
1754
|
fi
|
|
1764
1755
|
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
echo " $(_dim "•") $msg"
|
|
1768
|
-
done
|
|
1769
|
-
|
|
1770
|
-
# 验证 relay 能否实际绕过
|
|
1756
|
+
# 验证 relay 能否绕过
|
|
1757
|
+
local relay_ok=false
|
|
1771
1758
|
if _relay_is_running 2>/dev/null; then
|
|
1772
1759
|
local rport; rport=$(_read "$CAC_DIR/relay.port" "")
|
|
1773
1760
|
local relay_ip
|
|
1774
1761
|
relay_ip=$(curl -s --proxy "http://127.0.0.1:$rport" --connect-timeout 8 https://api.ipify.org 2>/dev/null || true)
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
return 0
|
|
1778
|
-
fi
|
|
1779
|
-
fi
|
|
1780
|
-
|
|
1781
|
-
# relay 未运行,尝试启动测试
|
|
1782
|
-
if [[ -f "$CAC_DIR/relay.js" ]]; then
|
|
1762
|
+
[[ -n "$relay_ip" ]] && relay_ok=true
|
|
1763
|
+
elif [[ -f "$CAC_DIR/relay.js" ]]; then
|
|
1783
1764
|
local _test_env; _test_env=$(_current_env)
|
|
1784
1765
|
if _relay_start "$_test_env" 2>/dev/null; then
|
|
1785
1766
|
local rport; rport=$(_read "$CAC_DIR/relay.port" "")
|
|
1786
1767
|
local relay_ip
|
|
1787
1768
|
relay_ip=$(curl -s --proxy "http://127.0.0.1:$rport" --connect-timeout 8 https://api.ipify.org 2>/dev/null || true)
|
|
1788
1769
|
_relay_stop 2>/dev/null || true
|
|
1789
|
-
|
|
1790
|
-
echo " $(_green "→") relay 测试连通 (出口: $(_cyan "$relay_ip")),claude 启动时会自动绕过"
|
|
1791
|
-
return 0
|
|
1792
|
-
fi
|
|
1770
|
+
[[ -n "$relay_ip" ]] && relay_ok=true
|
|
1793
1771
|
fi
|
|
1794
1772
|
fi
|
|
1795
1773
|
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1774
|
+
if [[ "$relay_ok" == "true" ]]; then
|
|
1775
|
+
echo "$(_green "✓") relay 自动绕过"
|
|
1776
|
+
if [[ "$verbose" == "true" ]]; then
|
|
1777
|
+
for msg in "${conflicts[@]}"; do
|
|
1778
|
+
echo " $(_dim "$msg")"
|
|
1779
|
+
done
|
|
1780
|
+
fi
|
|
1781
|
+
return 0
|
|
1782
|
+
fi
|
|
1783
|
+
|
|
1784
|
+
# relay 失败
|
|
1785
|
+
echo "$(_red "✗") 代理冲突,需手动处理"
|
|
1786
|
+
for msg in "${conflicts[@]}"; do
|
|
1787
|
+
echo " $(_yellow "•") $msg"
|
|
1788
|
+
done
|
|
1789
|
+
echo " 解决:在代理软件中为 $(_bold "$proxy_host") 添加 DIRECT 规则"
|
|
1800
1790
|
return 1
|
|
1801
1791
|
}
|
|
1802
1792
|
|
|
1803
1793
|
cmd_check() {
|
|
1804
1794
|
_require_setup
|
|
1805
1795
|
|
|
1796
|
+
local verbose=false
|
|
1797
|
+
[[ "${1:-}" == "-d" || "${1:-}" == "--detail" ]] && verbose=true
|
|
1798
|
+
|
|
1806
1799
|
local current; current=$(_current_env)
|
|
1807
1800
|
|
|
1808
1801
|
if [[ -f "$CAC_DIR/stopped" ]]; then
|
|
1809
|
-
echo "$(_yellow "⚠ cac
|
|
1810
|
-
echo " 恢复:cac ${current:-<name>}"
|
|
1802
|
+
echo "$(_yellow "⚠") cac 已停用 — 运行 'cac <name>' 恢复"
|
|
1811
1803
|
return
|
|
1812
1804
|
fi
|
|
1813
|
-
|
|
1814
1805
|
if [[ -z "$current" ]]; then
|
|
1815
1806
|
echo "错误:未激活任何环境,运行 'cac <name>'" >&2; exit 1
|
|
1816
1807
|
fi
|
|
1817
1808
|
|
|
1818
1809
|
local env_dir="$ENVS_DIR/$current"
|
|
1819
1810
|
local proxy; proxy=$(_read "$env_dir/proxy" "")
|
|
1811
|
+
local ver; ver=$(_read "$env_dir/version" "system")
|
|
1820
1812
|
|
|
1821
|
-
|
|
1822
|
-
echo "
|
|
1823
|
-
echo " UUID :$(_read "$env_dir/uuid")"
|
|
1824
|
-
echo " stable_id :$(_read "$env_dir/stable_id")"
|
|
1825
|
-
echo " user_id :$(_read "$env_dir/user_id" "(旧环境,无此字段)")"
|
|
1826
|
-
echo " 版本 :$(_read "$env_dir/version" "system")"
|
|
1827
|
-
echo " TZ :$(_read "$env_dir/tz" "(未设置)")"
|
|
1828
|
-
echo " LANG :$(_read "$env_dir/lang" "(未设置)")"
|
|
1829
|
-
echo
|
|
1813
|
+
# ── 基本信息 ──
|
|
1814
|
+
echo "$(_bold "$current") (claude: $(_cyan "$ver"))"
|
|
1830
1815
|
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
echo "$(_green "✓")"
|
|
1838
|
-
|
|
1839
|
-
printf " 出口 IP ... "
|
|
1840
|
-
local proxy_ip
|
|
1841
|
-
proxy_ip=$(curl -s --proxy "$proxy" \
|
|
1842
|
-
--connect-timeout 8 https://api.ipify.org 2>/dev/null || true)
|
|
1843
|
-
if [[ -n "$proxy_ip" ]]; then
|
|
1844
|
-
echo "$(_green "$proxy_ip")"
|
|
1845
|
-
else
|
|
1846
|
-
echo "$(_yellow "获取失败")"
|
|
1847
|
-
fi
|
|
1848
|
-
else
|
|
1849
|
-
echo " $(_dim "(无代理,跳过网络检查)")"
|
|
1816
|
+
if [[ "$verbose" == "true" ]]; then
|
|
1817
|
+
echo " UUID : $(_read "$env_dir/uuid")"
|
|
1818
|
+
echo " stable_id : $(_read "$env_dir/stable_id")"
|
|
1819
|
+
echo " user_id : $(_read "$env_dir/user_id" "—")"
|
|
1820
|
+
echo " TZ : $(_read "$env_dir/tz" "—")"
|
|
1821
|
+
echo " LANG : $(_read "$env_dir/lang" "—")"
|
|
1850
1822
|
fi
|
|
1851
1823
|
|
|
1852
|
-
# ──
|
|
1824
|
+
# ── 网络 ──
|
|
1825
|
+
local proxy_ip=""
|
|
1853
1826
|
if [[ -n "$proxy" ]]; then
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1827
|
+
printf " 代理 : "
|
|
1828
|
+
if ! _proxy_reachable "$proxy"; then
|
|
1829
|
+
echo "$(_red "✗ 不通") ($proxy)"
|
|
1830
|
+
return
|
|
1831
|
+
fi
|
|
1832
|
+
proxy_ip=$(curl -s --proxy "$proxy" --connect-timeout 8 https://api.ipify.org 2>/dev/null || true)
|
|
1833
|
+
echo "$(_green "✓") ${proxy_ip:-?} $(_dim "via ${proxy%%@*}@...")"
|
|
1859
1834
|
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
local rpid; rpid=$(_read "$CAC_DIR/relay.pid")
|
|
1864
|
-
local rport; rport=$(_read "$CAC_DIR/relay.port" "未知")
|
|
1865
|
-
echo " Relay ... $(_green "运行中") (PID=$rpid, 端口=$rport)"
|
|
1866
|
-
elif [[ -n "$proxy" ]]; then
|
|
1867
|
-
echo " Relay ... $(_dim "未运行(claude 启动时按需自动启用)")"
|
|
1835
|
+
# 冲突检测
|
|
1836
|
+
printf " 冲突检测 : "
|
|
1837
|
+
_check_proxy_conflict "$proxy" "${proxy_ip:-}" "$verbose"
|
|
1868
1838
|
else
|
|
1869
|
-
echo "
|
|
1839
|
+
echo " 代理 : $(_dim "无(API Key 模式)")"
|
|
1870
1840
|
fi
|
|
1871
1841
|
|
|
1872
|
-
|
|
1873
|
-
echo "── 安全防护状态 ──────────────────────────────────────"
|
|
1874
|
-
|
|
1875
|
-
# ── NS 层级 DNS 拦截 ──
|
|
1876
|
-
printf " DNS 拦截 ... "
|
|
1877
|
-
_check_dns_block "statsig.anthropic.com"
|
|
1878
|
-
|
|
1879
|
-
# ── 多层环境变量保护(单次读取 wrapper 文件)──
|
|
1880
|
-
echo " 环境变量保护:"
|
|
1842
|
+
# ── 安全防护(简洁模式只显示计数)──
|
|
1881
1843
|
local wrapper_file="$CAC_DIR/bin/claude"
|
|
1882
1844
|
local wrapper_content=""
|
|
1883
1845
|
[[ -f "$wrapper_file" ]] && wrapper_content=$(<"$wrapper_file")
|
|
1884
1846
|
local env_vars=(
|
|
1885
|
-
"CLAUDE_CODE_ENABLE_TELEMETRY"
|
|
1886
|
-
"
|
|
1887
|
-
"
|
|
1888
|
-
"
|
|
1889
|
-
"OTEL_METRICS_EXPORTER"
|
|
1890
|
-
"OTEL_LOGS_EXPORTER"
|
|
1891
|
-
"SENTRY_DSN"
|
|
1892
|
-
"DISABLE_ERROR_REPORTING"
|
|
1893
|
-
"DISABLE_BUG_COMMAND"
|
|
1894
|
-
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"
|
|
1895
|
-
"TELEMETRY_DISABLED"
|
|
1896
|
-
"DISABLE_TELEMETRY"
|
|
1847
|
+
"CLAUDE_CODE_ENABLE_TELEMETRY" "DO_NOT_TRACK"
|
|
1848
|
+
"OTEL_SDK_DISABLED" "OTEL_TRACES_EXPORTER" "OTEL_METRICS_EXPORTER" "OTEL_LOGS_EXPORTER"
|
|
1849
|
+
"SENTRY_DSN" "DISABLE_ERROR_REPORTING" "DISABLE_BUG_COMMAND"
|
|
1850
|
+
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC" "TELEMETRY_DISABLED" "DISABLE_TELEMETRY"
|
|
1897
1851
|
)
|
|
1852
|
+
local env_ok=0 env_total=${#env_vars[@]}
|
|
1898
1853
|
for var in "${env_vars[@]}"; do
|
|
1899
|
-
|
|
1900
|
-
if [[ "$wrapper_content" == *"$var"* ]]; then
|
|
1901
|
-
echo "$(_green "✓ 已配置")"
|
|
1902
|
-
else
|
|
1903
|
-
echo "$(_red "✗ 未找到")"
|
|
1904
|
-
fi
|
|
1854
|
+
[[ "$wrapper_content" == *"$var"* ]] && (( env_ok++ )) || true
|
|
1905
1855
|
done
|
|
1906
1856
|
|
|
1907
|
-
#
|
|
1908
|
-
|
|
1909
|
-
|
|
1857
|
+
# DNS 拦截
|
|
1858
|
+
local dns_ok=false
|
|
1859
|
+
if [[ -f "$CAC_DIR/cac-dns-guard.js" ]]; then
|
|
1860
|
+
local dns_result
|
|
1861
|
+
dns_result=$(node -e '
|
|
1862
|
+
require(process.argv[1]);
|
|
1863
|
+
var dns = require("dns");
|
|
1864
|
+
dns.lookup(process.argv[2], function(err) {
|
|
1865
|
+
process.stdout.write(err && (err.code === "ECONNREFUSED" || err.code === "ENOTFOUND") ? "BLOCKED" : "OPEN");
|
|
1866
|
+
});
|
|
1867
|
+
' "$CAC_DIR/cac-dns-guard.js" "statsig.anthropic.com" 2>/dev/null || echo "ERROR")
|
|
1868
|
+
[[ "$dns_result" == "BLOCKED" ]] && dns_ok=true
|
|
1869
|
+
fi
|
|
1870
|
+
|
|
1871
|
+
# mTLS
|
|
1872
|
+
local mtls_ok=false
|
|
1873
|
+
local ca_cert="$CAC_DIR/ca/ca_cert.pem"
|
|
1874
|
+
local client_cert="$env_dir/client_cert.pem"
|
|
1875
|
+
[[ -f "$ca_cert" ]] && [[ -f "$client_cert" ]] && \
|
|
1876
|
+
openssl verify -CAfile "$ca_cert" "$client_cert" >/dev/null 2>&1 && mtls_ok=true
|
|
1877
|
+
|
|
1878
|
+
if [[ "$verbose" == "true" ]]; then
|
|
1879
|
+
printf " DNS 拦截 : "
|
|
1880
|
+
[[ "$dns_ok" == "true" ]] && echo "$(_green "✓")" || echo "$(_red "✗")"
|
|
1881
|
+
echo " 遥测屏蔽 : ${env_ok}/${env_total} 环境变量"
|
|
1882
|
+
for var in "${env_vars[@]}"; do
|
|
1883
|
+
printf " %-36s" "$var"
|
|
1884
|
+
[[ "$wrapper_content" == *"$var"* ]] && echo "$(_green "✓")" || echo "$(_red "✗")"
|
|
1885
|
+
done
|
|
1886
|
+
printf " mTLS : "
|
|
1887
|
+
[[ "$mtls_ok" == "true" ]] && echo "$(_green "✓")" || echo "$(_yellow "—")"
|
|
1888
|
+
else
|
|
1889
|
+
local checks=() fails=()
|
|
1890
|
+
[[ "$dns_ok" == "true" ]] && checks+=("DNS 拦截") || fails+=("DNS 拦截")
|
|
1891
|
+
[[ "$env_ok" -eq "$env_total" ]] && checks+=("遥测屏蔽 ${env_ok}/${env_total}") || fails+=("遥测屏蔽 ${env_ok}/${env_total}")
|
|
1892
|
+
[[ "$mtls_ok" == "true" ]] && checks+=("mTLS") || true
|
|
1893
|
+
|
|
1894
|
+
printf " 防护 : "
|
|
1895
|
+
if [[ ${#fails[@]} -eq 0 ]]; then
|
|
1896
|
+
echo "$(_green "✓") $(IFS=', '; echo "${checks[*]}")"
|
|
1897
|
+
else
|
|
1898
|
+
echo "$(_yellow "⚠") $(IFS=', '; echo "${fails[*]}")"
|
|
1899
|
+
fi
|
|
1900
|
+
fi
|
|
1910
1901
|
}
|
|
1911
1902
|
|
|
1912
1903
|
# ━━━ cmd_stop.sh ━━━
|