Created
March 12, 2026 14:03
-
-
Save canghai118/0230a50ac2afa49897634b70febe805a to your computer and use it in GitHub Desktop.
Paste Image to Remove Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # iterm_smart_paste.sh — iTerm2 零配置剪贴板文件/图片粘贴 | |
| # | |
| # 功能: | |
| # 1. Finder 中复制的文件 → 保留原始文件名上传到远程 | |
| # 2. 截图/图片数据 → 以 clip_<时间戳>.png 上传 | |
| # 3. 自动检测当前 iTerm2 会话的 SSH 连接和远程主机 | |
| # 4. 超过 20MB 的文件自动跳过并提示 | |
| # | |
| # iTerm2 快捷键设置: | |
| # Action: Run Coprocess... | |
| # Parameters: /bin/bash ~/bin/iterm_smart_paste.sh | |
| REMOTE_DIR="/tmp/remote-paste-files" | |
| MAX_SIZE=$((20 * 1024 * 1024)) # 20MB | |
| # ============================================================ | |
| # 工具函数 | |
| # ============================================================ | |
| notify() { | |
| osascript -e "display notification \"$1\" with title \"${2:-Paste}\"" >/dev/null 2>&1 | |
| } | |
| # 解析 ssh 命令行提取目标主机 | |
| parse_ssh_host() { | |
| local -a args | |
| read -ra args <<< "$1" | |
| local i=1 | |
| while [ $i -lt ${#args[@]} ]; do | |
| case "${args[$i]}" in | |
| -[BbcDEeFIiJLlmOopQRSWw]) ((i += 2)) ;; | |
| -[BbcDEeFIiJLlmOopQRSWw]*) ((i++)) ;; | |
| -*) ((i++)) ;; | |
| *) echo "${args[$i]}"; return ;; | |
| esac | |
| done | |
| } | |
| # ============================================================ | |
| # 0. 查找 pngpaste | |
| # ============================================================ | |
| PNGPASTE_CMD="/opt/homebrew/bin/pngpaste" | |
| [ ! -x "$PNGPASTE_CMD" ] && PNGPASTE_CMD="/usr/local/bin/pngpaste" | |
| [ ! -x "$PNGPASTE_CMD" ] && PNGPASTE_CMD="$(which pngpaste 2>/dev/null)" | |
| # ============================================================ | |
| # 1. 检测当前 iTerm2 会话的 SSH 连接 | |
| # ============================================================ | |
| SESSION_TTY=$(osascript -e ' | |
| tell application "iTerm2" | |
| tell current session of current window | |
| return tty | |
| end tell | |
| end tell' 2>/dev/null) | |
| SSH_HOST="" | |
| if [ -n "$SESSION_TTY" ]; then | |
| while IFS= read -r pid; do | |
| [ -z "$pid" ] && continue | |
| COMM=$(ps -p "$pid" -o comm= 2>/dev/null) | |
| if [ "$COMM" = "ssh" ] || [ "$COMM" = "autossh" ]; then | |
| SSH_HOST=$(parse_ssh_host "$(ps -p "$pid" -o args= 2>/dev/null)") | |
| break | |
| fi | |
| done < <(lsof -t "$SESSION_TTY" 2>/dev/null) | |
| fi | |
| # ============================================================ | |
| # 2a. 尝试获取 Finder 复制的文件路径 | |
| # ============================================================ | |
| FILE_PATHS=$(osascript <<'APPLESCRIPT' 2>/dev/null | |
| use framework "AppKit" | |
| use scripting additions | |
| set pb to current application's NSPasteboard's generalPasteboard() | |
| set fileURLs to pb's readObjectsForClasses:{current application's NSURL} options:(missing value) | |
| if fileURLs is missing value then return "" | |
| if (count of fileURLs) is 0 then return "" | |
| set output to "" | |
| repeat with fileURL in fileURLs | |
| if (fileURL's isFileURL()) as boolean then | |
| set filePath to (fileURL's |path|()) as text | |
| if output is not "" then | |
| set output to output & linefeed | |
| end if | |
| set output to output & filePath | |
| end if | |
| end repeat | |
| return output | |
| APPLESCRIPT | |
| ) | |
| VALID_FILES=() | |
| if [ -n "$FILE_PATHS" ]; then | |
| while IFS= read -r fpath; do | |
| [ -z "$fpath" ] && continue | |
| [ -f "$fpath" ] && VALID_FILES+=("$fpath") | |
| done <<< "$FILE_PATHS" | |
| fi | |
| if [ ${#VALID_FILES[@]} -gt 0 ]; then | |
| if [ -n "$SSH_HOST" ]; then | |
| ssh -q -o BatchMode=yes -o ConnectTimeout=5 \ | |
| "$SSH_HOST" "mkdir -p $REMOTE_DIR" >/dev/null 2>&1 | |
| OUTPUT="" | |
| SKIPPED=0 | |
| for fpath in "${VALID_FILES[@]}"; do | |
| fname=$(basename "$fpath") | |
| fsize=$(stat -f%z "$fpath" 2>/dev/null || echo 0) | |
| if [ "$fsize" -gt "$MAX_SIZE" ]; then | |
| SKIPPED=$((SKIPPED + 1)) | |
| notify "文件 $fname 超过 20MB,已跳过" "Paste" | |
| continue | |
| fi | |
| scp -q -o BatchMode=yes -o ConnectTimeout=5 \ | |
| "$fpath" "$SSH_HOST:$REMOTE_DIR/$fname" 2>/dev/null | |
| if [ $? -eq 0 ]; then | |
| OUTPUT="${OUTPUT:+$OUTPUT }$REMOTE_DIR/$fname" | |
| fi | |
| done | |
| if [ -n "$OUTPUT" ]; then | |
| echo -n "$OUTPUT" | |
| elif [ "$SKIPPED" -eq 0 ]; then | |
| notify "SCP 上传失败,请检查 SSH 免密配置" "Paste" | |
| fi | |
| else | |
| OUTPUT="" | |
| for fpath in "${VALID_FILES[@]}"; do | |
| OUTPUT="${OUTPUT:+$OUTPUT }$fpath" | |
| done | |
| echo -n "$OUTPUT" | |
| notify "未检测到 SSH 会话,输出本地路径" "Paste" | |
| fi | |
| exit 0 | |
| fi | |
| # ============================================================ | |
| # 2b. 尝试获取剪贴板中的图片数据(截图等) | |
| # ============================================================ | |
| if [ -x "$PNGPASTE_CMD" ]; then | |
| FILENAME="clip_$(date +%s).png" | |
| LOCAL_TMP_PATH="/tmp/$FILENAME" | |
| "$PNGPASTE_CMD" "$LOCAL_TMP_PATH" >/dev/null 2>&1 | |
| if [ $? -eq 0 ]; then | |
| fsize=$(stat -f%z "$LOCAL_TMP_PATH" 2>/dev/null || echo 0) | |
| if [ "$fsize" -gt "$MAX_SIZE" ]; then | |
| notify "图片超过 20MB,已取消" "Paste" | |
| rm -f "$LOCAL_TMP_PATH" | |
| exit 1 | |
| fi | |
| if [ -n "$SSH_HOST" ]; then | |
| ssh -q -o BatchMode=yes -o ConnectTimeout=5 \ | |
| "$SSH_HOST" "mkdir -p $REMOTE_DIR" >/dev/null 2>&1 | |
| scp -q -o BatchMode=yes -o ConnectTimeout=5 \ | |
| "$LOCAL_TMP_PATH" "$SSH_HOST:$REMOTE_DIR/$FILENAME" 2>/dev/null | |
| if [ $? -eq 0 ]; then | |
| echo -n "$REMOTE_DIR/$FILENAME" | |
| rm -f "$LOCAL_TMP_PATH" | |
| else | |
| notify "SCP 上传失败,请检查 SSH 免密配置" "Paste" | |
| echo -n "$LOCAL_TMP_PATH" | |
| fi | |
| else | |
| echo -n "$LOCAL_TMP_PATH" | |
| notify "未检测到 SSH 会话,输出本地路径" "Paste" | |
| fi | |
| exit 0 | |
| fi | |
| fi | |
| # 剪贴板中没有可用的文件或图片 | |
| exit 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment