From 9efd731f98629ce8b4ec9dea73a1c7624e1d5f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Sat, 4 Oct 2025 14:02:02 +0000 Subject: [PATCH] =?UTF-8?q?Initial=20commit:=20Raspberry=20Pi=20CUPS=20?= =?UTF-8?q?=EB=B8=8C=EB=9D=BC=EB=8D=94=20=ED=94=84=EB=A6=B0=ED=84=B0=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EB=A6=AC=ED=8F=AC=EC=A7=80=ED=86=A0?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✨ 주요 목적: - 라즈베리파이 3B+에서 브라더 프린터 CUPS 설정 - wget으로 브라더 프린터 드라이버(gz) 쉽게 다운로드 - 프린터 설정 자동화 스크립트 및 문서 제공 📦 포함 파일: - linux-brprinter-installer-2.2.6-0.gz: 브라더 프린터 드라이버 - 각종 설정 문서 (COM 포트, Samba 마운트, 동기화 등) - Gitea 저장소 가이드 🔧 기술 스택: - Raspberry Pi OS - CUPS (Common Unix Printing System) - Brother printer driver 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- com포트자동.md | 64 ++++++ git.md | 311 +++++++++++++++++++++++++++ gitea.md | 0 linux-brprinter-installer-2.2.6-0.gz | Bin 0 -> 25030 bytes rpi_com_redirect.md | 54 +++++ sync.md | 88 ++++++++ 삼바마운트.md | 55 +++++ 팩스서버. md | 6 + 8 files changed, 578 insertions(+) create mode 100644 com포트자동.md create mode 100644 git.md create mode 100644 gitea.md create mode 100644 linux-brprinter-installer-2.2.6-0.gz create mode 100644 rpi_com_redirect.md create mode 100644 sync.md create mode 100644 삼바마운트.md create mode 100644 팩스서버. md diff --git a/com포트자동.md b/com포트자동.md new file mode 100644 index 0000000..8b3f043 --- /dev/null +++ b/com포트자동.md @@ -0,0 +1,64 @@ +sudo systemctl stop rdpclient + +cat | sudo tee /home/pi/rdp-start.sh > /dev/null <<'EOF' +#!/bin/bash +set -eu + +# ---- USB-Serial 자동 탐색 (Honeywell 우선) ---- +DEV="" +for CAND in /dev/ttyACM* /dev/ttyUSB*; do + if [ -e "$CAND" ]; then + VENDOR=$(udevadm info -q all -n "$CAND" 2>/dev/null | grep ID_VENDOR_ID || true) + PRODUCT=$(udevadm info -q all -n "$CAND" 2>/dev/null | grep ID_MODEL_ID || true) + if echo "$VENDOR$PRODUCT" | grep -qi "0c2e"; then + DEV="$CAND" + break + fi + fi +done + +if [ -n "$DEV" ]; then + echo "[RDP-START] serial redirect: $DEV -> COM3" + SERIAL_OPT="/serial:COM3,${DEV},Serial" +else + echo "[RDP-START] WARNING: no Honeywell device found; skipping serial redirect" + SERIAL_OPT="" +fi + +# ---- 경량 WM + 화면 절전 방지 ---- +openbox-session & +xset s off +xset -dpms +xset s noblank +setxkbmap us || true + +# ---- 접속 기본값 ---- +SIZE="1920x1080" +BPP="16" +SRV="pharmq.kr:7390" +USR="pqserver" +PW="pharmq119" + +# ---- 성능 최적화 (윈도우 UI 효과 제거) ---- +PERF="-wallpaper -themes -menu-anims -window-drag" + +# ---- FreeRDP 공통 옵션 ---- +BASE="/u:${USR} /p:${PW} /v:${SRV} \ +/bpp:${BPP} /clipboard /cert:ignore \ +/compression /network:lan ${PERF} /log-level:INFO /f" + +# ---- 코덱 순차 시도 ---- +for MODE in "/gfx:avc420" "/gfx" "/rfx" ""; do + LABEL="${MODE:-bitmap}" + echo "[RDP-START] trying: xfreerdp3 ${LABEL}" + if xfreerdp3 $BASE $SERIAL_OPT $MODE; then + echo "[RDP-START] connected with: ${LABEL}" + exit 0 + fi +done + +exit 1 +EOF + +sudo chmod +x /home/pi/rdp-start.sh +sudo systemctl start rdpclient diff --git a/git.md b/git.md new file mode 100644 index 0000000..68bc494 --- /dev/null +++ b/git.md @@ -0,0 +1,311 @@ +# Gitea 리포지토리 생성 및 푸시 가이드 + +## 🏠 서버 정보 + +- **Gitea 서버**: `git.0bin.in` +- **사용자명**: `thug0bin` +- **이메일**: `thug0bin@gmail.com` +- **액세스 토큰**: `d83f70b219c6028199a498fb94009f4c1debc9a9` + +## 🚀 새 리포지토리 생성 및 푸시 과정 + +### 1. 로컬 Git 리포지토리 초기화 + +```bash +# 프로젝트 디렉토리로 이동 +cd /path/to/your/project + +# Git 초기화 +git init + +# .gitignore 파일 생성 (필요시) +cat > .gitignore << 'EOF' +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +dist/ +build/ + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ + +# Database +*.db +*.sqlite +*.sqlite3 +EOF +``` + +### 2. Git 사용자 설정 확인 + +```bash +# Git 사용자 정보 확인 +git config --list | grep -E "user" + +# 설정되지 않은 경우 설정 +git config --global user.name "시골약사" +git config --global user.email "thug0bin@gmail.com" +``` + +### 3. 첫 번째 커밋 + +```bash +# 모든 파일 스테이징 +git add . + +# 첫 커밋 (상세한 커밋 메시지 예시) +git commit -m "$(cat <<'EOF' +Initial commit: [프로젝트명] + +✨ [주요 기능 설명] +- 기능 1 +- 기능 2 +- 기능 3 + +🛠️ 기술 스택: +- 사용된 기술들 나열 + +🔧 주요 구성: +- 프로젝트 구조 설명 + +🤖 Generated with [Claude Code](https://claude.ai/code) + +Co-Authored-By: Claude +EOF +)" +``` + +### 4. 원격 리포지토리 연결 및 푸시 + +```bash +# 원격 리포지토리 추가 (리포지토리명을 실제 이름으로 변경) +git remote add origin https://thug0bin:d83f70b219c6028199a498fb94009f4c1debc9a9@git.0bin.in/thug0bin/[REPOSITORY_NAME].git + +# 브랜치를 main으로 변경 +git branch -M main + +# 원격 리포지토리로 푸시 +git push -u origin main +``` + +## 📝 리포지토리명 네이밍 규칙 + +### 권장 네이밍 패턴: +- **프론트엔드 프로젝트**: `project-name-frontend` +- **백엔드 프로젝트**: `project-name-backend` +- **풀스택 프로젝트**: `project-name-fullstack` +- **도구/유틸리티**: `tool-name-utils` +- **문서/가이드**: `project-name-docs` + +### 예시: +- `figma-admin-dashboard` ✅ +- `anipharm-api-server` ✅ +- `inventory-management-system` ✅ +- `member-portal-frontend` ✅ + +## 🔄 기존 리포지토리에 추가 커밋 + +```bash +# 변경사항 확인 +git status + +# 변경된 파일 스테이징 +git add . + +# 또는 특정 파일만 스테이징 +git add path/to/specific/file + +# 커밋 +git commit -m "커밋 메시지" + +# 푸시 +git push origin main +``` + +## 🌿 브랜치 작업 + +```bash +# 새 브랜치 생성 및 전환 +git checkout -b feature/new-feature + +# 브랜치에서 작업 후 커밋 +git add . +git commit -m "Feature: 새로운 기능 추가" + +# 브랜치 푸시 +git push -u origin feature/new-feature + +# main 브랜치로 돌아가기 +git checkout main + +# 브랜치 병합 (필요시) +git merge feature/new-feature +``` + +## 🛠️ 자주 사용하는 Git 명령어 + +```bash +# 현재 상태 확인 +git status + +# 변경 내역 확인 +git diff + +# 커밋 히스토리 확인 +git log --oneline + +# 원격 리포지토리 정보 확인 +git remote -v + +# 특정 포트 프로세스 종료 (개발 서버 관련) +lsof -ti:PORT_NUMBER | xargs -r kill -9 +``` + +## 🔧 포트 관리 스크립트 + +```bash +# 특정 포트 종료 함수 추가 (bashrc에 추가 가능) +killport() { + if [ -z "$1" ]; then + echo "Usage: killport " + return 1 + fi + lsof -ti:$1 | xargs -r kill -9 + echo "Killed processes on port $1" +} + +# 사용 예시 +# killport 7738 +# killport 5000 +``` + +## 📋 VS Code 워크스페이스 설정 + +여러 리포지토리를 동시에 관리하려면 워크스페이스 파일을 생성하세요: + +```json +{ + "folders": [ + { + "name": "Main Repository", + "path": "." + }, + { + "name": "New Project", + "path": "./new-project-folder" + } + ], + "settings": { + "git.enableSmartCommit": true, + "git.confirmSync": false, + "git.autofetch": true + } +} +``` + +## 🚨 문제 해결 + +### 1. 인증 실패 +```bash +# 토큰이 만료된 경우, 새 토큰으로 원격 URL 업데이트 +git remote set-url origin https://thug0bin:NEW_TOKEN@git.0bin.in/thug0bin/repo-name.git +``` + +### 2. 푸시 거부 +```bash +# 원격 변경사항을 먼저 가져오기 +git pull origin main --rebase + +# 충돌 해결 후 푸시 +git push origin main +``` + +### 3. 대용량 파일 문제 +```bash +# Git LFS 설정 (필요시) +git lfs install +git lfs track "*.zip" +git lfs track "*.gz" +git add .gitattributes +``` + +## 📊 커밋 메시지 템플릿 + +### 기본 템플릿: +``` +타입: 간단한 설명 + +상세한 설명 (선택사항) + +🤖 Generated with [Claude Code](https://claude.ai/code) + +Co-Authored-By: Claude +``` + +### 타입별 예시: +- `✨ feat: 새로운 기능 추가` +- `🐛 fix: 버그 수정` +- `📝 docs: 문서 업데이트` +- `🎨 style: 코드 포맷팅` +- `♻️ refactor: 코드 리팩토링` +- `⚡ perf: 성능 개선` + +- `✅ test: 테스트 추가` +- `🔧 chore: 빌드 설정 변경` + +## 🔗 유용한 링크 + +- **Gitea 웹 인터페이스**: https://git.0bin.in/ +- **내 리포지토리 목록**: https://git.0bin.in/thug0bin +- **새 리포지토리 생성**: https://git.0bin.in/repo/create + +## 💡 팁과 모범 사례 + +1. **정기적인 커밋**: 작은 단위로 자주 커밋 +하세요 +2. **의미있는 커밋 메시지**: 변경 사항을 명확히 설명하세요 +3. **브랜치 활용**: 기능별로 브랜치를 나누어 작업하세요 +4. **.gitignore 활용**: 불필요한 파일은 제외하세요 +5. **문서화**: README.md와 같은 문서를 항상 업데이트하세요 + +--- + +**작성일**: 2025년 7월 29일 +**마지막 업데이트**: 토큰 및 서버 정보 최신화 +**참고**: 이 가이드는 재사용 가능하도록 작성되었습니다. 새 프로젝트마다 참고하세요. + +> 💡 **중요**: 액세스 토큰은 보안이 중요한 정보입니다. 공개 저장소에 업로드하지 마세요! \ No newline at end of file diff --git a/gitea.md b/gitea.md new file mode 100644 index 0000000..e69de29 diff --git a/linux-brprinter-installer-2.2.6-0.gz b/linux-brprinter-installer-2.2.6-0.gz new file mode 100644 index 0000000000000000000000000000000000000000..ea5588a1b864bd48dc40e954570499de06d792be GIT binary patch literal 25030 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 gxjId|AZqQQ_ COM3" + SERIAL_OPT="/serial:COM3,${DEV},Serial" +else + echo "[RDP-START] WARNING: no /dev/ttyACM* or /dev/ttyUSB* found; skipping serial redirect" + SERIAL_OPT="" +fi + +# ---- 경량 WM + 화면 절전 방지 ---- +openbox-session >/dev/null 2>&1 & +xset s off +xset -dpms +xset s noblank +setxkbmap us || true + +# ---- 접속 기본값 ---- +SIZE="1920x1080" +BPP="16" +SRV="pharmq.kr:7390" +USR="pqserver" +PW="pharmq119" + +# ---- 성능 최적화 (윈도우 UI 효과 제거) ---- +PERF="-wallpaper -themes -menu-anims -window-drag" + +# ---- FreeRDP 공통 옵션 ---- +BASE="/u:${USR} /p:${PW} /v:${SRV} \ +/size:${SIZE} /bpp:${BPP} /clipboard /cert:ignore \ +/compression /network:lan ${PERF} /log-level:INFO" + +# ---- 코덱 순차 시도 ---- +for MODE in "/gfx:avc420" "/gfx" "/rfx" ""; do + LABEL="${MODE:-bitmap}" + echo "[RDP-START] trying: xfreerdp3 ${LABEL}" + if xfreerdp3 $BASE $SERIAL_OPT $MODE; then + echo "[RDP-START] connected with: ${LABEL}" + exit 0 + fi +done + diff --git a/sync.md b/sync.md new file mode 100644 index 0000000..8eb0584 --- /dev/null +++ b/sync.md @@ -0,0 +1,88 @@ +# 1) 필요 패키지 +sudo apt update +sudo apt install -y inotify-tools rsync + +# 2) 수신 폴더/마운트 경로 확인(없으면 생성) +sudo mkdir -p /var/spool/hylafax/recvq +sudo mkdir -p /mnt/fax + +# 3) 실시간 이동 스크립트 생성 +cat | sudo tee /usr/local/bin/move-fax.sh >/dev/null <<'EOF' +#!/bin/bash +set -euo pipefail + +SRC="/var/spool/hylafax/recvq" +DST="/mnt/fax" +LOG="/var/log/fax-move.log" + +echo "[FAX-MOVE] started (SRC=${SRC}, DST=${DST})" | tee -a "$LOG" + +# NAS 마운트 대기(최대 60초) +for i in {1..60}; do + if mountpoint -q "$DST"; then + echo "[FAX-MOVE] mount OK: $DST" | tee -a "$LOG" + break + fi + if [ "$i" -eq 60 ]; then + echo "[FAX-MOVE] mount not ready after 60s, continuing and will keep trying..." | tee -a "$LOG" + fi + sleep 1 +done + +# inotify: 새 파일이 완전히 닫히거나(moved_to/close_write) 도착하면 처리 +# TIFF/TIF/PDF 우선 감시(확장자 제한 없이 동작 가능, 여기서는 전체 감시 후 파일만 필터) +inotifywait -m -e close_write -e moved_to --format '%w%f' "$SRC" | while read -r FILE; do + # 파일만 처리 + [ -f "$FILE" ] || continue + + BASENAME="$(basename "$FILE")" + TARGET="${DST}/${BASENAME}" + + # 마운트 점검(중간에 끊겼을 수도 있음) + if ! mountpoint -q "$DST"; then + echo "[FAX-MOVE] WARN: NAS not mounted, skip: $BASENAME" | tee -a "$LOG" + continue + fi + + # 복사 후 소스 제거(성공시에만) + if rsync -a --partial --inplace "$FILE" "$TARGET"; then + sync + rm -f -- "$FILE" + echo "[FAX-MOVE] moved: $BASENAME -> $DST" | tee -a "$LOG" + else + echo "[FAX-MOVE] ERROR: rsync failed for $BASENAME" | tee -a "$LOG" + fi +done +EOF + +sudo chmod +x /usr/local/bin/move-fax.sh + +# 4) systemd 서비스 유닛 생성 +cat | sudo tee /etc/systemd/system/fax-move.service >/dev/null <<'EOF' +[Unit] +Description=Move received faxes to NAS (real-time) +After=network-online.target mnt-fax.mount +Wants=network-online.target +Requires=mnt-fax.mount +ConditionPathIsDirectory=/var/spool/hylafax/recvq +ConditionPathIsMountPoint=/mnt/fax + +[Service] +Type=simple +ExecStart=/usr/local/bin/move-fax.sh +Restart=always +RestartSec=2 +User=pi +# NAS 일시 끊김 대비로 환경변수 여유(선택) +Environment=RSYNC_RSH=ssh + +[Install] +WantedBy=multi-user.target +EOF + +# 5) 적용 및 시작 +sudo systemctl daemon-reload +sudo systemctl enable --now fax-move.service + +# 6) 동작 확인(로그 tail) +sudo journalctl -u fax-move.service -n 50 -f diff --git a/삼바마운트.md b/삼바마운트.md new file mode 100644 index 0000000..a0e59ea --- /dev/null +++ b/삼바마운트.md @@ -0,0 +1,55 @@ +좋습니다 👍 지금 상황은 단순해요. +/etc/samba/ 폴더가 기본적으로 없는 경우가 있습니다. 그래서 nano에서 파일을 열려고 하면 "그런 파일이나 디렉터리가 없습니다" 라는 메시지가 나옵니다. + +해결 방법 +먼저 디렉터리를 만들어주세요: + +sudo mkdir -p /etc/samba +그다음 다시 자격증명 파일을 여세요: + +sudo nano /etc/samba/creds-fax +그리고 안에 다음을 입력합니다: + +username=0bin +password=@Trajet6640 +저장 후 나와서 권한 제한: + +sudo chmod 600 /etc/samba/creds-fax +✅ 이렇게 하면 /etc/samba/creds-fax 파일이 생기고, systemd에서 마운트 설정할 때 사용할 수 있어요. + +👉 원하시면 제가 바로 /etc/systemd/system/mnt-fax.mount 유닛까지 한방팩으로 작성해드릴까요? + +나의 말: +이제됫어 다음은 어떻게해 크리덴셜파일까지 생성해성 +ChatGPT의 말: +좋습니다 👌 이제 크리덴셜 파일까지 잘 만들었으니, 다음은 systemd 마운트 유닛을 만들어서 라즈베리파이가 켜질 때 자동으로 \\192.168.0.211\fax 를 /mnt/fax 로 마운트되도록 하면 됩니다. + +1. 마운트할 디렉터리 만들기 +sudo mkdir -p /mnt/fax +2. systemd 마운트 유닛 작성 +/etc/systemd/system/mnt-fax.mount 파일 생성: + +sudo nano /etc/systemd/system/mnt-fax.mount +내용 입력: + +[Unit] +Description=Mount SMB Share for Fax +After=network-online.target +Wants=network-online.target + +[Mount] +What=//192.168.0.211/fax +Where=/mnt/fax +Type=cifs +Options=credentials=/etc/samba/creds-fax,iocharset=utf8,vers=3.0,uid=pi,gid=pi,file_mode=0660,dir_mode=0770 + +[Install] +WantedBy=multi-user.target +3. systemd 리로드 & 마운트 +sudo systemctl daemon-reload +sudo systemctl enable mnt-fax.mount +sudo systemctl start mnt-fax.mount +4. 확인 +mount | grep fax +ls -l /mnt/fax +여기까지 하면 SMB 공유가 자동으로 /mnt/fax 에 마운트돼요. \ No newline at end of file diff --git a/팩스서버. md b/팩스서버. md new file mode 100644 index 0000000..f42065f --- /dev/null +++ b/팩스서버. md @@ -0,0 +1,6 @@ +1. NAS에 FAX 폴더 SMB로 마운트 +2. inotify 로 실시간 감시 +3. 수신되면 일단 라즈베리파이에 저장 (안정성 확보), +4. 수신될걸 FAX폴더 (NAS로 복사) +5. USB faxmodem으로 fax 안정적으로 수신후 , 라즈베리파이 저장 +6. 트리거로 cups로 인쇄된것 쏘기(즉시 네트워크 프린터로 인쇄 및 TTS 발송)