Browse Source

```

feat(cursor): 提升Linux和Mac脚本的跨平台兼容性

- 新增sed_inplace函数,封装sed -i命令以兼容GNU/BSD sed的不同参数格式
- 修复JSON配置文件修改逻辑,使用awk替代sed处理多行JSON格式
- 优化Python脚本调用方式,使用sys.argv传递参数避免特殊字符导致的语法错误
- 统一配置修改流程,复用modify_or_add_config函数处理settings.json更新
- 移除直接字符串拼接到Python代码的危险做法,提升安全性
```
master
煎饼果子卷鲨鱼辣椒 2 weeks ago
parent
commit
9905d89135
  1. 142
      scripts/run/cursor_linux_id_modifier.sh
  2. 188
      scripts/run/cursor_mac_id_modifier.sh

142
scripts/run/cursor_linux_id_modifier.sh

@ -87,6 +87,33 @@ log_cmd_output() {
echo "" >> "$LOG_FILE"
}
# sed -i 兼容封装:优先原地编辑;不支持/失败时回退到临时文件替换,提升跨发行版兼容性
sed_inplace() {
local expr="$1"
local file="$2"
# GNU sed / BusyBox sed:通常支持 sed -i
if sed -i "$expr" "$file" 2>/dev/null; then
return 0
fi
# BSD sed:需要提供 -i '' 形式(少数环境可能出现)
if sed -i '' "$expr" "$file" 2>/dev/null; then
return 0
fi
# 最后兜底:临时文件替换(避免不同 sed 的 -i 语义差异)
local temp_file
temp_file=$(mktemp) || return 1
if sed "$expr" "$file" > "$temp_file"; then
cat "$temp_file" > "$file"
rm -f "$temp_file"
return 0
fi
rm -f "$temp_file"
return 1
}
# 获取当前用户
get_current_user() {
if [ "$EUID" -eq 0 ]; then
@ -609,12 +636,53 @@ modify_or_add_config() {
elif grep -q "}" "$file"; then
# key不存在, 在最后一个 '}' 前添加新的key-value对
# 注意:这种方式比较脆弱,如果 JSON 格式不标准或最后一行不是 '}' 会失败
sed '$ s/}/,\n "'$key'\": "'$value'\"\n}/' "$file" > "$temp_file" || {
log_error "添加配置失败 (注入): $key to $file"
rm -f "$temp_file"
chmod u-w "$file" # 恢复权限
return 1
}
# 🔧 兼容修复:不依赖 GNU sed 的 \n 替换扩展;同时避免在 `}` 独占一行时生成无效 JSON
if tail -n 1 "$file" | grep -Eq '^[[:space:]]*}[[:space:]]*$'; then
# 多行 JSON:在最后一个 `}` 前插入新行,并为上一条属性补上逗号
awk -v key="$key" -v value="$value" '
{ lines[NR] = $0 }
END {
brace = 0
for (i = NR; i >= 1; i--) {
if (lines[i] ~ /^[[:space:]]*}[[:space:]]*$/) { brace = i; break }
}
if (brace == 0) { exit 2 }
prev = 0
for (i = brace - 1; i >= 1; i--) {
if (lines[i] !~ /^[[:space:]]*$/) { prev = i; break }
}
if (prev > 0) {
line = lines[prev]
sub(/[[:space:]]*$/, "", line)
if (line !~ /{$/ && line !~ /,$/) {
lines[prev] = line ","
} else {
lines[prev] = line
}
}
insert_line = " \"" key "\": \"" value "\""
for (i = 1; i <= NR; i++) {
if (i == brace) { print insert_line }
print lines[i]
}
}
' "$file" > "$temp_file" || {
log_error "添加配置失败 (注入): $key to $file"
rm -f "$temp_file"
chmod u-w "$file" # 恢复权限
return 1
}
else
# 单行 JSON:直接在末尾 `}` 前插入键值(避免依赖 sed 的 \\n 扩展)
sed "s/}[[:space:]]*$/,\"$key\": \"$value\"}/" "$file" > "$temp_file" || {
log_error "添加配置失败 (注入): $key to $file"
rm -f "$temp_file"
chmod u-w "$file" # 恢复权限
return 1
}
fi
log_debug "已添加 key '$key' 到文件 '$file' 中"
else
log_error "无法确定如何添加配置: $key to $file (文件结构可能不标准)"
@ -1116,49 +1184,49 @@ EOF
# 如果直接把 someValue.machineId 替换成 "\"<真实值>\"",会形成 ""<真实值>"" 导致 JS 语法错误。
# 因此这里优先替换完整的字符串字面量(包含外层引号),再兜底替换不带引号的占位符。
if grep -q 'someValue\.machineId' "$file"; then
sed -i "s/\"someValue\.machineId\"/\"${machine_id}\"/g" "$file"
sed -i "s/'someValue\.machineId'/\"${machine_id}\"/g" "$file"
sed -i "s/someValue\.machineId/\"${machine_id}\"/g" "$file"
sed_inplace "s/\"someValue\.machineId\"/\"${machine_id}\"/g" "$file"
sed_inplace "s/'someValue\.machineId'/\"${machine_id}\"/g" "$file"
sed_inplace "s/someValue\.machineId/\"${machine_id}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.machineId"
replaced=true
fi
if grep -q 'someValue\.macMachineId' "$file"; then
sed -i "s/\"someValue\.macMachineId\"/\"${mac_machine_id}\"/g" "$file"
sed -i "s/'someValue\.macMachineId'/\"${mac_machine_id}\"/g" "$file"
sed -i "s/someValue\.macMachineId/\"${mac_machine_id}\"/g" "$file"
sed_inplace "s/\"someValue\.macMachineId\"/\"${mac_machine_id}\"/g" "$file"
sed_inplace "s/'someValue\.macMachineId'/\"${mac_machine_id}\"/g" "$file"
sed_inplace "s/someValue\.macMachineId/\"${mac_machine_id}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.macMachineId"
replaced=true
fi
if grep -q 'someValue\.devDeviceId' "$file"; then
sed -i "s/\"someValue\.devDeviceId\"/\"${device_id}\"/g" "$file"
sed -i "s/'someValue\.devDeviceId'/\"${device_id}\"/g" "$file"
sed -i "s/someValue\.devDeviceId/\"${device_id}\"/g" "$file"
sed_inplace "s/\"someValue\.devDeviceId\"/\"${device_id}\"/g" "$file"
sed_inplace "s/'someValue\.devDeviceId'/\"${device_id}\"/g" "$file"
sed_inplace "s/someValue\.devDeviceId/\"${device_id}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.devDeviceId"
replaced=true
fi
if grep -q 'someValue\.sqmId' "$file"; then
sed -i "s/\"someValue\.sqmId\"/\"${sqm_id}\"/g" "$file"
sed -i "s/'someValue\.sqmId'/\"${sqm_id}\"/g" "$file"
sed -i "s/someValue\.sqmId/\"${sqm_id}\"/g" "$file"
sed_inplace "s/\"someValue\.sqmId\"/\"${sqm_id}\"/g" "$file"
sed_inplace "s/'someValue\.sqmId'/\"${sqm_id}\"/g" "$file"
sed_inplace "s/someValue\.sqmId/\"${sqm_id}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sqmId"
replaced=true
fi
if grep -q 'someValue\.sessionId' "$file"; then
sed -i "s/\"someValue\.sessionId\"/\"${session_id}\"/g" "$file"
sed -i "s/'someValue\.sessionId'/\"${session_id}\"/g" "$file"
sed -i "s/someValue\.sessionId/\"${session_id}\"/g" "$file"
sed_inplace "s/\"someValue\.sessionId\"/\"${session_id}\"/g" "$file"
sed_inplace "s/'someValue\.sessionId'/\"${session_id}\"/g" "$file"
sed_inplace "s/someValue\.sessionId/\"${session_id}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sessionId"
replaced=true
fi
if grep -q 'someValue\.firstSessionDate' "$file"; then
sed -i "s/\"someValue\.firstSessionDate\"/\"${first_session_date}\"/g" "$file"
sed -i "s/'someValue\.firstSessionDate'/\"${first_session_date}\"/g" "$file"
sed -i "s/someValue\.firstSessionDate/\"${first_session_date}\"/g" "$file"
sed_inplace "s/\"someValue\.firstSessionDate\"/\"${first_session_date}\"/g" "$file"
sed_inplace "s/'someValue\.firstSessionDate'/\"${first_session_date}\"/g" "$file"
sed_inplace "s/someValue\.firstSessionDate/\"${first_session_date}\"/g" "$file"
log_info " ✓ [方案A] 替换 someValue.firstSessionDate"
replaced=true
fi
@ -1481,25 +1549,19 @@ disable_auto_update() {
# 备份
cp "$config" "${config}.bak_$(date +%Y%m%d%H%M%S)" 2>/dev/null
# 尝试修改 JSON (如果存在且是 settings.json)
if [[ "$config" == *settings.json ]]; then
# 尝试添加或修改 "update.mode": "none"
if grep -q '"update.mode"' "$config"; then
sed -i 's/"update.mode":[[:space:]]*"[^"]*"/"update.mode": "none"/' "$config" || log_warn "修改 settings.json 中的 update.mode 失败"
elif grep -q "}" "$config"; then # 尝试注入
sed -i '$ s/}/,\n "update.mode": "none"\n}/' "$config" || log_warn "注入 update.mode 到 settings.json 失败"
# 尝试修改 JSON (如果存在且是 settings.json)
if [[ "$config" == *settings.json ]]; then
# 🔧 兼容修复:复用 modify_or_add_config 统一处理替换/注入,避免 sed -i 与 \n 扩展差异
if modify_or_add_config "update.mode" "none" "$config"; then
((disabled_count++))
log_info "已尝试在 '$config' 中设置 'update.mode' 为 'none'"
else
log_warn "无法修改 settings.json 以禁用更新(结构未知)"
log_warn "修改 settings.json 中的 update.mode 失败: $config"
fi
# 确保权限正确
elif [[ "$config" == *update-config.json ]]; then
# 直接覆盖 update-config.json
echo '{"autoCheck": false, "autoDownload": false}' > "$config"
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$config" || log_warn "设置所有权失败: $config"
chmod 644 "$config" || log_warn "设置权限失败: $config"
((disabled_count++))
log_info "已尝试在 '$config' 中设置 'update.mode' 为 'none'"
elif [[ "$config" == *update-config.json ]]; then
# 直接覆盖 update-config.json
echo '{"autoCheck": false, "autoDownload": false}' > "$config"
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$config" || log_warn "设置所有权失败: $config"
chmod 644 "$config" || log_warn "设置权限失败: $config"
((disabled_count++))
log_info "已覆盖更新配置文件: $config"

188
scripts/run/cursor_mac_id_modifier.sh

@ -260,7 +260,8 @@ test_cursor_environment() {
issues+=("配置文件不存在: $config_path")
else
# 验证JSON格式
if python3 -c "import json; json.load(open('$config_path'))" 2>/dev/null; then
# 🔧 修复:避免把路径直接拼进 Python 源码字符串(路径包含引号等特殊字符时会导致语法错误)
if python3 -c 'import json, sys; json.load(open(sys.argv[1], "r", encoding="utf-8"))' "$config_path" 2>/dev/null; then
log_info "✅ [检查] 配置文件格式正确"
else
issues+=("配置文件格式错误或损坏")
@ -449,7 +450,8 @@ modify_machine_code_config() {
# 验证配置文件格式并显示结构
log_info "🔍 [验证] 检查配置文件格式..."
if ! python3 -c "import json; json.load(open('$config_path'))" 2>/dev/null; then
# 🔧 修复:避免把路径直接拼进 Python 源码字符串(路径包含引号等特殊字符时会导致语法错误)
if ! python3 -c 'import json, sys; json.load(open(sys.argv[1], "r", encoding="utf-8"))' "$config_path" 2>/dev/null; then
log_error "❌ [错误] 配置文件格式错误或损坏"
log_info "💡 [建议] 配置文件可能已损坏,建议选择'重置环境+修改机器码'选项"
return 1
@ -458,23 +460,26 @@ modify_machine_code_config() {
# 显示当前配置文件中的相关属性
log_info "📋 [当前配置] 检查现有的遥测属性:"
# 🔧 修复:避免把路径直接拼进 Python 源码字符串(路径包含引号等特殊字符时会导致语法错误)
python3 -c "
import json
try:
with open('$config_path', 'r', encoding='utf-8') as f:
config = json.load(f)
properties = ['telemetry.machineId', 'telemetry.macMachineId', 'telemetry.devDeviceId', 'telemetry.sqmId']
for prop in properties:
if prop in config:
value = config[prop]
display_value = value[:20] + '...' if len(value) > 20 else value
print(f' ✓ {prop} = {display_value}')
else:
print(f' - {prop} (不存在,将创建)')
except Exception as e:
print(f'Error reading config: {e}')
"
import json
import sys
try:
config_path = sys.argv[1]
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
properties = ['telemetry.machineId', 'telemetry.macMachineId', 'telemetry.devDeviceId', 'telemetry.sqmId']
for prop in properties:
if prop in config:
value = config[prop]
display_value = value[:20] + '...' if len(value) > 20 else value
print(f' ✓ {prop} = {display_value}')
else:
print(f' - {prop} (不存在,将创建)')
except Exception as e:
print(f'Error reading config: {e}')
" "$config_path"
echo
# 显示操作进度
@ -535,40 +540,49 @@ except Exception as e:
log_info "⏳ [进度] 4/5 - 更新配置文件..."
# 使用Python修改JSON配置(更可靠,安全方式)
# 🔧 修复:避免把路径/值直接拼进 Python 源码字符串(引号/反斜杠等特殊字符会导致语法错误或写入错误)
local python_result=$(python3 -c "
import json
import sys
try:
with open('$config_path', 'r', encoding='utf-8') as f:
config = json.load(f)
# 安全更新配置,确保属性存在
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate
properties_to_update = {
'telemetry.machineId': '$MACHINE_ID',
'telemetry.macMachineId': '$MAC_MACHINE_ID',
'telemetry.devDeviceId': '$UUID',
'telemetry.sqmId': '$SQM_ID',
'storage.serviceMachineId': '$SERVICE_MACHINE_ID',
'telemetry.firstSessionDate': '$FIRST_SESSION_DATE'
}
for key, value in properties_to_update.items():
if key in config:
print(f' ✓ 更新属性: {key}')
else:
print(f' + 添加属性: {key}')
config[key] = value
with open('$config_path', 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print('SUCCESS')
except Exception as e:
print(f'ERROR: {e}')
sys.exit(1)
" 2>&1)
import json
import sys
try:
config_path = sys.argv[1]
machine_id = sys.argv[2]
mac_machine_id = sys.argv[3]
dev_device_id = sys.argv[4]
sqm_id = sys.argv[5]
service_machine_id = sys.argv[6]
first_session_date = sys.argv[7]
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
# 安全更新配置,确保属性存在
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate
properties_to_update = {
'telemetry.machineId': machine_id,
'telemetry.macMachineId': mac_machine_id,
'telemetry.devDeviceId': dev_device_id,
'telemetry.sqmId': sqm_id,
'storage.serviceMachineId': service_machine_id,
'telemetry.firstSessionDate': first_session_date
}
for key, value in properties_to_update.items():
if key in config:
print(f' ✓ 更新属性: {key}')
else:
print(f' + 添加属性: {key}')
config[key] = value
with open(config_path, 'w', encoding='utf-8') as f:
json.dump(config, f, indent=2, ensure_ascii=False)
print('SUCCESS')
except Exception as e:
print(f'ERROR: {e}')
sys.exit(1)
" "$config_path" "$MACHINE_ID" "$MAC_MACHINE_ID" "$UUID" "$SQM_ID" "$SERVICE_MACHINE_ID" "$FIRST_SESSION_DATE" 2>&1)
# 🔧 关键修复:正确解析Python执行结果
local python_exit_code=$?
@ -598,38 +612,48 @@ except Exception as e:
chmod 644 "$config_path" 2>/dev/null || true
# 验证修改是否成功
# 🔧 修复:避免把路径/值直接拼进 Python 源码字符串(引号/反斜杠等特殊字符会导致语法错误或写入错误)
local verification_result=$(python3 -c "
import json
try:
with open('$config_path', 'r', encoding='utf-8') as f:
config = json.load(f)
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate 验证
properties_to_check = {
'telemetry.machineId': '$MACHINE_ID',
'telemetry.macMachineId': '$MAC_MACHINE_ID',
'telemetry.devDeviceId': '$UUID',
'telemetry.sqmId': '$SQM_ID',
'storage.serviceMachineId': '$SERVICE_MACHINE_ID',
'telemetry.firstSessionDate': '$FIRST_SESSION_DATE'
}
verification_passed = True
for key, expected_value in properties_to_check.items():
actual_value = config.get(key)
if actual_value == expected_value:
print(f'✓ {key}: 验证通过')
else:
print(f'✗ {key}: 验证失败 (期望: {expected_value}, 实际: {actual_value})')
verification_passed = False
if verification_passed:
print('VERIFICATION_SUCCESS')
else:
print('VERIFICATION_FAILED')
except Exception as e:
print(f'VERIFICATION_ERROR: {e}')
" 2>&1)
import json
import sys
try:
config_path = sys.argv[1]
machine_id = sys.argv[2]
mac_machine_id = sys.argv[3]
dev_device_id = sys.argv[4]
sqm_id = sys.argv[5]
service_machine_id = sys.argv[6]
first_session_date = sys.argv[7]
with open(config_path, 'r', encoding='utf-8') as f:
config = json.load(f)
# 🔧 修复: 添加 storage.serviceMachineId 和 telemetry.firstSessionDate 验证
properties_to_check = {
'telemetry.machineId': machine_id,
'telemetry.macMachineId': mac_machine_id,
'telemetry.devDeviceId': dev_device_id,
'telemetry.sqmId': sqm_id,
'storage.serviceMachineId': service_machine_id,
'telemetry.firstSessionDate': first_session_date
}
verification_passed = True
for key, expected_value in properties_to_check.items():
actual_value = config.get(key)
if actual_value == expected_value:
print(f'✓ {key}: 验证通过')
else:
print(f'✗ {key}: 验证失败 (期望: {expected_value}, 实际: {actual_value})')
verification_passed = False
if verification_passed:
print('VERIFICATION_SUCCESS')
else:
print('VERIFICATION_FAILED')
except Exception as e:
print(f'VERIFICATION_ERROR: {e}')
" "$config_path" "$MACHINE_ID" "$MAC_MACHINE_ID" "$UUID" "$SQM_ID" "$SERVICE_MACHINE_ID" "$FIRST_SESSION_DATE" 2>&1)
# 检查验证结果(忽略其他输出,只关注最终结果)
if echo "$verification_result" | grep -q "VERIFICATION_SUCCESS"; then

Loading…
Cancel
Save