@clawhub-leo-zzl-2fccc5dda8
记录每日心情并保存到 Obsidian 库。当用户要求记录心情、情绪日记、心情追踪或类似的情绪记录任务时使用。使用 scripts/log_mood.py 脚本确保格式固定一致。支持心情评分(1-10)、标签和备注。
--- name: mood-logger version: 1.0.0 description: 记录每日心情并保存到 Obsidian 库。当用户要求记录心情、情绪日记、心情追踪或类似的情绪记录任务时使用。使用 scripts/log_mood.py 脚本确保格式固定一致。支持心情评分(1-10)、标签和备注。 --- # 心情日记 用于记录每日心情和情绪状态,保存到 Obsidian 库中,格式完全固定。 ## 使用方法 使用 Python 脚本记录心情: ```bash python3 ~/.openclaw/workspace/skills/mood-logger/scripts/log_mood.py \ --date 2026-03-27 \ --score 8 \ --tags "开心,充实" \ --note "今天完成了重要任务" ``` ### 参数说明 - `--date`: 日期 (YYYY-MM-DD),默认为今天 - `--score`: 心情评分 (1-10),必需 - `--tags`: 心情标签,逗号分隔,必需 - `--note`: 备注/原因 (可选) ### 评分与表情对照 | 评分 | 表情 | 说明 | |------|------|------| | 9-10 | 😄 | 非常开心 | | 7-8 | 😊 | 开心/不错 | | 5-6 | 😐 | 平静/一般 | | 3-4 | 😔 | 低落/疲惫 | | 1-2 | 😢 | 很难过 | ### 示例 ```bash # 简单记录 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/log_mood.py \ --score 8 --tags "开心" # 带备注 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/log_mood.py \ --score 6 --tags "平静,普通" --note "今天没什么特别的事" # 多条记录(支持一天多次记录) python3 ~/.openclaw/workspace/skills/mood-logger/scripts/log_mood.py \ --score 4 --tags "疲惫,焦虑" --note "工作压力有点大" # 指定日期 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/log_mood.py \ --date 2026-03-26 --score 9 --tags "兴奋,成就感" ``` ## 文件格式 生成的文件格式固定如下: ```markdown # YYYY-MM-DD 心情日记 ## 今日心情 ### 😊 评分: 8/10 **标签**: `开心` `充实` **备注**: 今天完成了重要任务 ### 😔 评分: 4/10 **标签**: `疲惫` `焦虑` **备注**: 工作压力有点大 --- *记录时间: YYYY-MM-DD HH:MM* ``` ## 配置信息 **保存路径**: `/mnt/c/Users/loong/iCloudDrive/iCloud~md~obsidian/HomeMo.Art/05-Daily/` **文件名格式**: `心情日记-YYYY-MM-DD.md` **脚本位置**: `scripts/log_mood.py` ## 周报功能 ### 生成周报 ```bash # 生成本周周报(打印到控制台) python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py # 生成指定周的周报 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py --date 2026-03-27 # 保存到文件 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py --output /tmp/mood_report.md ``` ### 周报内容 - 本周心情平均分 - 最高/最低心情 - 心情标签统计 TOP5 - 每日心情走势 - 备注摘录 ### 定时发送 每周日早上 9:00 自动生成并发送周报。 设置命令: ```bash openclaw cron create --name "mood-weekly-report" \ --schedule "0 9 * * 0" \ --command "python3 ~/.openclaw/workspace/skills/mood-logger/scripts/send_weekly_report.py" \ --channel openclaw-weixin \ --to "[email protected]" ``` FILE:WEEKLY_REPORT_SETUP.md # 心情周报定时设置 ## 方案一:OpenClaw Cron(推荐) 当 OpenClaw CLI 可用时,运行: ```bash openclaw cron create mood-weekly-report \ --schedule "0 9 * * 0" \ --task "每周心情周报" \ --command "生成并发送上周的心情周报" ``` ## 方案二:系统 Cron(备用) 添加到系统定时任务: ```bash # 编辑 crontab crontab -e # 添加以下行(每周日 9:00 运行) 0 9 * * 0 cd /home/loong/.openclaw/workspace && python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py >> /tmp/mood_report.log 2>&1 ``` ## 方案三:手动生成 随时手动生成周报: ```bash # 生成本周周报 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py # 生成上周周报 python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py --date $(date -d 'last sunday' +%Y-%m-%d) ``` ## 周报示例输出 ``` # 📊 心情周报 (03月23日 - 03月29日) ## 本周概览 | 指标 | 数值 | |------|------| | 平均心情 | 8.0/10 😊 | | 最高心情 | 8/10 | | 最低心情 | 8/10 | | 记录次数 | 1 次 | | 整体趋势 | 平稳 | ## 心情标签 TOP5 - `开心`: 1 次 - `满足`: 1 次 ## 每日心情 - **周一**: 无记录 - **周二**: 无记录 - **周三**: 无记录 - **周四**: 无记录 - **周五**: 😊 8.0/10 - **周六**: 无记录 - **周日**: 无记录 ``` FILE:scripts/cron_send_report.sh #!/bin/bash # 心情周报定时发送脚本 # 每周日早上 9:00 执行 cd /home/loong/.openclaw/workspace # 生成周报 REPORT=$(python3 ~/.openclaw/workspace/skills/mood-logger/scripts/weekly_mood_report.py 2>/dev/null) # 发送到微信(通过 OpenClaw 消息系统) # 注意:需要配置 webhook 或消息代理 echo "$REPORT" > /tmp/weekly_mood_report.txt # 输出生成的报告 cat /tmp/weekly_mood_report.txt FILE:scripts/log_mood.py #!/usr/bin/env python3 """ 心情记录工具 - 生成固定格式的心情记录文件 用法: python3 log_mood.py --date 2026-03-27 --score 8 --tags "开心,充实" --note "今天完成了重要任务" python3 log_mood.py --score 6 --tags "平静" --note "普通的一天" python3 log_mood.py --score 4 --tags "疲惫,焦虑" 参数: --date: 日期 (默认今天,格式 YYYY-MM-DD) --score: 心情评分 (1-10) --tags: 心情标签,逗号分隔 --note: 备注/原因 (可选) """ import argparse import os from datetime import datetime # 配置 VAULT_PATH = "/mnt/c/Users/loong/iCloudDrive/iCloud~md~obsidian/HomeMo.Art" DAILY_DIR = os.path.join(VAULT_PATH, "05-Daily") def get_mood_emoji(score: int) -> str: """根据评分返回表情""" if score >= 9: return "😄" elif score >= 7: return "😊" elif score >= 5: return "😐" elif score >= 3: return "😔" else: return "😢" def get_template(date_str: str) -> str: """获取文件模板""" return f"""# {date_str} 心情日记 ## 今日心情 --- *记录时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}* """ def parse_tags(tags_str: str) -> list: """解析标签列表""" return [tag.strip() for tag in tags_str.split(",") if tag.strip()] def format_tags(tags: list) -> str: """格式化标签为 markdown""" return " ".join([f"`{tag}`" for tag in tags]) def read_or_create_file(filepath: str, date_str: str) -> str: """读取文件,如果不存在则创建""" if os.path.exists(filepath): with open(filepath, "r", encoding="utf-8") as f: return f.read() return get_template(date_str) def update_mood(content: str, score: int, tags: list, note: str = None) -> str: """更新心情记录""" emoji = get_mood_emoji(score) tags_md = format_tags(tags) # 构建心情条目 mood_entry = f""" ### {emoji} 评分: {score}/10 **标签**: {tags_md} """ if note: mood_entry += f"\n**备注**: {note}\n" # 在 "## 今日心情" 后插入 lines = content.split("\n") result = [] mood_section_found = False for i, line in enumerate(lines): result.append(line) if line.strip() == "## 今日心情": mood_section_found = True # 在标题后插入心情记录 result.append(mood_entry) # 如果没找到心情段落,追加到最后(在分隔线之前) if not mood_section_found: # 找到分隔线位置 for i in range(len(result) - 1, -1, -1): if result[i].strip().startswith("---"): # 在分隔线前插入 result.insert(i, f"## 今日心情\n{mood_entry}") break else: # 没找到分隔线,追加到末尾 result.append(f"## 今日心情\n{mood_entry}") return "\n".join(result) def main(): parser = argparse.ArgumentParser(description="记录心情") parser.add_argument("--date", default=datetime.now().strftime("%Y-%m-%d"), help="日期 (YYYY-MM-DD)") parser.add_argument("--score", type=int, required=True, help="心情评分 (1-10)") parser.add_argument("--tags", required=True, help="心情标签,逗号分隔") parser.add_argument("--note", default=None, help="备注/原因 (可选)") args = parser.parse_args() # 验证评分范围 if not 1 <= args.score <= 10: print("错误: 评分必须在 1-10 之间") return # 确保目录存在 os.makedirs(DAILY_DIR, exist_ok=True) # 文件路径 filename = f"心情日记-{args.date}.md" filepath = os.path.join(DAILY_DIR, filename) # 读取或创建文件 content = read_or_create_file(filepath, args.date) # 解析标签 tags = parse_tags(args.tags) # 更新内容 new_content = update_mood(content, args.score, tags, args.note) # 保存文件 with open(filepath, "w", encoding="utf-8") as f: f.write(new_content) emoji = get_mood_emoji(args.score) print(f"✅ 已记录心情: {emoji} {args.score}/10") print(f"🏷️ 标签: {', '.join(tags)}") if args.note: print(f"📝 备注: {args.note}") print(f"📁 文件: {filepath}") if __name__ == "__main__": main() FILE:scripts/send_weekly_report.py #!/usr/bin/env python3 """ 心情周报发送工具 - 生成并发送周报给用户 用法: python3 send_weekly_report.py 说明: 生成上周的心情周报,并通过 OpenClaw 消息系统发送 """ import subprocess import sys import os # 获取脚本所在目录 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) REPORT_SCRIPT = os.path.join(SCRIPT_DIR, "weekly_mood_report.py") def main(): # 生成周报 result = subprocess.run( [sys.executable, REPORT_SCRIPT], capture_output=True, text=True, cwd=SCRIPT_DIR ) if result.returncode != 0: print(f"生成报告失败: {result.stderr}") return # 提取报告内容(去掉第一行"正在生成周报...") lines = result.stdout.strip().split('\n') # 找到第一个 # 开头的行(报告标题) report_start = 0 for i, line in enumerate(lines): if line.startswith('# '): report_start = i break report = '\n'.join(lines[report_start:]) print(report) if __name__ == "__main__": main() FILE:scripts/weekly_mood_report.py #!/usr/bin/env python3 """ 心情周报生成工具 - 分析本周心情记录并生成报告 用法: python3 weekly_mood_report.py --date 2026-03-27 参数: --date: 指定日期,计算该日期所在周的报告 (默认今天) --output: 输出文件路径 (可选,默认打印到控制台) """ import argparse import os import re from datetime import datetime, timedelta from collections import Counter # 配置 VAULT_PATH = "/mnt/c/Users/loong/iCloudDrive/iCloud~md~obsidian/HomeMo.Art" DAILY_DIR = os.path.join(VAULT_PATH, "05-Daily") def get_week_range(date: datetime) -> tuple: """获取指定日期所在周的起止日期 (周一到周日)""" # 找到本周一 monday = date - timedelta(days=date.weekday()) # 本周日 sunday = monday + timedelta(days=6) return monday, sunday def parse_mood_file(filepath: str) -> list: """解析心情记录文件,返回记录列表""" records = [] if not os.path.exists(filepath): return records with open(filepath, "r", encoding="utf-8") as f: content = f.read() # 提取日期 date_match = re.search(r'# (\d{4}-\d{2}-\d{2})', content) if not date_match: return records date_str = date_match.group(1) # 提取每条心情记录 # 匹配模式: ### 😊 评分: 8/10 mood_blocks = re.findall( r'### .+ 评分: (\d+)/10\s*\n\s*\*\*标签\*\*: (.+?)(?:\s*\n\s*\*\*备注\*\*: (.+?))?(?=\n### |\n---|$)', content, re.DOTALL ) for score_str, tags_str, note in mood_blocks: score = int(score_str) # 解析标签 `标签1` `标签2` tags = re.findall(r'`([^`]+)`', tags_str) records.append({ 'date': date_str, 'score': score, 'tags': tags, 'note': note.strip() if note else None }) return records def get_weekly_records(monday: datetime, sunday: datetime) -> list: """获取本周所有心情记录""" all_records = [] for i in range(7): current_date = monday + timedelta(days=i) date_str = current_date.strftime("%Y-%m-%d") filepath = os.path.join(DAILY_DIR, f"心情日记-{date_str}.md") records = parse_mood_file(filepath) all_records.extend(records) return all_records def generate_report(records: list, week_start: datetime, week_end: datetime) -> str: """生成周报""" if not records: return "本周没有心情记录。" # 基础统计 scores = [r['score'] for r in records] avg_score = sum(scores) / len(scores) max_score = max(scores) min_score = min(scores) # 标签统计 all_tags = [] for r in records: all_tags.extend(r['tags']) tag_counter = Counter(all_tags) top_tags = tag_counter.most_common(5) # 按日期分组 daily_scores = {} for r in records: date = r['date'] if date not in daily_scores: daily_scores[date] = [] daily_scores[date].append(r['score']) # 计算每日平均 daily_avg = {date: sum(scores)/len(scores) for date, scores in daily_scores.items()} # 趋势判断 trend = "平稳" if len(daily_avg) >= 3: dates = sorted(daily_avg.keys()) first_half = [daily_avg[d] for d in dates[:len(dates)//2]] second_half = [daily_avg[d] for d in dates[len(dates)//2:]] first_avg = sum(first_half) / len(first_half) second_avg = sum(second_half) / len(second_half) if second_avg - first_avg > 1: trend = "上升 📈" elif first_avg - second_avg > 1: trend = "下降 📉" # 生成报告 week_start_str = week_start.strftime("%m月%d日") week_end_str = week_end.strftime("%m月%d日") report = f"""# 📊 心情周报 ({week_start_str} - {week_end_str}) ## 本周概览 | 指标 | 数值 | |------|------| | 平均心情 | {avg_score:.1f}/10 {'😊' if avg_score >= 7 else '😐' if avg_score >= 5 else '😔'} | | 最高心情 | {max_score}/10 | | 最低心情 | {min_score}/10 | | 记录次数 | {len(records)} 次 | | 有记录天数 | {len(daily_scores)} 天 | | 整体趋势 | {trend} | ## 心情标签 TOP5 """ for tag, count in top_tags: report += f"- `{tag}`: {count} 次\n" # 每日详情 report += "\n## 每日心情\n\n" for i in range(7): date = week_start + timedelta(days=i) date_str = date.strftime("%Y-%m-%d") weekday_name = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"][i] if date_str in daily_avg: score = daily_avg[date_str] emoji = "😄" if score >= 9 else "😊" if score >= 7 else "😐" if score >= 5 else "😔" report += f"- **{weekday_name}** ({date_str}): {emoji} {score:.1f}/10\n" else: report += f"- **{weekday_name}** ({date_str}): 无记录\n" # 备注摘录 notes = [r for r in records if r['note']] if notes: report += "\n## 本周备注\n\n" for r in notes[:5]: # 最多显示5条 report += f"- **{r['date']}** ({r['score']}/10): {r['note']}\n" report += f"\n---\n*报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}*" return report def main(): parser = argparse.ArgumentParser(description="生成心情周报") parser.add_argument("--date", default=datetime.now().strftime("%Y-%m-%d"), help="指定日期 (YYYY-MM-DD),计算该日期所在周的报告") parser.add_argument("--output", default=None, help="输出文件路径 (可选)") args = parser.parse_args() # 解析日期 try: target_date = datetime.strptime(args.date, "%Y-%m-%d") except ValueError: print("错误: 日期格式应为 YYYY-MM-DD") return # 获取本周范围 monday, sunday = get_week_range(target_date) print(f"正在生成周报: {monday.strftime('%Y-%m-%d')} 至 {sunday.strftime('%Y-%m-%d')}") # 获取记录 records = get_weekly_records(monday, sunday) # 生成报告 report = generate_report(records, monday, sunday) # 输出 if args.output: with open(args.output, "w", encoding="utf-8") as f: f.write(report) print(f"✅ 报告已保存: {args.output}") else: print("\n" + report) if __name__ == "__main__": main()
记录日常饮食并保存到 Obsidian 库。当用户要求记录早饭、午饭、晚饭、加餐、饮食日记或类似的饮食追踪任务时使用。使用 scripts/log_diet.py 脚本确保格式固定一致。
---
name: diet-logger
version: 1.0.0
description: 记录日常饮食并保存到 Obsidian 库。当用户要求记录早饭、午饭、晚饭、加餐、饮食日记或类似的饮食追踪任务时使用。使用 scripts/log_diet.py 脚本确保格式固定一致。
---
# 饮食记录
用于记录日常饮食,保存到 Obsidian 库中,格式完全固定。
## 使用方法
使用 Python 脚本记录饮食:
```bash
python3 ~/.openclaw/workspace/skills/diet-logger/scripts/log_diet.py \
--date 2026-03-27 \
--meal 晚饭 \
--items "红烧肉,米饭"
```
### 参数说明
- `--date`: 日期 (YYYY-MM-DD),默认为今天
- `--meal`: 餐段,可选值:早饭、中饭、晚饭、加餐
- `--items`: 食物列表,逗号分隔
### 示例
```bash
# 记录早饭
python3 ~/.openclaw/workspace/skills/diet-logger/scripts/log_diet.py \
--meal 早饭 --items "鸡蛋,牛奶"
# 记录中饭
python3 ~/.openclaw/workspace/skills/diet-logger/scripts/log_diet.py \
--meal 中饭 --items "清蒸鲈鱼,炒花菜,米饭"
# 指定日期
python3 ~/.openclaw/workspace/skills/diet-logger/scripts/log_diet.py \
--date 2026-03-26 --meal 晚饭 --items "面条"
```
## 文件格式
生成的文件格式固定如下:
```markdown
# YYYY-MM-DD 饮食记录
## 早饭
- 鸡蛋
- 牛奶
## 中饭
- 清蒸鲈鱼
- 炒花菜
- 米饭
## 晚饭
## 加餐
---
*记录时间: YYYY-MM-DD HH:MM*
```
## 配置信息
**保存路径**: `/mnt/c/Users/loong/iCloudDrive/iCloud~md~obsidian/HomeMo.Art/05-Daily/`
**文件名格式**: `饮食记录-YYYY-MM-DD.md`
**脚本位置**: `scripts/log_diet.py`
FILE:scripts/log_diet.py
#!/usr/bin/env python3
"""
饮食记录工具 - 生成固定格式的饮食记录文件
用法:
python3 log_diet.py --date 2026-03-27 --meal 晚饭 --items "红烧肉,米饭"
python3 log_diet.py --meal 早饭 --items "鸡蛋,牛奶"
参数:
--date: 日期 (默认今天,格式 YYYY-MM-DD)
--meal: 餐段 (早饭/中饭/晚饭/加餐)
--items: 食物列表,逗号分隔
"""
import argparse
import os
from datetime import datetime
# 配置
VAULT_PATH = "/mnt/c/Users/loong/iCloudDrive/iCloud~md~obsidian/HomeMo.Art"
DAILY_DIR = os.path.join(VAULT_PATH, "05-Daily")
def get_template(date_str: str) -> str:
"""获取文件模板"""
return f"""# {date_str} 饮食记录
## 早饭
## 中饭
## 晚饭
## 加餐
---
*记录时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}*
"""
def parse_items(items_str: str) -> list:
"""解析食物列表"""
return [item.strip() for item in items_str.split(",") if item.strip()]
def format_items(items: list) -> str:
"""格式化食物列表为 markdown"""
return "\n".join([f"- {item}" for item in items])
def read_or_create_file(filepath: str, date_str: str) -> str:
"""读取文件,如果不存在则创建"""
if os.path.exists(filepath):
with open(filepath, "r", encoding="utf-8") as f:
return f.read()
return get_template(date_str)
def update_meal(content: str, meal: str, items: list) -> str:
"""在对应餐段追加食物"""
items_md = format_items(items)
meal_header = f"## {meal}"
lines = content.split("\n")
result = []
meal_found = False
meal_line_idx = -1
# 找到餐段位置
for i, line in enumerate(lines):
if line.strip() == meal_header:
meal_found = True
meal_line_idx = i
result.append(line)
# 在餐段标题后添加食物
result.append(items_md)
else:
result.append(line)
# 如果没找到餐段,追加到最后
if not meal_found:
result.append(f"\n## {meal}")
result.append(items_md)
return "\n".join(result)
def main():
parser = argparse.ArgumentParser(description="记录饮食")
parser.add_argument("--date", default=datetime.now().strftime("%Y-%m-%d"),
help="日期 (YYYY-MM-DD)")
parser.add_argument("--meal", required=True,
choices=["早饭", "中饭", "晚饭", "加餐"],
help="餐段")
parser.add_argument("--items", required=True,
help="食物列表,逗号分隔")
args = parser.parse_args()
# 确保目录存在
os.makedirs(DAILY_DIR, exist_ok=True)
# 文件路径
filename = f"饮食记录-{args.date}.md"
filepath = os.path.join(DAILY_DIR, filename)
# 读取或创建文件
content = read_or_create_file(filepath, args.date)
# 解析食物
items = parse_items(args.items)
# 更新内容
new_content = update_meal(content, args.meal, items)
# 保存文件
with open(filepath, "w", encoding="utf-8") as f:
f.write(new_content)
print(f"✅ 已记录: {args.meal} - {', '.join(items)}")
print(f"📁 文件: {filepath}")
if __name__ == "__main__":
main()
Automated GitHub synchronization for Obsidian vault with conflict detection and notification. Use when the user wants to: - Sync their Obsidian vault to a Gi...
--- name: obsidian-github-sync description: | Automated GitHub synchronization for Obsidian vault with conflict detection and notification. Use when the user wants to: - Sync their Obsidian vault to a GitHub repository - Set up automatic daily synchronization - Handle git conflicts in Obsidian vault - Configure git-based backup for Obsidian notes Triggers on phrases like: "sync obsidian", "obsidian github", "vault backup", "sync my notes", "setup obsidian git sync" --- # Obsidian GitHub Sync Automated synchronization of Obsidian vault with GitHub repository using git with conflict detection. ## Features - **Automatic sync**: `git pull --rebase` → commit → push - **Conflict detection**: Detects and flags merge conflicts - **Configurable**: Environment variable based configuration - **Notification**: Optional conflict notifications - **Safe**: Uses rebase to maintain clean history ## Quick Start ### 1. Set Environment Variables ```bash export OBSIDIAN_VAULT_DIR="/path/to/your/obsidian-vault" export GITHUB_REMOTE_URL="[email protected]:username/repo.git" ``` ### 2. Run Initial Sync ```bash ./scripts/obsidian-sync.sh ``` ### 3. Setup Auto-sync (Cron) ```bash # Daily at 3 AM 0 3 * * * /path/to/scripts/obsidian-sync.sh # Check conflicts at 9 AM 0 9 * * * /path/to/scripts/check-conflict.sh ``` ## Scripts ### obsidian-sync.sh Main synchronization script. Located at `scripts/obsidian-sync.sh`. **What it does:** 1. Checks for uncommitted changes and commits them 2. Pulls from GitHub with `--rebase` 3. Pushes to GitHub 4. Creates conflict flag if rebase fails **Environment Variables:** - `OBSIDIAN_VAULT_DIR` (required): Path to Obsidian vault - `GITHUB_REMOTE_URL` (required): GitHub repository URL - `GIT_USER_NAME` (optional): Git user name - `GIT_USER_EMAIL` (optional): Git user email - `SYNC_LOG_FILE` (optional): Log file path (default: `/tmp/obsidian-sync.log`) - `CONFLICT_FLAG_FILE` (optional): Conflict flag path (default: `/tmp/obsidian-sync-conflict.flag`) ### check-conflict.sh Conflict checking script. Located at `scripts/check-conflict.sh`. **What it does:** - Checks if conflict flag file exists - Outputs conflict details if found - Returns exit code 1 on conflict, 0 on clean state ## Workflow ### Normal Sync Flow ``` User modifies notes in Obsidian ↓ Cron runs obsidian-sync.sh at 3 AM ↓ Auto-commit local changes ↓ git pull --rebase origin master ↓ git push origin master ↓ Sync complete ✓ ``` ### Conflict Flow ``` Sync runs ↓ pull --rebase fails (remote has divergent changes) ↓ Create conflict flag file ↓ Exit with error ↓ Morning check-conflict.sh detects flag ↓ Notify user ↓ User resolves conflicts manually ↓ Re-run sync ``` ## Handling Conflicts When conflicts occur: 1. Check conflict flag file location (default: `/tmp/obsidian-sync-conflict.flag`) 2. Navigate to vault directory 3. Resolve conflicts using standard git workflow: ```bash cd $OBSIDIAN_VAULT_DIR git status # See conflicted files # Edit files to resolve conflicts git add -A # Stage resolved files git rebase --continue # Complete rebase git push origin master # Push resolved state ``` ## Configuration Reference See [references/setup-guide.md](references/setup-guide.md) for detailed setup instructions including: - SSH key configuration - Multi-device sync best practices - Troubleshooting guide - Cron setup examples ## Integration Examples ### With OpenClaw ```bash # Add sync cron job openclaw cron add --name "obsidian-sync" \ --cron "0 3 * * *" \ --command "/path/to/obsidian-sync.sh" # Add conflict check openclaw cron add --name "obsidian-check" \ --cron "0 9 * * *" \ --command "/path/to/check-conflict.sh" ``` ### With Systemd (Linux) Create `~/.config/systemd/user/obsidian-sync.service`: ```ini [Unit] Description=Obsidian Vault Git Sync [Service] Type=oneshot Environment="OBSIDIAN_VAULT_DIR=/path/to/vault" Environment="[email protected]:user/repo.git" ExecStart=/path/to/obsidian-sync.sh ``` Create `~/.config/systemd/user/obsidian-sync.timer`: ```ini [Unit] Description=Run Obsidian sync daily at 3 AM [Timer] OnCalendar=*-*-* 03:00:00 Persistent=true [Install] WantedBy=timers.target ``` Enable: ```bash systemctl --user daemon-reload systemctl --user enable obsidian-sync.timer systemctl --user start obsidian-sync.timer ``` ## Best Practices 1. **Close Obsidian** during sync to avoid file lock issues 2. **Commit regularly** in Obsidian to reduce conflict chances 3. **Sync before switching devices** 4. **Use `.gitignore`** to exclude Obsidian's cache files: ```gitignore # Obsidian .obsidian/workspace.json .obsidian/workspace-mobile.json .obsidian/plugins/*/data.json .trash/ ``` ## License MIT FILE:references/setup-guide.md # Obsidian GitHub Sync - 配置指南 ## 快速开始 ### 1. 环境变量配置 在使用同步脚本之前,需要设置以下环境变量: ```bash # 必需 export OBSIDIAN_VAULT_DIR="/path/to/your/obsidian-vault" export GITHUB_REMOTE_URL="[email protected]:username/repo.git" # 可选 export GIT_USER_NAME="Your Name" export GIT_USER_EMAIL="[email protected]" export SYNC_LOG_FILE="/tmp/obsidian-sync.log" export CONFLICT_FLAG_FILE="/tmp/obsidian-sync-conflict.flag" ``` ### 2. SSH 密钥设置 确保本地 SSH 密钥已添加到 GitHub: ```bash ssh-keygen -t ed25519 -C "[email protected]" cat ~/.ssh/id_ed25519.pub # 将公钥添加到 GitHub Settings -> SSH and GPG keys ``` ### 3. 手动测试同步 ```bash # 进入 skill scripts 目录 cd /path/to/obsidian-github-sync/scripts # 运行同步 ./obsidian-sync.sh # 检查冲突 ./check-conflict.sh ``` ## 自动同步设置 ### 使用 Cron (Linux/Mac) ```bash # 编辑 crontab crontab -e # 每天凌晨3点同步 0 3 * * * /path/to/obsidian-github-sync/scripts/obsidian-sync.sh # 每天早上9点检查冲突 0 9 * * * /path/to/obsidian-github-sync/scripts/check-conflict.sh ``` ### 使用 OpenClaw Cron ```bash openclaw cron add --name "obsidian-sync" \ --cron "0 3 * * *" \ --command "/path/to/obsidian-github-sync/scripts/obsidian-sync.sh" openclaw cron add --name "obsidian-check" \ --cron "0 9 * * *" \ --command "/path/to/obsidian-github-sync/scripts/check-conflict.sh" ``` ## 冲突处理 当同步遇到冲突时: 1. 冲突标记文件会被创建(默认 `/tmp/obsidian-sync-conflict.flag`) 2. 手动进入 vault 目录解决冲突 3. 解决后重新运行同步脚本 ```bash cd $OBSIDIAN_VAULT_DIR git status # 解决冲突文件 git add -A git rebase --continue git push ``` ## 多设备同步注意事项 1. **确保 Obsidian 关闭**后再运行同步,避免文件被占用 2. 在另一台设备上先 pull 再打开 Obsidian 3. 如果 Obsidian Sync 插件也启用,注意可能的冲突 ## 故障排查 ### 检查日志 ```bash tail -f /tmp/obsidian-sync.log ``` ### 验证 Git 配置 ```bash cd $OBSIDIAN_VAULT_DIR git remote -v git status ``` ### SSH 连接测试 ```bash ssh -T [email protected] ``` FILE:scripts/check-conflict.sh #!/bin/bash # 检查 Obsidian Vault 同步冲突 # # 环境变量配置(必需): # CONFLICT_FLAG_FILE - 冲突标记文件路径 (默认: /tmp/obsidian-sync-conflict.flag) CONFLICT_FLAG_FILE="-/tmp/obsidian-sync-conflict.flag" if [ -f "$CONFLICT_FLAG_FILE" ]; then echo "🚨 Obsidian Vault Git Sync Conflict Detected" echo "" echo "Details:" cat "$CONFLICT_FLAG_FILE" exit 1 else echo "✅ Obsidian Vault sync is healthy - no conflicts detected" exit 0 fi FILE:scripts/obsidian-sync.sh #!/bin/bash # Obsidian Vault GitHub 同步脚本 # # 环境变量配置(必需): # OBSIDIAN_VAULT_DIR - Obsidian vault 本地路径 # GITHUB_REMOTE_URL - GitHub 远程仓库地址 (如: [email protected]:username/repo.git) # # 可选环境变量: # GIT_USER_NAME - Git 用户名 # GIT_USER_EMAIL - Git 邮箱 # SYNC_LOG_FILE - 同步日志文件路径 (默认: /tmp/obsidian-sync.log) # CONFLICT_FLAG_FILE - 冲突标记文件路径 (默认: /tmp/obsidian-sync-conflict.flag) set -e # 配置检查 if [ -z "$OBSIDIAN_VAULT_DIR" ]; then echo "ERROR: OBSIDIAN_VAULT_DIR environment variable not set" exit 1 fi if [ -z "$GITHUB_REMOTE_URL" ]; then echo "ERROR: GITHUB_REMOTE_URL environment variable not set" exit 1 fi # 默认值 SYNC_LOG_FILE="-/tmp/obsidian-sync.log" CONFLICT_FLAG_FILE="-/tmp/obsidian-sync-conflict.flag" cd "$OBSIDIAN_VAULT_DIR" || { echo "ERROR: Cannot change to directory $OBSIDIAN_VAULT_DIR" exit 1 } # 初始化 git(如果需要) if [ ! -d ".git" ]; then echo "Initializing git repository..." git init git remote add origin "$GITHUB_REMOTE_URL" fi # 设置 git 用户信息(如果提供) if [ -n "$GIT_USER_NAME" ]; then git config user.name "$GIT_USER_NAME" fi if [ -n "$GIT_USER_EMAIL" ]; then git config user.email "$GIT_USER_EMAIL" fi echo "=== Obsidian Sync started at $(date) ===" >> "$SYNC_LOG_FILE" # 检查工作区是否有未提交的更改 if ! git diff --quiet HEAD 2>/dev/null || ! git diff --cached --quiet HEAD 2>/dev/null; then echo "Local changes detected, committing..." >> "$SYNC_LOG_FILE" git add -A git commit -m "Auto sync: $(date '+%Y-%m-%d %H:%M:%S')" >> "$SYNC_LOG_FILE" 2>&1 || true fi # 尝试 pull --rebase echo "Pulling from GitHub with rebase..." >> "$SYNC_LOG_FILE" if ! git pull --rebase origin master >> "$SYNC_LOG_FILE" 2>&1; then echo "ERROR: Pull rebase failed, possible conflict" >> "$SYNC_LOG_FILE" # 标记冲突状态 echo "Conflict detected at $(date)" > "$CONFLICT_FLAG_FILE" echo "Repository: $OBSIDIAN_VAULT_DIR" >> "$CONFLICT_FLAG_FILE" echo "Remote: $GITHUB_REMOTE_URL" >> "$CONFLICT_FLAG_FILE" echo "" >> "$CONFLICT_FLAG_FILE" echo "To resolve:" >> "$CONFLICT_FLAG_FILE" echo " 1. cd $OBSIDIAN_VAULT_DIR" >> "$CONFLICT_FLAG_FILE" echo " 2. git status" >> "$CONFLICT_FLAG_FILE" echo " 3. Resolve conflict files" >> "$CONFLICT_FLAG_FILE" echo " 4. git add -A" >> "$CONFLICT_FLAG_FILE" echo " 5. git rebase --continue" >> "$CONFLICT_FLAG_FILE" echo " 6. git push" >> "$CONFLICT_FLAG_FILE" echo "Git sync conflict detected. Check $CONFLICT_FLAG_FILE for details." exit 1 fi # 推送 echo "Pushing to GitHub..." >> "$SYNC_LOG_FILE" if git push origin master >> "$SYNC_LOG_FILE" 2>&1; then echo "Sync completed successfully at $(date)" >> "$SYNC_LOG_FILE" rm -f "$CONFLICT_FLAG_FILE" exit 0 else echo "ERROR: Push failed" >> "$SYNC_LOG_FILE" exit 1 fi
帮助用户将读过书中的观点结构化为系统化笔记,包含原文补充、转述、深度追问和业务关联分析。
# 📚 Reading Notes - 读书笔记管理 Skill
> **核心使命**: 帮用户把读过的书变成结构化的知识资产
---
## 触发条件
**必须响应的关键词/场景:**
- 用户说"在读..."、"刚看了..."、"书里提到..."
- 用户分享书中的观点、金句、想法
- 用户明确说"记一下这个笔记"
**一旦触发,立即进入「读书笔记模式」**
---
## 工作流程
### 1. 识别书籍信息
从用户输入中提取:
- 书名(必须)
- 作者(尽量获取)
- 章节/页码(可选)
- 用户的核心想法/要点
### 2. 查找原文
- 使用搜索工具查找书籍原文
- 补充用户提到的要点的完整句子
- 确认上下文准确性
### 3. 创建/更新笔记
- 检查书籍目录是否存在,不存在则创建
- 按主题/章节创建笔记文件
- 使用模板格式化内容
### 4. 输出确认
- 告诉用户笔记已保存
- 简要复述记录的核心内容
---
## 文件结构
```
reading-notes/ # 数据存储目录
├── README.md # 书籍总览
├── _templates/ # 模板文件
│ ├── book-readme.md # 书籍信息页模板
│ └── note-template.md # 单条笔记模板
├── assets/ # 附件(书摘图片等)
└── {书名}/ # 每本书一个目录
├── README.md # 书籍信息
└── {主题}.md # 具体笔记
workspace/skills/reading-notes/ # Skill 代码
├── SKILL.md # 本文件
├── scripts/ # 辅助脚本
└── references/ # 参考文档
```
---
## 笔记格式规范
### 单条笔记必须包含:
```yaml
---
title: "笔记标题"
book: "书名"
author: "作者"
chapter: "章节名"
page: 页码
tags: [标签1, 标签2]
created: YYYY-MM-DD
---
```
### 内容结构:
1. **📖 原文摘录**
- 用户提到的要点
- 查找后的完整原文
- 出处信息
- **⚠️ 如果原文是并列结构(多个要点/步骤/要素),必须拆分为结构化表格**
2. **🔄 我的转述**(强制)
- 用自己的话重新表述原文概念
- 不是简单重复,而是真正理解后的表达
3. **❓ 5个为什么追问**(强制)
- 针对核心概念,连续追问至少3-5个「为什么」
- 层层深入,触及本质
- 每个「为什么」都要有答案
4. **💼 业务关联分析**(强制)
- **当前工作关联**:与现有工作/部门的关系?如何应用?
- **未来事业关联**:与想做的事业方向的关系?长期价值?
- **行动计划**:具体可以做什么?下一步行动?
5. **💭 我的感悟**(可选补充)
- 其他延伸思考
- 情感共鸣或反思
6. **🔗 关联思考**(可选)
- 关联概念
- 类似观点
- 其他书籍引用
---
## 输出格式
保存后向用户确认:
```
✅ 已记录笔记
📖 《书名》- 作者
📝 主题: xxx
💡 核心观点: (一句话概括)
📁 保存位置: reading-notes/书名/xxx.md
```
---
## 并列结构表格化规范
当原文包含并列要素(如:多个要点、步骤、条件、特征等),必须拆分为结构化表格,便于理解、搜索和记忆。
### 需要表格化的场景:
| 场景 | 原文特征 | 处理方式 |
|------|----------|----------|
| 列举型 | "有三个要点:A、B、C" | 表格列出每个要点 + 解释 |
| 步骤型 | "第一步...第二步..." | 表格列出步骤 + 操作 + 目的 |
| 对比型 | "A 是...B 是..." | 表格对比不同维度的差异 |
| 条件型 | "如果...那么..." | 表格列出条件 + 结果/行动 |
| 要素型 | "成功的 X 要素" | 表格列出要素 + 说明 + 重要性 |
### 表格格式示例:
**原文**: "高效能人士的七个习惯:积极主动、以终为始、要事第一、双赢思维、知彼解己、统合综效、不断更新"
**表格化后**:
```markdown
| 序号 | 习惯 | 核心含义 | 关键词 |
|------|------|----------|--------|
| 1 | 积极主动 | 对自己的选择负责,不被动反应 | 责任、选择 |
| 2 | 以终为始 | 先明确目标,再开始行动 | 愿景、目标 |
| 3 | 要事第一 | 优先处理重要但不紧急的事 | 优先级、专注 |
| 4 | 双赢思维 | 寻求互惠互利的解决方案 | 合作、共赢 |
| 5 | 知彼解己 | 先理解别人,再被理解 | 倾听、共情 |
| 6 | 统合综效 | 1+1>2,创造第三种选择 | 协作、创新 |
| 7 | 不断更新 | 在身体、精神、智力、社会情感上持续提升 | 成长、平衡 |
```
### 表格设计原则:
1. **列的选择**:根据内容类型选择合适的列
- 概念类:序号、术语、定义、关键词、关联概念
- 步骤类:步骤、操作、目的、注意事项
- 对比类:维度、A方、B方、差异点
2. **可读性**:
- 每列内容不宜过长
- 复杂概念用简短关键词概括
- 必要时添加「备注」列
3. **搜索友好**:
- 关键词单独成列
- 使用标准化的术语
- 避免口语化表达
---
## 每日内化提醒机制(21:00)
### 触发条件
- 当天有新记录的笔记
- 用户尚未完成「5个为什么 + 业务关联」内化流程
### 提醒流程
**每天晚上 21:00**,检查当天的新笔记:
1. **读取待内化清单**:`reading-notes/_pending/internalization.md`
2. **列出所有未完成条目**:
```
📚 今日待内化笔记 (X条)
1. 《书名》- 笔记主题
⏳ 状态: 待转述 + 5个为什么 + 业务关联
2. 《书名》- 笔记主题
⏳ 状态: 已完成转述,待5个为什么 + 业务关联
...
```
3. **逐项引导用户完成**:
- 我列出每一条笔记
- 用户逐一确认「是否已完成内化」
- 未完成的,引导用户现场完成
4. **完成后标记**:更新待内化清单状态
### 待内化清单格式
文件位置:`reading-notes/_pending/internalization.md`
```markdown
---
date: YYYY-MM-DD
status: pending | in-progress | completed
---
# 待内化笔记清单
| 序号 | 书名 | 笔记主题 | 文件路径 | 转述 | 5个为什么 | 业务关联 | 状态 |
|------|------|----------|----------|------|-----------|----------|------|
| 1 | 《原子习惯》| 系统胜过目标 | atomic-habits/systems.md | ⬜ | ⬜ | ⬜ | 待完成 |
| 2 | 《金字塔原理》| 四个基本原则 | pyramid-principle/four.md | ✅ | ⬜ | ⬜ | 进行中 |
## 完成记录
- [ ] 21:00 提醒已发送
- [ ] 用户已完成全部内化
```
### 用户响应方式
**用户可以说**:
- "第1条我完成了:...(给出转述和5个为什么)"
- "第2条跳过,暂时想不到关联"
- "全部完成"
- "明天再说"
**我的回应**:
- 将用户的内化内容补充到对应笔记文件中
- 更新待内化清单状态
- 确认完成度
---
## 完整示例(含内化流程)
### 步骤1: 用户分享
**用户输入:**
> 刚看《原子习惯》,书里说你不需要成为作家才能写作,每天写一页就行
### 步骤2: 我记录笔记
**创建笔记文件**: `atomic-habits/systems-over-goals.md`
```markdown
---
title: "系统胜过目标"
book: "原子习惯"
author: "James Clear"
chapter: "第一章"
page: null
tags: [习惯, 系统, 目标]
created: 2026-03-15
internalization:
paraphrase: ⬜
five_whys: ⬜
business_link: ⬜
---
# 系统胜过目标
## 📖 原文摘录
### 用户要点
> 不需要成为作家才能写作,每天写一页就行
### 原文完整句子
> "You do not rise to the level of your goals. You fall to the level of your systems."
> "Every action you take is a vote for the type of person you wish to become."
*出处: 《Atomic Habits》- James Clear,第一章*
---
## 🔄 我的转述(待完成)
<!-- 用自己的话重新表述 -->
⬜ 待补充...
---
## ❓ 5个为什么(待完成)
**核心概念**: 系统比目标更重要
1. **为什么系统比目标更重要?**
- ⬜ 待回答...
2. **为什么「每天写一页」比「成为作家」更有效?**
- ⬜ 待回答...
3. **为什么目标导向会失败?**
- ⬜ 待回答...
4. **为什么系统导向能持续?**
- ⬜ 待回答...
5. **为什么身份认同比结果更重要?**
- ⬜ 待回答...
---
## 💼 业务关联(待完成)
### 当前工作关联
⬜ 待思考...
### 未来事业关联
⬜ 待思考...
### 行动计划
- [ ]
---
## 💭 我的感悟
待补充...
```
**同时添加到待内化清单**: `reading-notes/_pending/internalization.md`
### 步骤3: 晚上21:00提醒
**我发送消息:**
```
🌙 21:00 内化提醒
今天记录了 1 条新笔记,需要完成深度内化:
📚 待内化笔记
1. 《原子习惯》- 系统胜过目标
⏳ 待完成:
⬜ 我的转述(用自己的话重新说一遍)
⬜ 5个为什么追问
⬜ 业务关联分析(当前工作 + 未来事业)
请逐项完成,或者直接告诉我你的想法,我来帮你整理~
```
### 步骤4: 用户完成内化
**用户回复:**
> 第1条:
> **转述**:目标只是方向,真正决定你能走多远的是日常的习惯系统。就像健身,定目标"瘦10斤"没用,有用的是每天去健身房那个动作。
>
> **5个为什么**:
> 1. 为什么系统更重要?因为目标是一次性的,系统是持续的
> 2. 为什么每天写一页更有效?因为行动塑造身份,不是身份决定行动
> 3. 为什么目标导向会失败?达成目标后就停了,没有持续机制
> 4. 为什么系统能持续?因为它变成了日常,不需要意志力
> 5. 为什么身份认同重要?因为你做的每件事都在投票给"你是谁"
>
> **业务关联**:
> - 当前工作:我做产品方案不应该只盯着上线那个目标,而是要建立「每周用户访谈」的系统
> - 未来事业:想做独立产品,现在就要建立「每天写代码/写文档」的系统,而不是等离职才开始
> - 行动:从明天开始,每天下班前写30分钟产品思考,不管写多少
### 步骤5: 我更新笔记文件
将用户的内化内容填充到对应位置,标记完成状态。
**最终输出确认:**
```
✅ 笔记已完整内化!
📖 《Atomic Habits》- James Clear
📝 主题: 系统胜过目标
✅ 转述:完成(用自己的话重新表述)
✅ 5个为什么:完成(层层深入触及本质)
✅ 业务关联:完成(工作+事业+行动)
📁 保存位置: reading-notes/atomic-habits/systems-over-goals.md
💡 核心洞察: 每天30分钟产品思考,投票给"我是产品经理"的身份
```
**用户输入:**
> 刚看《原子习惯》,书里说你不需要成为作家才能写作,每天写一页就行
**我的动作:**
1. 搜索《原子习惯》相关原文
2. 找到完整句子:"You do not rise to the level of your goals. You fall to the level of your systems."
3. 创建笔记文件
4. 向用户确认
**输出:**
```
✅ 已记录笔记
📖 《Atomic Habits》- James Clear
📝 主题: 系统胜过目标
💡 核心: 真正决定结果的是日常系统,不是宏大目标
📁 保存位置: reading-notes/atomic-habits/systems-over-goals.md
```
---
**用户输入(并列结构):**
> 刚看《金字塔原理》,书里讲思考问题的四个基本原则:结论先行、以上统下、归类分组、逻辑递进
**我的动作:**
1. 确认书籍信息:《金字塔原理》- 芭芭拉·明托
2. 找到原文完整表述
3. **将四个原则表格化**,每列包含:原则、含义、应用场景
4. 创建笔记文件
**输出:**
```
✅ 已记录笔记(含结构化表格)
📖 《金字塔原理》- 芭芭拉·明托
📝 主题: 思考问题的四个基本原则
💡 核心: 结构化表达的四个维度
📊 表格: 4个原则 × 3个维度(含义、应用、关键词)
📁 保存位置: reading-notes/pyramid-principle/four-principles.md
```
**笔记中的表格示例**:
```markdown
| 原则 | 核心含义 | 典型应用场景 | 关键词 |
|------|----------|--------------|--------|
| 结论先行 | 先说结论,再说论据 | 汇报、邮件、演讲开头 | 论点、中心思想 |
| 以上统下 | 上层是下层的概括 | 构建层级结构 | 总分、概括 |
| 归类分组 | 同类信息归为一组 | 整理复杂信息 | MECE、分类 |
| 逻辑递进 | 按逻辑顺序排列 | 论证过程、时间线 | 顺序、因果 |
```
---
## 注意事项
1. **书名标准化**: 使用英文原名(如有),便于后续搜索
2. **原文准确性**: 尽量找到完整句子,不确定时标注「大致意思」
3. **感悟个性化**: 不要套话,写出真实的思考
4. **标签一致性**: 使用统一的标签体系(待建立)
5. **⚠️ 并列结构必须表格化**: 遇到列举、步骤、对比、要素等并列内容,必须拆分为结构化表格
6. **⚠️ 内化流程是强制的**: 每个笔记必须包含「转述 + 5个为什么 + 业务关联」,未完成会在21:00提醒
7. **⚠️ 晚上21:00检查**: 每天检查当天新笔记的内化状态,发送提醒清单
---
## Obsidian 兼容性
笔记格式设计为可直接导入 Obsidian:
- YAML frontmatter → Obsidian 属性
- `[[链接]]` 语法支持双向链接
- `#标签` 语法支持标签检索
- 相对路径兼容 Obsidian 附件
---
*Skill 创建: 2026-03-15*
*版本: 1.2*
*Cron任务: `reading-notes-internalization` (每天 21:00)*
FILE:scripts/publish.sh
#!/bin/bash
# Reading Notes Skill 发布脚本
# 创建时间: 2026-03-16
SKILL_DIR="/root/.openclaw/workspace/skills/reading-notes"
SLUG="reading-notes"
NAME="Reading Notes"
VERSION="1.2.0"
CHANGELOG="Initial release: structured reading notes with table formatting, 5 Whys internalization, and daily 21:00 reminders"
echo "正在发布 NAME@VERSION..."
clawhub publish "SKILL_DIR" \
--slug "SLUG" \
--name "NAME" \
--version "VERSION" \
--changelog "CHANGELOG"
if [ $? -eq 0 ]; then
echo "✅ 发布成功!"
else
echo "❌ 发布失败,请检查错误信息"
fi