@ -42,9 +42,9 @@ if [ -z "$CURRENT_USER" ]; then
exit 1
exit 1
fi
fi
# 定义配置文件路径 (修改为 Linux 路径)
STORAGE_FILE = " /home/ $CURRENT_USER /.config/Cursor/User/globalStorage/storage.json "
BACKUP_DIR = " /home/ $CURRENT_USER /.config/Cursor/User/globalStorage/backups "
# 定义配置文件路径
STORAGE_FILE = " $HOME /.config/Cursor/User/globalStorage/storage.json "
BACKUP_DIR = " $HOME /.config/Cursor/User/globalStorage/backups "
# 检查权限
# 检查权限
check_permissions( ) {
check_permissions( ) {
@ -66,12 +66,11 @@ check_and_kill_cursor() {
get_process_details( ) {
get_process_details( ) {
local process_name = " $1 "
local process_name = " $1 "
log_debug " 正在获取 $process_name 进程详细信息: "
log_debug " 正在获取 $process_name 进程详细信息: "
ps aux | grep -E " /[C]ursor|[C]ursor $" || true
ps aux | grep -i " $process_name " | grep -v grep
}
}
while [ $attempt -le $max_attempts ] ; do
while [ $attempt -le $max_attempts ] ; do
# 使用更精确的方式查找 Cursor 进程
CURSOR_PIDS = $( ps aux | grep -E " /[C]ursor|[C]ursor $" | awk '{print $2}' || true )
CURSOR_PIDS = $( pgrep -i "cursor" || true )
if [ -z " $CURSOR_PIDS " ] ; then
if [ -z " $CURSOR_PIDS " ] ; then
log_info "未发现运行中的 Cursor 进程"
log_info "未发现运行中的 Cursor 进程"
@ -79,35 +78,30 @@ check_and_kill_cursor() {
fi
fi
log_warn "发现 Cursor 进程正在运行"
log_warn "发现 Cursor 进程正在运行"
get_process_details "C ursor"
get_process_details "c ursor"
log_warn "尝试关闭 Cursor 进程..."
log_warn "尝试关闭 Cursor 进程..."
# 遍历每个 PID 并尝试终止
for pid in $CURSOR_PIDS ; do
if [ $attempt -eq $max_attempts ] ; then
log_warn " 尝试强制终止进程 PID: ${ pid } ... "
kill -9 " ${ pid } " 2>/dev/null || true
else
kill " ${ pid } " 2>/dev/null || true
fi
done
if [ $attempt -eq $max_attempts ] ; then
log_warn "尝试强制终止进程..."
kill -9 $CURSOR_PIDS 2>/dev/null || true
else
kill $CURSOR_PIDS 2>/dev/null || true
fi
sleep 2
sleep 1
# 检查是否还有 Cursor 进程在运行
if ! ps aux | grep -E " /[C]ursor|[C]ursor $" > /dev/null; then
if ! pgrep -i "cursor" > /dev/null; then
log_info "Cursor 进程已成功关闭"
log_info "Cursor 进程已成功关闭"
return 0
return 0
fi
fi
log_warn " 等待进程关闭,尝试 $attempt / $max_attempts ... "
log_warn " 等待进程关闭,尝试 $attempt / $max_attempts ... "
( ( attempt++) )
( ( attempt++) )
sleep 1
done
done
log_error " 在 $max_attempts 次尝试后仍无法关闭 Cursor 进程 "
log_error " 在 $max_attempts 次尝试后仍无法关闭 Cursor 进程 "
get_process_details "C ursor"
get_process_details "c ursor"
log_error "请手动关闭进程后重试"
log_error "请手动关闭进程后重试"
exit 1
exit 1
}
}
@ -117,20 +111,18 @@ backup_system_id() {
log_info "正在备份系统 ID..."
log_info "正在备份系统 ID..."
local system_id_file = " $BACKUP_DIR /system_id.backup_ $( date +%Y%m%d_%H%M%S) "
local system_id_file = " $BACKUP_DIR /system_id.backup_ $( date +%Y%m%d_%H%M%S) "
# 获取并备份 machine-id
# 创建备份目录
mkdir -p " $BACKUP_DIR "
{
{
echo "# Original Machine ID Backup" > " $system_id_file "
echo "## /var/lib/dbus/machine-id:" >> " $system_id_file "
cat /var/lib/dbus/machine-id 2>/dev/null >> " $system_id_file " || echo "Not found" >> " $system_id_file "
echo -e "\n## /etc/machine-id:" >> " $system_id_file "
cat /etc/machine-id 2>/dev/null >> " $system_id_file " || echo "Not found" >> " $system_id_file "
echo -e "\n## hostname:" >> " $system_id_file "
hostname >> " $system_id_file "
echo " # Original System ID Backup - $( date) " > " $system_id_file "
echo "## Machine ID:" >> " $system_id_file "
cat /etc/machine-id >> " $system_id_file "
echo -e "\n## DMI System UUID:" >> " $system_id_file "
dmidecode -s system-uuid >> " $system_id_file " 2>/dev/null || echo "N/A"
chmod 444 " $system_id_file "
chmod 444 " $system_id_file "
chown " $CURRENT_USER : $CURRENT_USER " " $system_id_file "
chown " $CURRENT_USER " " $system_id_file "
log_info " 系统 ID 已备份到: $system_id_file "
log_info " 系统 ID 已备份到: $system_id_file "
} || {
} || {
log_error "备份系统 ID 失败"
log_error "备份系统 ID 失败"
@ -140,23 +132,17 @@ backup_system_id() {
# 备份配置文件
# 备份配置文件
backup_config( ) {
backup_config( ) {
# 检查文件权限
if [ -f " $STORAGE_FILE " ] && [ ! -w " $STORAGE_FILE " ] ; then
log_error "无法写入配置文件,请检查权限"
exit 1
fi
if [ ! -f " $STORAGE_FILE " ] ; then
if [ ! -f " $STORAGE_FILE " ] ; then
log_warn "配置文件不存在,跳过备份"
log_warn "配置文件不存在,跳过备份"
return 0
return 0
fi
}
mkdir -p " $BACKUP_DIR "
mkdir -p " $BACKUP_DIR "
local backup_file = " $BACKUP_DIR /storage.json.backup_ $( date +%Y%m%d_%H%M%S) "
local backup_file = " $BACKUP_DIR /storage.json.backup_ $( date +%Y%m%d_%H%M%S) "
if cp " $STORAGE_FILE " " $backup_file " ; then
if cp " $STORAGE_FILE " " $backup_file " ; then
chmod 644 " $backup_file "
chmod 644 " $backup_file "
chown " $CURRENT_USER : $CURRENT_USER " " $backup_file "
chown " $CURRENT_USER " " $backup_file "
log_info " 配置已备份到: $backup_file "
log_info " 配置已备份到: $backup_file "
else
else
log_error "备份失败"
log_error "备份失败"
@ -166,109 +152,147 @@ backup_config() {
# 生成随机 ID
# 生成随机 ID
generate_random_id( ) {
generate_random_id( ) {
# Linux 可以使用 /dev/urandom
# 生成32字节(64个十六进制字符)的随机数
head -c 32 /dev/urandom | xxd -p
head -c 32 /dev/urandom | xxd -p
}
}
# 生成随机 UUID
# 生成随机 UUID
generate_uuid( ) {
generate_uuid( ) {
# Linux 使用 uuidgen 命令
uuidgen | tr '[:upper:]' '[:lower:]'
uuidgen | tr '[:upper:]' '[:lower:]'
}
}
# 修改现有文件
modify_or_add_config( ) {
local key = " $1 "
local value = " $2 "
local file = " $3 "
if [ ! -f " $file " ] ; then
log_error " 文件不存在: $file "
return 1
}
# 确保文件可写
chmod 644 " $file " || {
log_error " 无法修改文件权限: $file "
return 1
}
# 创建临时文件
local temp_file = $( mktemp)
# 检查key是否存在
if grep -q " \" $key \": " " $file " ; then
# key存在,执行替换
sed " s|\" $key \":[[:space:]]*\"[^\"]*\"|\" $key \": \" $value \"| " " $file " > " $temp_file " || {
log_error " 修改配置失败: $key "
rm -f " $temp_file "
return 1
}
else
# key不存在,添加新的key-value对
sed " s/} $/,\n \" $key \": \" $value \"\n}/ " " $file " > " $temp_file " || {
log_error " 添加配置失败: $key "
rm -f " $temp_file "
return 1
}
fi
# 检查临时文件是否为空
if [ ! -s " $temp_file " ] ; then
log_error "生成的临时文件为空"
rm -f " $temp_file "
return 1
}
# 使用 cat 替换原文件内容
cat " $temp_file " > " $file " || {
log_error " 无法写入文件: $file "
rm -f " $temp_file "
return 1
}
rm -f " $temp_file "
# 恢复文件权限
chmod 444 " $file "
return 0
}
# 生成新的配置
# 生成新的配置
generate_new_config( ) {
generate_new_config( ) {
# 错误处理
if ! command -v xxd & > /dev/null; then
log_error "未找到 xxd 命令,请安装 xxd,使用 apt-get install xxd"
exit 1
fi
# 修改系统 ID
log_info "正在修改系统 ID..."
if ! command -v uuidgen & > /dev/null; then
log_error "未找到 uuidgen 命令,请安装 uuidgen,使用 apt-get install uuid-runtime"
exit 1
fi
# 备份当前系统 ID
backup_system_id
# 检查配置文件是否存在
if [ ! -f " $STORAGE_FILE " ] ; then
log_error " 未找到配置文件: $STORAGE_FILE "
log_warn "请先安装并运行一次 Cursor 后再使用此脚本"
exit 1
fi
# 生成新的 machine-id
local new_machine_id = $( generate_random_id | cut -c1-32)
# 修改系统 machine-id
# 备份并修改 machine-id
if [ -f "/etc/machine-id" ] ; then
if [ -f "/etc/machine-id" ] ; then
log_info "正在修改系统 machine-id..."
local new_machine_id = $( uuidgen | tr -d '-' )
# 备份原始 machine-id
backup_system_id
# 修改 machine-id
echo " $new_machine_id " | sudo tee /etc/machine-id > /dev/null
if [ -f "/var/lib/dbus/machine-id" ] ; then
sudo ln -sf /etc/machine-id /var/lib/dbus/machine-id
fi
cp /etc/machine-id /etc/machine-id.backup
echo " $new_machine_id " > /etc/machine-id
log_info "系统 machine-id 已更新"
log_info "系统 machine-id 已更新"
fi
fi
# 将 auth0|user_ 转换为字节数组的十六进制
# 将 auth0|user_ 转换为字节数组的十六进制
local machine_id = " auth0|user_ $( generate_random_id | cut -c 1-32) "
local prefix_hex = $( echo -n "auth0|user_" | xxd -p)
local random_part = $( generate_random_id)
local machine_id = " ${ prefix_hex } ${ random_part } "
local mac_machine_id = $( generate_random_id)
local mac_machine_id = $( generate_random_id)
local device_id = $( generate_uuid | tr '[:upper:]' '[:lower:]' )
local device_id = $( generate_uuid | tr '[:upper:]' '[:lower:]' )
local sqm_id = " { $( generate_uuid | tr '[:lower:]' '[:upper:]' ) } "
local sqm_id = " { $( generate_uuid | tr '[:lower:]' '[:upper:]' ) } "
# 增强的转义函数
escape_sed_replacement( ) {
echo " $1 " | sed -e 's/[\/&]/\\&/g'
log_info "正在修改配置文件..."
# 检查配置文件是否存在
if [ ! -f " $STORAGE_FILE " ] ; then
log_error " 未找到配置文件: $STORAGE_FILE "
log_warn "请先安装并运行一次 Cursor 后再使用此脚本"
exit 1
fi
# 确保配置文件目录存在
mkdir -p " $( dirname " $STORAGE_FILE " ) " || {
log_error "无法创建配置目录"
exit 1
}
}
# 对变量进行转义处理
machine_id_escaped = $( escape_sed_replacement " $machine_id " )
mac_machine_id_escaped = $( escape_sed_replacement " $mac_machine_id " )
device_id_escaped = $( escape_sed_replacement " $device_id " )
sqm_id_escaped = $( escape_sed_replacement " $sqm_id " )
# 使用增强正则表达式和转义
sed -i " s|\"telemetry\.machineId\": *\"[^\"]*\"|\"telemetry.machineId\": \" ${ machine_id_escaped } \"| " " $STORAGE_FILE "
sed -i " s|\"telemetry\.macMachineId\": *\"[^\"]*\"|\"telemetry.macMachineId\": \" ${ mac_machine_id_escaped } \"| " " $STORAGE_FILE "
sed -i " s|\"telemetry\.devDeviceId\": *\"[^\"]*\"|\"telemetry.devDeviceId\": \" ${ device_id_escaped } \"| " " $STORAGE_FILE "
sed -i " s|\"telemetry\.sqmId\": *\"[^\"]*\"|\"telemetry.sqmId\": \" ${ sqm_id_escaped } \"| " " $STORAGE_FILE "
# 如果文件不存在,创建一个基本的 JSON 结构
if [ ! -s " $STORAGE_FILE " ] ; then
echo '{}' > " $STORAGE_FILE " || {
log_error "无法初始化配置文件"
exit 1
}
fi
# 修改现有文件
modify_or_add_config "telemetry.machineId" " $machine_id " " $STORAGE_FILE " || exit 1
modify_or_add_config "telemetry.macMachineId" " $mac_machine_id " " $STORAGE_FILE " || exit 1
modify_or_add_config "telemetry.devDeviceId" " $device_id " " $STORAGE_FILE " || exit 1
modify_or_add_config "telemetry.sqmId" " $sqm_id " " $STORAGE_FILE " || exit 1
# 设置文件权限和所有者
# 设置文件权限和所有者
chmod 444 " $STORAGE_FILE " # 改为只读权限
chmod 444 " $STORAGE_FILE " # 改为只读权限
chown " $CURRENT_USER : $CURRENT_USER " " $STORAGE_FILE "
chown " $CURRENT_USER " " $STORAGE_FILE "
# 验证权限设置
# 验证权限设置
if [ -w " $STORAGE_FILE " ] ; then
if [ -w " $STORAGE_FILE " ] ; then
log_warn "无法设置只读权限,尝试使用其他方法..."
log_warn "无法设置只读权限,尝试使用其他方法..."
# 在 Linux 上使用 chattr 命令设置不可修改属性
if command -v chattr & > /dev/null; then
chattr +i " $STORAGE_FILE " 2>/dev/null || log_warn "chattr 设置失败"
fi
chattr +i " $STORAGE_FILE " 2>/dev/null || true
else
else
log_info "成功设置文件只读权限"
log_info "成功设置文件只读权限"
fi
fi
echo
echo
log_info "已更新配置:"
log_info " 已更新配置: $STORAGE_FILE "
log_debug " machineId: $machine_id "
log_debug " machineId: $machine_id "
log_debug " macMachineId: $mac_machine_id "
log_debug " macMachineId: $mac_machine_id "
log_debug " devDeviceId: $device_id "
log_debug " devDeviceId: $device_id "
log_debug " sqmId: $sqm_id "
log_debug " sqmId: $sqm_id "
# 在generate_new_config函数末尾添加验证
log_info "验证配置文件有效性..."
if ! command -v jq & > /dev/null; then
log_warn "未找到jq命令,跳过JSON验证"
else
if ! jq empty " $STORAGE_FILE " & > /dev/null; then
log_error "配置文件格式错误,正在恢复备份..."
cp " $( ls -t " $BACKUP_DIR " /storage.json.backup_* | head -1) " " $STORAGE_FILE "
exit 1
fi
fi
}
}
# 显示文件树结构
# 显示文件树结构
@ -284,7 +308,7 @@ show_file_tree() {
# 列出备份文件
# 列出备份文件
if [ -d " $BACKUP_DIR " ] ; then
if [ -d " $BACKUP_DIR " ] ; then
local backup_files = ( " $BACKUP_DIR " /*)
local backup_files = ( " $BACKUP_DIR " /*)
if [ ${# backup_files [@] } -gt 0 ] && [ -e " ${ backup_files [0] } " ] ; then
if [ ${# backup_files [@] } -gt 0 ] ; then
for file in " ${ backup_files [@] } " ; do
for file in " ${ backup_files [@] } " ; do
if [ -f " $file " ] ; then
if [ -f " $file " ] ; then
echo " │ └── $( basename " $file " ) "
echo " │ └── $( basename " $file " ) "
@ -301,7 +325,7 @@ show_file_tree() {
show_follow_info( ) {
show_follow_info( ) {
echo
echo
echo -e " ${ GREEN } ================================ ${ NC } "
echo -e " ${ GREEN } ================================ ${ NC } "
echo -e " ${ YELLOW } 关注公众号【煎饼果子卷AI】一起交流更多Cursor技巧和AI知识 ${ NC } "
echo -e " ${ YELLOW } 关注公众号【煎饼果子卷AI】一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬) ${ NC } "
echo -e " ${ GREEN } ================================ ${ NC } "
echo -e " ${ GREEN } ================================ ${ NC } "
echo
echo
}
}
@ -388,6 +412,12 @@ disable_auto_update() {
# 主函数
# 主函数
main( ) {
main( ) {
# 检查是否为 Linux 系统
if [ [ $( uname) != "Linux" ] ] ; then
log_error "本脚本仅支持 Linux 系统"
exit 1
}
clear
clear
# 显示 Logo
# 显示 Logo
echo -e "
echo -e "
@ -399,7 +429,7 @@ main() {
╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝
╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝
"
"
echo -e " ${ BLUE } ================================ ${ NC } "
echo -e " ${ BLUE } ================================ ${ NC } "
echo -e " ${ GREEN } Cursor 设备ID 修改工具 ${ NC } "
echo -e " ${ GREEN } Cursor 设备ID 修改工具 (Linux版) ${ NC } "
echo -e " ${ YELLOW } 关注公众号【煎饼果子卷AI】 ${ NC } "
echo -e " ${ YELLOW } 关注公众号【煎饼果子卷AI】 ${ NC } "
echo -e " ${ YELLOW } 一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬) ${ NC } "
echo -e " ${ YELLOW } 一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬) ${ NC } "
echo -e " ${ BLUE } ================================ ${ NC } "
echo -e " ${ BLUE } ================================ ${ NC } "
@ -412,14 +442,14 @@ main() {
check_and_kill_cursor
check_and_kill_cursor
backup_config
backup_config
generate_new_config
generate_new_config
echo
log_info "操作完成!"
show_follow_info
show_file_tree
show_file_tree
log_info "请重启 Cursor 以应用新的配置"
show_follow_info
# 添加禁用自动更新功能
disable_auto_update
disable_auto_update
log_info "请重启 Cursor 以应用新的配置"
show_follow_info
}
}
# 执行主函数
# 执行主函数