<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>로아</title>
    <link>https://roaroa.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 13:43:14 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>로아_</managingEditor>
    <item>
      <title>라즈베리파이 B+ 에서 nvim(neovim) 최신버전설치</title>
      <link>https://roaroa.tistory.com/129</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이에서 lazyvim을 설치하려니 neovim 0.11.2 버전 이상이 필요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #1c1e21; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Neovim &amp;gt;=&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;0.11.2&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(needs to be built with&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;LuaJIT&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈비안에서 공식 설치 이미지는 0.7버전이 마지막이 었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 neovim git 공식저장소에서 소스 받은 후 직접 빌드 후 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드시간은 3시간 이상 걸린듯하다. (라즈베리파이 B+ 사양 한계)&lt;/p&gt;
&lt;pre id=&quot;code_1762388186319&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update
sudo apt install -y ninja-build gettext cmake unzip curl build-essential git
git clone https://github.com/neovim/neovim.git
cd neovim
git checkout stable
make CMAKE_BUILD_TYPE=Release
sudo make install&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Server/Raspbian</category>
      <category>lazyvim</category>
      <category>Neovim</category>
      <category>nvim</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/129</guid>
      <comments>https://roaroa.tistory.com/129#entry129comment</comments>
      <pubDate>Thu, 6 Nov 2025 09:16:58 +0900</pubDate>
    </item>
    <item>
      <title>PowerToys</title>
      <link>https://roaroa.tistory.com/128</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;PowerToys&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DTc8q/dJMcadG5CJE/9FogXoYK38TFIehHszhseK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DTc8q/dJMcadG5CJE/9FogXoYK38TFIehHszhseK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DTc8q/dJMcadG5CJE/9FogXoYK38TFIehHszhseK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDTc8q%2FdJMcadG5CJE%2F9FogXoYK38TFIehHszhseK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1091&quot; height=&quot;768&quot; data-origin-width=&quot;1091&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;372&quot; data-start=&quot;355&quot; data-ke-size=&quot;size26&quot;&gt;  PowerToys란?&lt;/h2&gt;
&lt;p data-end=&quot;500&quot; data-start=&quot;374&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PowerToys&lt;/b&gt;는 마이크로소프트에서 공식 제공하는 &lt;b&gt;윈도우용 오픈소스 유틸리티 세트&lt;/b&gt;입니다.&lt;br /&gt;Windows 95 시절부터 존재했으며, 현재는 &lt;b&gt;Windows 10과 11&lt;/b&gt;에서 무료로 사용할 수 있습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;658&quot; data-start=&quot;502&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;515&quot; data-start=&quot;504&quot; data-ke-size=&quot;size16&quot;&gt;  설치 방법:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;658&quot; data-start=&quot;518&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;554&quot; data-start=&quot;518&quot;&gt;Microsoft Store에서 &amp;ldquo;PowerToys&amp;rdquo; 검색&lt;/li&gt;
&lt;li data-end=&quot;658&quot; data-start=&quot;557&quot;&gt;또는 GitHub의 &lt;a href=&quot;https://github.com/microsoft/PowerToys/releases&quot; data-end=&quot;643&quot; data-start=&quot;570&quot;&gt;PowerToys Releases 페이지&lt;span aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&lt;/a&gt;에서 설치 파일 다운로드&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;711&quot; data-start=&quot;660&quot; data-ke-size=&quot;size16&quot;&gt;설치 후 작업 표시줄에 파란색 &amp;ldquo;PT&amp;rdquo; 아이콘이 생기며, 각 기능을 켜거나 끌 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;716&quot; data-start=&quot;713&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;732&quot; data-start=&quot;718&quot; data-ke-size=&quot;size26&quot;&gt;  주요 기능 소개&lt;/h2&gt;
&lt;h3 data-end=&quot;772&quot; data-start=&quot;734&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ &lt;b&gt;FancyZones &amp;mdash; 윈도우 창 레이아웃 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;856&quot; data-start=&quot;774&quot; data-ke-size=&quot;size16&quot;&gt;멀티모니터 사용자나 창을 여러 개 띄워두는 사람에게 필수 기능입니다.&lt;br /&gt;드래그 한 번으로 &lt;b&gt;창을 원하는 구역에 자동 배치&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;946&quot; data-start=&quot;858&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;903&quot; data-start=&quot;858&quot;&gt;사용 예시: 화면을 3분할로 나눠 개발툴, 브라우저, 터미널을 깔끔히 정렬&lt;/li&gt;
&lt;li data-end=&quot;946&quot; data-start=&quot;904&quot;&gt;단축키: Shift 키를 누른 채 창을 드래그하면 자동 정렬 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;1023&quot; data-start=&quot;948&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1023&quot; data-start=&quot;950&quot; data-ke-size=&quot;size16&quot;&gt;  비슷한 프로그램으로 AquaSnap, Divvy 등이 있지만, PowerToys는 무료 + 윈도우 통합이라는 장점이 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1028&quot; data-start=&quot;1025&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1066&quot; data-start=&quot;1030&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ &lt;b&gt;PowerToys Run &amp;mdash; 빠른 실행 런처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1152&quot; data-start=&quot;1068&quot; data-ke-size=&quot;size16&quot;&gt;Alt + Space를 누르면 등장하는 &lt;b&gt;빠른 검색창&lt;/b&gt;입니다.&lt;br /&gt;앱 실행, 파일 검색, 계산기, 명령어 실행 등 무엇이든 입력만 하면 됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1231&quot; data-start=&quot;1154&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1176&quot; data-start=&quot;1154&quot;&gt;예: calc &amp;rarr; 계산기 실행&lt;/li&gt;
&lt;li data-end=&quot;1202&quot; data-start=&quot;1177&quot;&gt;예: cmd &amp;rarr; 명령 프롬프트 실행&lt;/li&gt;
&lt;li data-end=&quot;1231&quot; data-start=&quot;1203&quot;&gt;예: =45*3 &amp;rarr; 바로 계산 결과 표시&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1276&quot; data-start=&quot;1233&quot; data-ke-size=&quot;size16&quot;&gt;Mac의 Spotlight 같은 기능이라 &lt;b&gt;작업 흐름이 훨씬 빨라집니다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1281&quot; data-start=&quot;1278&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1320&quot; data-start=&quot;1283&quot; data-ke-size=&quot;size23&quot;&gt;3️⃣ &lt;b&gt;Color Picker &amp;mdash; 화면의 색상 추출기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1423&quot; data-start=&quot;1322&quot; data-ke-size=&quot;size16&quot;&gt;디자인 작업이나 블로그 이미지 편집할 때 유용합니다.&lt;br /&gt;Win + Shift + C를 누르면 마우스 커서 아래의 **색상 코드(HEX, RGB)**를 바로 복사할 수 있습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1465&quot; data-start=&quot;1425&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1465&quot; data-start=&quot;1427&quot; data-ke-size=&quot;size16&quot;&gt;  예: 웹사이트의 버튼 색상이나 배경색을 똑같이 맞출 때 편리&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1470&quot; data-start=&quot;1467&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1513&quot; data-start=&quot;1472&quot; data-ke-size=&quot;size23&quot;&gt;4️⃣ &lt;b&gt;Text Extractor &amp;mdash; 이미지 속 텍스트 복사&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1598&quot; data-start=&quot;1515&quot; data-ke-size=&quot;size16&quot;&gt;스크린샷에 있는 글자를 **OCR(문자 인식)**으로 추출해줍니다.&lt;br /&gt;Win + Shift + T로 영역을 지정하면, 텍스트가 자동 복사됩니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1642&quot; data-start=&quot;1600&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1642&quot; data-start=&quot;1602&quot; data-ke-size=&quot;size16&quot;&gt;예: 캡처 이미지 속 오류 메시지, 영수증 텍스트를 그대로 복사 가능&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1647&quot; data-start=&quot;1644&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1700&quot; data-start=&quot;1649&quot; data-ke-size=&quot;size23&quot;&gt;5️⃣ &lt;b&gt;File Locksmith &amp;mdash; 어떤 프로세스가 파일을 점유 중인지 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1797&quot; data-start=&quot;1702&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 파일이 사용 중이라 삭제할 수 없습니다&amp;rdquo;라는 메시지, 누구나 한 번쯤 봤죠.&lt;br /&gt;이 기능을 쓰면 &lt;b&gt;어떤 프로그램이 파일을 잡고 있는지 바로 확인&lt;/b&gt;할 수 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1863&quot; data-start=&quot;1799&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1837&quot; data-start=&quot;1799&quot;&gt;탐색기에서 파일 우클릭 &amp;rarr; &amp;ldquo;File Locksmith&amp;rdquo; 선택&lt;/li&gt;
&lt;li data-end=&quot;1863&quot; data-start=&quot;1838&quot;&gt;점유 프로세스 확인 및 바로 종료 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1868&quot; data-start=&quot;1865&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1909&quot; data-start=&quot;1870&quot; data-ke-size=&quot;size23&quot;&gt;6️⃣ &lt;b&gt;Image Resizer &amp;mdash; 이미지 일괄 리사이즈&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1947&quot; data-start=&quot;1911&quot; data-ke-size=&quot;size16&quot;&gt;여러 이미지를 한 번에 줄이거나 확대하고 싶을 때 간편합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2000&quot; data-start=&quot;1948&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1972&quot; data-start=&quot;1948&quot;&gt;파일 탐색기에서 이미지 여러 개 선택&lt;/li&gt;
&lt;li data-end=&quot;2000&quot; data-start=&quot;1973&quot;&gt;우클릭 &amp;rarr; &amp;ldquo;Resize pictures&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2063&quot; data-start=&quot;2002&quot; data-ke-size=&quot;size16&quot;&gt;미리 설정한 크기(예: 800px, 1080p 등)로 자동 변환되며, 블로그용 이미지 편집에 특히 유용합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2068&quot; data-start=&quot;2065&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2106&quot; data-start=&quot;2070&quot; data-ke-size=&quot;size23&quot;&gt;7️⃣ &lt;b&gt;Keyboard Manager &amp;mdash; 키 리매핑&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2165&quot; data-start=&quot;2108&quot; data-ke-size=&quot;size16&quot;&gt;잘 안 쓰는 키를 다른 기능으로 바꾸거나, 특정 단축키를 새로 지정할 수 있습니다.&lt;br /&gt;예를 들어,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2258&quot; data-start=&quot;2166&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2188&quot; data-start=&quot;2166&quot;&gt;Caps Lock &amp;rarr; Ctrl&lt;/li&gt;
&lt;li data-end=&quot;2258&quot; data-start=&quot;2189&quot;&gt;Alt + S &amp;rarr; Snipping Tool 실행&lt;br /&gt;같은 식으로 완전한 &lt;b&gt;커스터마이징 키맵&lt;/b&gt;을 만들 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2263&quot; data-start=&quot;2260&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2304&quot; data-start=&quot;2265&quot; data-ke-size=&quot;size23&quot;&gt;8️⃣ &lt;b&gt;Mouse Utilities &amp;mdash; 마우스 강조 도구&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2390&quot; data-start=&quot;2306&quot; data-ke-size=&quot;size16&quot;&gt;Ctrl 키를 두 번 누르면 &lt;b&gt;마우스 위치를 하이라이트&lt;/b&gt;해줍니다.&lt;br /&gt;프레젠테이션, 화면 녹화, 튜토리얼 영상 제작 시 시선 유도에 탁월합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2395&quot; data-start=&quot;2392&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2434&quot; data-start=&quot;2397&quot; data-ke-size=&quot;size23&quot;&gt;9️⃣ &lt;b&gt;Quick Accent &amp;mdash; 특수문자 입력 보조&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2525&quot; data-start=&quot;2436&quot; data-ke-size=&quot;size16&quot;&gt;영문 자판에서도 &lt;b&gt;&amp;eacute;, &amp;ntilde;, &amp;uuml;&lt;/b&gt; 같은 발음기호 문자를 쉽게 입력할 수 있습니다.&lt;br /&gt;단축키로 활성화 후 해당 알파벳을 길게 누르면 자동으로 옵션이 뜹니다.&lt;/p&gt;
&lt;hr data-end=&quot;2530&quot; data-start=&quot;2527&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2579&quot; data-start=&quot;2532&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;Hosts File Editor &amp;mdash; hosts 파일 GUI 편집기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;2691&quot; data-start=&quot;2581&quot; data-ke-size=&quot;size16&quot;&gt;C:\Windows\System32\drivers\etc\hosts 파일을 쉽게 관리할 수 있게 해줍니다.&lt;br /&gt;도메인 테스트나 서버 전환 시 매우 유용하며, GUI로 직관적으로 수정 가능합니다.&lt;/p&gt;
&lt;hr data-end=&quot;2696&quot; data-start=&quot;2693&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2716&quot; data-start=&quot;2698&quot; data-ke-size=&quot;size26&quot;&gt; ️ 그 외 유용한 기능들&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2901&quot; data-start=&quot;2718&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2761&quot; data-start=&quot;2718&quot;&gt;&lt;b&gt;Peek&lt;/b&gt;: 파일을 선택하고 Ctrl + Space로 미리보기&lt;/li&gt;
&lt;li data-end=&quot;2810&quot; data-start=&quot;2762&quot;&gt;&lt;b&gt;Paste as Plain Text&lt;/b&gt;: 복사한 텍스트를 서식 없이 붙여넣기&lt;/li&gt;
&lt;li data-end=&quot;2852&quot; data-start=&quot;2811&quot;&gt;&lt;b&gt;Crop and Lock&lt;/b&gt;: 앱 창의 특정 영역만 따서 띄우기&lt;/li&gt;
&lt;li data-end=&quot;2901&quot; data-start=&quot;2853&quot;&gt;&lt;b&gt;Registry Preview&lt;/b&gt;: .reg 파일을 미리 보고 안전하게 병합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;2906&quot; data-start=&quot;2903&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2940&quot; data-start=&quot;2908&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ 정리: PowerToys는 이런 분께 추천합니다&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;대상이유
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;3169&quot; data-start=&quot;2942&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;3169&quot; data-start=&quot;2970&quot;&gt;
&lt;tr data-end=&quot;3009&quot; data-start=&quot;2970&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2982&quot; data-start=&quot;2970&quot;&gt; &amp;zwj;  개발자&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;3009&quot; data-start=&quot;2982&quot;&gt;창 관리, 단축키 커스터마이징, 빠른 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3065&quot; data-start=&quot;3010&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3020&quot; data-start=&quot;3010&quot;&gt;  디자이너&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;3065&quot; data-start=&quot;3020&quot;&gt;Color Picker, Image Resizer, Quick Accent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3126&quot; data-start=&quot;3066&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3075&quot; data-start=&quot;3066&quot;&gt;✍️ 블로거&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;3126&quot; data-start=&quot;3075&quot;&gt;Text Extractor, Paste as Plain Text, FancyZones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;3169&quot; data-start=&quot;3127&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;3139&quot; data-start=&quot;3127&quot;&gt;  일반 사용자&lt;/td&gt;
&lt;td data-col-size=&quot;md&quot; data-end=&quot;3169&quot; data-start=&quot;3139&quot;&gt;파일 점유 확인, 마우스 강조, hosts 편집&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>Server/Windows</category>
      <category>PowerToys</category>
      <category>utility</category>
      <category>Windows</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/128</guid>
      <comments>https://roaroa.tistory.com/128#entry128comment</comments>
      <pubDate>Wed, 5 Nov 2025 13:56:20 +0900</pubDate>
    </item>
    <item>
      <title>자바 JVM 모니터링</title>
      <link>https://roaroa.tistory.com/127</link>
      <description>&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5&quot; data-message-id=&quot;a32e84c8-795d-486f-a564-62b878f2d3e4&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;111&quot; data-origin-height=&quot;29&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/orcxZ/dJMcajUOs2B/OzKfnQEaF1cdrQLZjGsdxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/orcxZ/dJMcajUOs2B/OzKfnQEaF1cdrQLZjGsdxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/orcxZ/dJMcajUOs2B/OzKfnQEaF1cdrQLZjGsdxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2ForcxZ%2FdJMcajUOs2B%2FOzKfnQEaF1cdrQLZjGsdxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;111&quot; height=&quot;29&quot; data-origin-width=&quot;111&quot; data-origin-height=&quot;29&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-5&quot; data-message-id=&quot;20be7392-31b5-483e-a647-d7a5fff087be&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;h2 data-end=&quot;190&quot; data-start=&quot;170&quot; data-ke-size=&quot;size26&quot;&gt;  1. VisualVM 소개&lt;/h2&gt;
&lt;p data-end=&quot;290&quot; data-start=&quot;192&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;VisualVM&lt;/b&gt;은 JDK에 포함된 jvisualvm 또는 독립 실행형 형태로 제공되는 &lt;b&gt;JVM 모니터링 및 분석 도구&lt;/b&gt;입니다.&lt;br /&gt;다음과 같은 기능을 제공합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;304&quot; data-start=&quot;292&quot; data-ke-size=&quot;size23&quot;&gt;  주요 기능&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;기능설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;660&quot; data-start=&quot;305&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;660&quot; data-start=&quot;333&quot;&gt;
&lt;tr data-end=&quot;420&quot; data-start=&quot;333&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;354&quot; data-start=&quot;333&quot;&gt;&lt;b&gt;CPU / 메모리 모니터링&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;420&quot; data-start=&quot;354&quot; data-col-size=&quot;md&quot;&gt;힙(Heap) / PermGen(Metaspace) 사용량, GC(Garbage Collection) 횟수 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;478&quot; data-start=&quot;421&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;437&quot; data-start=&quot;421&quot;&gt;&lt;b&gt;스레드 상태 추적&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;478&quot; data-start=&quot;437&quot; data-col-size=&quot;md&quot;&gt;실행 중 스레드, 데드락, Runnable/Waiting 상태 추적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;531&quot; data-start=&quot;479&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;502&quot; data-start=&quot;479&quot;&gt;&lt;b&gt;프로파일링(Profiling)&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;531&quot; data-start=&quot;502&quot; data-col-size=&quot;md&quot;&gt;CPU, 메서드 호출 빈도, 메모리 할당 추적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;581&quot; data-start=&quot;532&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;551&quot; data-start=&quot;532&quot;&gt;&lt;b&gt;Heap Dump 분석&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;581&quot; data-start=&quot;551&quot; data-col-size=&quot;md&quot;&gt;힙 덤프를 시각적으로 분석하여 메모리 누수 탐지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;660&quot; data-start=&quot;582&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;615&quot; data-start=&quot;582&quot;&gt;&lt;b&gt;원격 모니터링(Remote Monitoring)&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;660&quot; data-start=&quot;615&quot; data-col-size=&quot;md&quot;&gt;원격 서버의 톰캣 프로세스 모니터링 가능 (JMX 또는 jstatd 사용)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;665&quot; data-start=&quot;662&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;688&quot; data-start=&quot;667&quot; data-ke-size=&quot;size26&quot;&gt;⚙️ 2. Tomcat 연동 방법&lt;/h2&gt;
&lt;h3 data-end=&quot;707&quot; data-start=&quot;690&quot; data-ke-size=&quot;size23&quot;&gt;(1) &lt;b&gt;로컬 톰캣&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;846&quot; data-start=&quot;708&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;757&quot; data-start=&quot;708&quot;&gt;같은 PC에서 톰캣 실행 시 자동으로 VisualVM이 JVM 프로세스를 탐지합니다.&lt;/li&gt;
&lt;li data-end=&quot;846&quot; data-start=&quot;758&quot;&gt;그냥 jvisualvm 실행 &amp;rarr; &amp;ldquo;Local&amp;rdquo; 탭에서 org.apache.catalina.startup.Bootstrap 프로세스 선택하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;865&quot; data-start=&quot;848&quot; data-ke-size=&quot;size23&quot;&gt;(2) &lt;b&gt;원격 톰캣&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1270&quot; data-start=&quot;866&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1119&quot; data-start=&quot;866&quot;&gt;&lt;b&gt;톰캣 실행 옵션에 JMX 포트 설정&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1119&quot; data-start=&quot;896&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;CATALINA_OPTS=&lt;/span&gt;&lt;span&gt;&lt;span&gt;&quot;&lt;span&gt;$CATALINA_OPTS&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt; -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false&quot; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1233&quot; data-start=&quot;1120&quot;&gt;&lt;b&gt;톰캣 재시작 후 VisualVM에서 원격 호스트 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1233&quot; data-start=&quot;1160&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1190&quot; data-start=&quot;1160&quot;&gt;VisualVM &amp;rarr; Add Remote Host&lt;/li&gt;
&lt;li data-end=&quot;1233&quot; data-start=&quot;1194&quot;&gt;&amp;ldquo;JMX Connection&amp;rdquo;으로 hostname:9090 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1270&quot; data-start=&quot;1234&quot;&gt;원격 연결 시 &lt;b&gt;방화벽 9090 포트 허용&lt;/b&gt; 필요합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1275&quot; data-start=&quot;1272&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1294&quot; data-start=&quot;1277&quot; data-ke-size=&quot;size26&quot;&gt;⚠️ 3. 운영 시 주의점&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;구분주의사항설명
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1809&quot; data-start=&quot;1296&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1809&quot; data-start=&quot;1344&quot;&gt;
&lt;tr data-end=&quot;1436&quot; data-start=&quot;1344&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1356&quot; data-start=&quot;1344&quot;&gt;&lt;b&gt;성능 부하&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1395&quot; data-start=&quot;1356&quot; data-col-size=&quot;md&quot;&gt;⚠️ 실시간 프로파일링(Profiling) 시 CPU 점유율 상승&lt;/td&gt;
&lt;td data-end=&quot;1436&quot; data-start=&quot;1395&quot; data-col-size=&quot;md&quot;&gt;운영 서버에서는 &amp;ldquo;모니터링&amp;rdquo;만, 프로파일링은 테스트 환경에서만 수행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1538&quot; data-start=&quot;1437&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1446&quot; data-start=&quot;1437&quot;&gt;&lt;b&gt;보안&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1474&quot; data-start=&quot;1446&quot; data-col-size=&quot;md&quot;&gt;⚠️ JMX 인증 미설정 시 누구나 접근 가능&lt;/td&gt;
&lt;td data-end=&quot;1538&quot; data-start=&quot;1474&quot; data-col-size=&quot;md&quot;&gt;운영 환경에서는 jmxremote.access / jmxremote.password 파일로 인증 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1641&quot; data-start=&quot;1539&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1556&quot; data-start=&quot;1539&quot;&gt;&lt;b&gt;메모리 사용량 증가&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1603&quot; data-start=&quot;1556&quot; data-col-size=&quot;md&quot;&gt;VisualVM 연결 시 JVM의 Metaspace와 Heap 사용량 소폭 증가&lt;/td&gt;
&lt;td data-end=&quot;1641&quot; data-start=&quot;1603&quot; data-col-size=&quot;md&quot;&gt;일시적인 영향이므로 큰 문제는 없으나, 여유 메모리 확보 권장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1704&quot; data-start=&quot;1642&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1655&quot; data-start=&quot;1642&quot;&gt;&lt;b&gt;방화벽 설정&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1676&quot; data-start=&quot;1655&quot; data-col-size=&quot;md&quot;&gt;⚠️ JMX 포트 외부 노출 금지&lt;/td&gt;
&lt;td data-end=&quot;1704&quot; data-start=&quot;1676&quot; data-col-size=&quot;md&quot;&gt;내부망에서만 접근하거나 SSH 터널링을 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1809&quot; data-start=&quot;1705&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1724&quot; data-start=&quot;1705&quot;&gt;&lt;b&gt;Heap Dump 크기&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1763&quot; data-start=&quot;1724&quot; data-col-size=&quot;md&quot;&gt;대형 서비스는 Heap Dump 시 수백 MB~수 GB 발생 가능&lt;/td&gt;
&lt;td data-end=&quot;1809&quot; data-start=&quot;1763&quot; data-col-size=&quot;md&quot;&gt;운영 중에는 Heap Dump 남발 금지 &amp;mdash; 스냅샷은 트래픽 저하 유발 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1814&quot; data-start=&quot;1811&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1833&quot; data-start=&quot;1816&quot; data-ke-size=&quot;size26&quot;&gt;  4. 권장 운영 방식&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;목적방법
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2050&quot; data-start=&quot;1835&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2050&quot; data-start=&quot;1863&quot;&gt;
&lt;tr data-end=&quot;1921&quot; data-start=&quot;1863&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1879&quot; data-start=&quot;1863&quot;&gt;&lt;b&gt;개발&amp;middot;테스트 환경&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1921&quot; data-start=&quot;1879&quot; data-col-size=&quot;md&quot;&gt;VisualVM을 이용해 GC 튜닝, 스레드 분석, 메모리 누수 점검&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1964&quot; data-start=&quot;1922&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1934&quot; data-start=&quot;1922&quot;&gt;&lt;b&gt;운영 환경&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;1964&quot; data-start=&quot;1934&quot; data-col-size=&quot;md&quot;&gt;기본 JMX 연결만 유지하고, 필요할 때만 접속&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2050&quot; data-start=&quot;1965&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;1979&quot; data-start=&quot;1965&quot;&gt;&lt;b&gt;장기 모니터링&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;2050&quot; data-start=&quot;1979&quot; data-col-size=&quot;md&quot;&gt;VisualVM 대신 Prometheus + Grafana 또는 JMX Exporter를 통해 안정적 시각화 추천&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;2055&quot; data-start=&quot;2052&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2064&quot; data-start=&quot;2057&quot; data-ke-size=&quot;size26&quot;&gt;  팁&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2297&quot; data-start=&quot;2065&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2122&quot; data-start=&quot;2065&quot;&gt;&lt;b&gt;플러그인 설치&lt;/b&gt;로 기능 확장 가능 (Visual GC, Thread Inspector 등)&lt;/li&gt;
&lt;li data-end=&quot;2184&quot; data-start=&quot;2123&quot;&gt;&lt;b&gt;JDK 버전별 호환성 주의&lt;/b&gt; &amp;mdash; JDK 17 이상에서는 최신 VisualVM (2.x 이상) 사용&lt;/li&gt;
&lt;li data-end=&quot;2297&quot; data-start=&quot;2185&quot;&gt;&lt;b&gt;SSH 터널링&lt;/b&gt;을 이용하면 JMX 포트를 외부로 열지 않고도 원격 모니터링 가능:&lt;/li&gt;
&lt;li data-end=&quot;2297&quot; data-start=&quot;2238&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;ssh -L 9090:localhost:9090 user@your-server &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-end=&quot;2189&quot; data-start=&quot;2167&quot; data-ke-size=&quot;size26&quot;&gt;  5. VisualVM 실무 팁&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2374&quot; data-start=&quot;2191&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2282&quot; data-start=&quot;2191&quot;&gt;&lt;b&gt;Visual GC 플러그인 설치&lt;/b&gt; &amp;rarr; GC 동작 시각화&lt;br /&gt;&amp;rarr; Tools &amp;gt; Plugins &amp;gt; Available Plugins &amp;gt; Visual GC&lt;/li&gt;
&lt;li data-end=&quot;2315&quot; data-start=&quot;2283&quot;&gt;&lt;b&gt;Heap Dump&lt;/b&gt;는 꼭 트래픽 낮은 시간에 수행&lt;/li&gt;
&lt;li data-end=&quot;2374&quot; data-start=&quot;2316&quot;&gt;&lt;b&gt;자동 모니터링&lt;/b&gt;은 VisualVM 대신 Prometheus + JMX Exporter 연동 추천&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctdUlL/dJMcafrlhRA/jfNPXceirnmzzkL60EnaOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctdUlL/dJMcafrlhRA/jfNPXceirnmzzkL60EnaOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctdUlL/dJMcafrlhRA/jfNPXceirnmzzkL60EnaOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctdUlL%2FdJMcafrlhRA%2FjfNPXceirnmzzkL60EnaOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1018&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;564&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l3JMB/dJMcake7gsh/d7bcndjznAlbkb3KhdWmY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l3JMB/dJMcake7gsh/d7bcndjznAlbkb3KhdWmY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l3JMB/dJMcake7gsh/d7bcndjznAlbkb3KhdWmY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl3JMB%2FdJMcake7gsh%2Fd7bcndjznAlbkb3KhdWmY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;889&quot; height=&quot;564&quot; data-origin-width=&quot;889&quot; data-origin-height=&quot;564&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Programming/JAVA</category>
      <category>Gc</category>
      <category>Heap</category>
      <category>Java</category>
      <category>JVM</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/127</guid>
      <comments>https://roaroa.tistory.com/127#entry127comment</comments>
      <pubDate>Thu, 30 Oct 2025 09:47:18 +0900</pubDate>
    </item>
    <item>
      <title>casaos docker Jellyfin pcloud  Crypto Folder 연결</title>
      <link>https://roaroa.tistory.com/126</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ubuntu에 casaos의 docker jellyfin의 영상 폴더를 pcloud Crypto Folder에 연결하려고 시도해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker jellyfin 빌드시에 pcloud폴더가 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;permission denied에러로 구동불가&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1760491504415&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ubuntu server

casaos 설치

pcloudcc 설치
    pcloud마운트하기
    pcloudcc -u user@user.com -p -s -c -m /home/user/pcloud -d

casaos 앱스토어 Jellyfin 설치

version: '3.8'
services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    environment:
      - PUID=1000 # Replace with your user ID
      - PGID=1000 # Replace with your group ID
      - TZ=Europe/London # Replace with your timezone
    volumes:
      - /path/to/jellyfin/config:/config # Host path for Jellyfin configuration
      - /path/to/jellyfin/cache:/cache # Host path for Jellyfin cache
      - /home/user/pcloud:/media # Host path for your media files
    ports:
      - 8096:8096 # HTTP access
      - 8920:8920 # HTTPS access (optional)
      - 7359:7359/udp # For server discovery
    restart: unless-stopped&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 - /home/user/pcloud:/media 를 마운트할때 permission denied 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPT에게 물어보니 아래 답변&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;242&quot; data-start=&quot;224&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FUSE 마운트 권한 문제&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;407&quot; data-start=&quot;246&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;297&quot; data-start=&quot;246&quot;&gt;pcloudcc는 FUSE(Filesystem in Userspace)로 동작합니다.&lt;/li&gt;
&lt;li data-end=&quot;407&quot; data-start=&quot;301&quot;&gt;기본적으로 FUSE 마운트는 &lt;b&gt;마운트한 사용자만 접근 가능&lt;/b&gt;하고, 다른 사용자/프로세스(특히 root, docker)가 접근하면 Permission denied가 나올 수 있어요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/home/user/pcloud의 권한 변경을 해보았으나 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;permission denied&lt;span&gt;&amp;nbsp;해결안됨&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/home/user 폴더자체를 연결함. 그 후에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;permission denied&lt;span&gt; 없이 정상 구동&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1760491667285&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;유저 home폴더를 연결 후 permission denied없이 연결됨

/home/user:/media

그 후 jellyfin에서 /home/user/pcloud 폴더의 영상폴더로 설정&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Server/Linux</category>
      <category>casaos</category>
      <category>Docker</category>
      <category>pcloud</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/126</guid>
      <comments>https://roaroa.tistory.com/126#entry126comment</comments>
      <pubDate>Wed, 15 Oct 2025 10:31:06 +0900</pubDate>
    </item>
    <item>
      <title>라즈베리파이 B+ CCTV 녹화 (RTSP)</title>
      <link>https://roaroa.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;집에 TP-LINK TC60 홈캠이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;택배 및 출입을 보기위해 현관 앞에 설치하였는데 문제는 SD카드가 CCTV채로 노출되어 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TP-LINK링크 CLOUD를 이용하자니 비용이 들어서 나의 장비로 따로 녹화하기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 서버에 MOTION-EYE를 DOCKER에 올린 듯 RTSP로 연결 후 녹화를 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 집의 서버를 24시간 켜두기에는 전기료가 부담스러웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 찾은 방법은 현재 집에 24시간 돌아가는 라즈베리파이 B+가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라즈베리파이는 caddy proxy 서버로 잘 사용중이다. (ngnix proxy manager은 라즈베리파이에 구동불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전기료도 적게먹고 최적의 기기로 판단해서 해당기기로 녹화하기를 구상했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude.ai를 사용해서 질의 후 최종 VNC로 녹화 후 CLOUD 서버에 업로드 스크립트를 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. CCTV -&amp;gt; RTSP -&amp;gt; 서버 -&amp;gt; MOTION-EYE (전기료 부담)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. CCTV -&amp;gt; RTSP -&amp;gt; 라즈베리파이 B+ -&amp;gt; ffmpeg (녹화시 CPU가 90%까지 올라가고 발열까지 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. CCTV -&amp;gt; RTSP -&amp;gt; 라즈베리파이 B+ -&amp;gt; VNC (CPU사용이 6~10% 안전적이 었다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번 테스트&lt;/p&gt;
&lt;pre id=&quot;code_1759305842825&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# VLC 설치
sudo apt install vlc

# VLC로 녹화 테스트
cvlc rtsp://아이디:암호@URL:554/stream2 \
  --sout '#std{access=file,mux=mp4,dst=test_vlc.mp4}' \
  --run-time=10 \
  vlc://quit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번으로 스크립트작성 자동 녹화 및 백업, 파일 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;CCTV -&amp;gt; RTSP -&amp;gt; 라즈베리파이 B+ -&amp;gt; VNC -&amp;gt; RCLONE -&amp;gt; PCLOUD 업로드 (또는 GOOGLE DRIVE, CLOUD)&lt;/p&gt;
&lt;pre id=&quot;code_1759305784008&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash

# ===========================================
# VLC 기반 CCTV 녹화 및 pcloud 백업 스크립트
# Raspberry Pi Model B Plus 최적화 (검증완료)
# CPU 사용률: 6-10%
# ===========================================

RTSP_URL=&quot;rtsp://아이디:암호@URL:554/stream2&quot;
STORAGE_PATH=&quot;/home/pi/cctv&quot;
PCLOUD_REMOTE=&quot;pcloud:Backups/cctv&quot;
MAX_STORAGE_GB=20
SEGMENT_DURATION=600        # 10분 세그먼트
#BACKUP_INTERVAL=1800       # 30분마다 백업
BACKUP_INTERVAL=3600        # 60분마다 백업
KEEP_LOCAL_HOURS=12         # 로컬 파일 12시간 보관
MAX_LOCAL_FILES=200         # 최대 200개 파일
PCLOUD_KEEP_DAYS=7          # pcloud 7일 보관

LOG_FILE=&quot;/home/pi/script/cctv/log/cctv_backup.log&quot;
LOCK_FILE=&quot;/h/cctv_upload.lock&quot;

log() {
    echo &quot;[$(date '+%Y-%m-%d %H:%M:%S')] $1&quot; | tee -a &quot;$LOG_FILE&quot;
}

mkdir -p &quot;$STORAGE_PATH&quot;
mkdir -p &quot;$STORAGE_PATH/uploading&quot;
mkdir -p &quot;$STORAGE_PATH/uploaded&quot;
mkdir -p &quot;$STORAGE_PATH/temp&quot;

# 디스크 공간 체크 (적극적 정리)
check_disk_space() {
    local USED_MB=$(du -sm &quot;$STORAGE_PATH&quot; 2&amp;gt;/dev/null | awk '{print $1}')
    local USED_GB=$((USED_MB / 1024))
    
    if [ -z &quot;$USED_GB&quot; ]; then
        USED_GB=0
    fi
    
    # 15GB 넘으면 긴급 정리
    if [ &quot;$USED_GB&quot; -gt 15 ]; then
        log &quot;⚠️  디스크 공간 위험 ($USED_GB GB / $MAX_STORAGE_GB GB)&quot;
        log &quot;   긴급 정리 시작...&quot;
        
        local count=0
        while IFS= read -r file; do
            if [ -f &quot;$file&quot; ]; then
                rm -f &quot;$file&quot;
                log &quot;   긴급 삭제: $(basename &quot;$file&quot;)&quot;
                count=$((count + 1))
                [ $count -ge 10 ] &amp;amp;&amp;amp; break
            fi
        done &amp;lt; &amp;lt;(find &quot;$STORAGE_PATH&quot; -name &quot;*.mp4&quot; -type f -printf '%T+ %p\n' 2&amp;gt;/dev/null | sort | cut -d' ' -f2-)
    fi
    
    # 파일 개수로도 체크
    local FILE_COUNT=$(find &quot;$STORAGE_PATH&quot; -name &quot;*.mp4&quot; -type f 2&amp;gt;/dev/null | wc -l)
    if [ &quot;$FILE_COUNT&quot; -gt &quot;$MAX_LOCAL_FILES&quot; ]; then
        log &quot;⚠️  파일 개수 초과 ($FILE_COUNT / $MAX_LOCAL_FILES)&quot;
        local OVER_COUNT=$((FILE_COUNT - MAX_LOCAL_FILES + 10))
        
        local count=0
        while IFS= read -r file; do
            if [ -f &quot;$file&quot; ]; then
                rm -f &quot;$file&quot;
                log &quot;   개수 초과 삭제: $(basename &quot;$file&quot;)&quot;
                count=$((count + 1))
                [ $count -ge $OVER_COUNT ] &amp;amp;&amp;amp; break
            fi
        done &amp;lt; &amp;lt;(find &quot;$STORAGE_PATH&quot; -name &quot;*.mp4&quot; -type f -printf '%T+ %p\n' 2&amp;gt;/dev/null | sort | cut -d' ' -f2-)
    fi
}

# 네트워크 연결 확인
check_network() {
    local host=$(echo &quot;$RTSP_URL&quot; | sed -n 's|.*@\([^:]*\):.*|\1|p')
    if [ -z &quot;$host&quot; ]; then
        host=$(echo &quot;$RTSP_URL&quot; | sed -n 's|rtsp://\([^:/]*\).*|\1|p')
    fi
    
    if ping -c 1 -W 3 &quot;$host&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
        return 0
    else
        return 1
    fi
}

# VLC 녹화 (안정화)
start_recording() {
    log &quot;  VLC 녹화 시작 (CPU 최적화 모드)&quot;
    log &quot;   RTSP: $RTSP_URL&quot;
    log &quot;   세그먼트: ${SEGMENT_DURATION}초&quot;
    
    local consecutive_failures=0
    local MAX_FAILURES=5
    
    while true; do
        # 네트워크 체크
        if ! check_network; then
            log &quot;❌ 네트워크 연결 없음, 60초 후 재시도...&quot;
            consecutive_failures=$((consecutive_failures + 1))
            
            if [ $consecutive_failures -ge $MAX_FAILURES ]; then
                log &quot;⚠️  연속 실패 ${consecutive_failures}회, 5분 대기...&quot;
                sleep 300
                consecutive_failures=0
            else
                sleep 60
            fi
            continue
        fi
        
        local TIMESTAMP=$(date +%Y%m%d_%H%M%S)
        local TEMP_FILE=&quot;$STORAGE_PATH/temp/cctv_${TIMESTAMP}.mp4&quot;
        local OUTPUT_FILE=&quot;$STORAGE_PATH/cctv_${TIMESTAMP}.mp4&quot;
        
        log &quot;  녹화 시작: $(basename &quot;$OUTPUT_FILE&quot;)&quot;
        
        # VLC 실행 (에러 출력을 파일로 저장)
        local VLC_LOG=&quot;/tmp/vlc_${TIMESTAMP}.log&quot;
        
        timeout $((SEGMENT_DURATION + 30)) cvlc \
            &quot;rtsp://아이디:암호@URL:554/stream2&quot; \
            --quiet \
            --no-audio \
            --no-sout-audio \
            --rtsp-tcp \
            --network-caching=2000 \
            --sout-mux-caching=2000 \
            --sout &quot;#std{access=file,mux=mp4,dst=$TEMP_FILE}&quot; \
            --run-time=&quot;$SEGMENT_DURATION&quot; \
            vlc://quit \
            &amp;gt; &quot;$VLC_LOG&quot; 2&amp;gt;&amp;amp;1
        
        local VLC_EXIT=$?
        
        # 에러 로그에서 심각한 문제만 기록
        if [ -f &quot;$VLC_LOG&quot; ]; then
            grep -E &quot;error:|failed|cannot&quot; &quot;$VLC_LOG&quot; | grep -v &quot;PulseAudio\|interface\|globalhotkeys\|dummy&quot; &amp;gt;&amp;gt; &quot;$LOG_FILE&quot;
            rm -f &quot;$VLC_LOG&quot;
        fi
        
        # 녹화 결과 확인
        if [ -f &quot;$TEMP_FILE&quot; ] &amp;amp;&amp;amp; [ -s &quot;$TEMP_FILE&quot; ]; then
            local FILE_SIZE=$(du -h &quot;$TEMP_FILE&quot; | cut -f1)
            
            # 최소 크기 확인 (1MB 이상)
            local FILE_SIZE_BYTES=$(stat -c%s &quot;$TEMP_FILE&quot; 2&amp;gt;/dev/null || echo 0)
            if [ &quot;$FILE_SIZE_BYTES&quot; -lt 1048576 ]; then
                log &quot;⚠️  파일 크기 너무 작음: $FILE_SIZE_BYTES bytes&quot;
                rm -f &quot;$TEMP_FILE&quot;
                consecutive_failures=$((consecutive_failures + 1))
                sleep 10
                continue
            fi
            
            # 정상 파일 이동
            mv &quot;$TEMP_FILE&quot; &quot;$STORAGE_PATH/uploading/&quot;
            log &quot;✅ 녹화 완료: $(basename &quot;$OUTPUT_FILE&quot;) ($FILE_SIZE)&quot;
            
            consecutive_failures=0
            
            # 시스템 상태 (5회마다 출력)
            if [ $((RANDOM % 5)) -eq 0 ]; then
                if command -v vcgencmd &amp;amp;&amp;gt; /dev/null; then
                    local CPU_TEMP=$(vcgencmd measure_temp 2&amp;gt;/dev/null | grep -oP '\d+\.\d+' || echo &quot;N/A&quot;)
                    log &quot;   CPU 온도: ${CPU_TEMP}&amp;deg;C&quot;
                fi
                
                local MEM_FREE=$(free -m | awk 'NR==2{printf &quot;%.0f&quot;, $7}')
                log &quot;   여유 메모리: ${MEM_FREE}MB&quot;
            fi
            
        else
            log &quot;❌ 녹화 실패: $(basename &quot;$OUTPUT_FILE&quot;) (exit: $VLC_EXIT)&quot;
            rm -f &quot;$TEMP_FILE&quot;
            
            consecutive_failures=$((consecutive_failures + 1))
            
            # 연속 실패 시 긴 대기
            if [ $consecutive_failures -ge $MAX_FAILURES ]; then
                log &quot;⚠️  연속 실패 ${consecutive_failures}회, RTSP 연결 문제 가능성&quot;
                log &quot;   5분 후 재시도...&quot;
                sleep 300
                consecutive_failures=0
            else
                sleep 30
            fi
        fi
        
        check_disk_space
        sleep 5
    done
}

# pcloud 업로드 (중복 실행 방지 + 개선)
upload_to_pcloud() {
    log &quot;☁️  pcloud 백업 프로세스 시작&quot;
    
    while true; do
        sleep &quot;$BACKUP_INTERVAL&quot;
        
        # 업로드 중인지 확인 (lock 파일)
        if [ -f &quot;$LOCK_FILE&quot; ]; then
            local LOCK_PID=$(cat &quot;$LOCK_FILE&quot; 2&amp;gt;/dev/null)
            if ps -p &quot;$LOCK_PID&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
                log &quot;⏳ 이전 업로드 진행 중 (PID: $LOCK_PID), 대기...&quot;
                continue
            else
                log &quot;⚠️  오래된 lock 파일 제거&quot;
                rm -f &quot;$LOCK_FILE&quot;
            fi
        fi
        
        # rclone 연결 확인
        if ! rclone about &quot;$PCLOUD_REMOTE&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
            log &quot;❌ pcloud 연결 실패, 다음 사이클에 재시도&quot;
            continue
        fi
        
        # lock 생성
        echo $$ &amp;gt; &quot;$LOCK_FILE&quot;
        
        # 2분 이상 된 파일만 업로드
        local UPLOAD_COUNT=0
        local SKIP_COUNT=0
        local FAIL_COUNT=0
        
        while IFS= read -r file; do
            if [ ! -f &quot;$file&quot; ]; then
                continue
            fi
            
            local FILENAME=$(basename &quot;$file&quot;)
            local DATE_STR=$(echo &quot;$FILENAME&quot; | grep -oE '[0-9]{8}' | head -1)
            
            local REMOTE_PATH=&quot;$PCLOUD_REMOTE&quot;
            if [ -n &quot;$DATE_STR&quot; ]; then
                local YEAR=${DATE_STR:0:4}
                local MONTH=${DATE_STR:4:2}
                REMOTE_PATH=&quot;$PCLOUD_REMOTE/$YEAR/$MONTH&quot;
            fi
            
            # pcloud에 이미 존재하는지 확인
            if rclone ls &quot;$REMOTE_PATH/$FILENAME&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
                log &quot;⏭️  건너뜀: $FILENAME (이미 존재)&quot;
                mv &quot;$file&quot; &quot;$STORAGE_PATH/uploaded/&quot;
                SKIP_COUNT=$((SKIP_COUNT + 1))
                continue
            fi
            
            local FILE_SIZE=$(du -h &quot;$file&quot; | cut -f1)
            log &quot;⬆️  업로드: $FILENAME ($FILE_SIZE)&quot;
            
            if rclone copy &quot;$file&quot; &quot;$REMOTE_PATH&quot; \
                --transfers 1 \
                --checkers 1 \
                --buffer-size 8M \
                --bwlimit 2M \
                --retries 3 \
                --low-level-retries 3 \
                --timeout 300s \
                --contimeout 60s \
                --stats 0 \
                -q &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1; then
                
                # 업로드 검증
                if rclone ls &quot;$REMOTE_PATH/$FILENAME&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
                    log &quot;✅ 업로드 성공: $FILENAME&quot;
                    mv &quot;$file&quot; &quot;$STORAGE_PATH/uploaded/&quot;
                    UPLOAD_COUNT=$((UPLOAD_COUNT + 1))
                else
                    log &quot;❌ 업로드 검증 실패: $FILENAME&quot;
                    FAIL_COUNT=$((FAIL_COUNT + 1))
                fi
            else
                log &quot;❌ 업로드 실패: $FILENAME (재시도 예정)&quot;
                FAIL_COUNT=$((FAIL_COUNT + 1))
            fi
            
        done &amp;lt; &amp;lt;(find &quot;$STORAGE_PATH/uploading&quot; -name &quot;*.mp4&quot; -type f -mmin +2 2&amp;gt;/dev/null)
        
        if [ $UPLOAD_COUNT -gt 0 ] || [ $SKIP_COUNT -gt 0 ] || [ $FAIL_COUNT -gt 0 ]; then
            log &quot;  업로드 결과 - 성공: ${UPLOAD_COUNT}, 건너뜀: ${SKIP_COUNT}, 실패: ${FAIL_COUNT}&quot;
        else
            log &quot;  업로드할 파일 없음&quot;
        fi
        
        # lock 해제
        rm -f &quot;$LOCK_FILE&quot;
    done
}

# 파일 정리 (로컬 + pcloud)
cleanup_old_files() {
    log &quot; ️  파일 정리 프로세스 시작&quot;
    
    while true; do
        sleep 1800  # 30분마다
        
        # 로컬 정리 - 12시간 이상
        local DELETED=$(find &quot;$STORAGE_PATH/uploaded&quot; -name &quot;*.mp4&quot; -type f -mmin +$((KEEP_LOCAL_HOURS * 60)) -delete -print 2&amp;gt;/dev/null | wc -l)
        
        if [ &quot;$DELETED&quot; -gt 0 ]; then
            log &quot; ️  로컬 정리: ${DELETED}개 파일 삭제 (${KEEP_LOCAL_HOURS}시간 이상)&quot;
        fi
        
        # uploading 폴더 - 1일 이상
        local OLD_UPLOADING=$(find &quot;$STORAGE_PATH/uploading&quot; -name &quot;*.mp4&quot; -type f -mmin +1440 -delete -print 2&amp;gt;/dev/null | wc -l)
        
        if [ &quot;$OLD_UPLOADING&quot; -gt 0 ]; then
            log &quot; ️  오래된 업로딩 파일 삭제: ${OLD_UPLOADING}개&quot;
        fi
        
        # temp 폴더 정리
        find &quot;$STORAGE_PATH/temp&quot; -name &quot;*.mp4&quot; -type f -mmin +60 -delete 2&amp;gt;/dev/null
        
        # 통계
        local USED_MB=$(du -sm &quot;$STORAGE_PATH&quot; 2&amp;gt;/dev/null | awk '{print $1}')
        local USED_GB=$((USED_MB / 1024))
        local FILE_COUNT=$(find &quot;$STORAGE_PATH&quot; -name &quot;*.mp4&quot; -type f 2&amp;gt;/dev/null | wc -l)
        log &quot;  저장 공간: ${USED_GB}GB / ${MAX_STORAGE_GB}GB, 파일: ${FILE_COUNT}개&quot;
        
        # 6시간마다 pcloud 정리
        local CLEANUP_MARKER=&quot;/tmp/pcloud_cleanup_last&quot;
        local CURRENT_TIME=$(date +%s)
        local LAST_CLEANUP=0
        
        if [ -f &quot;$CLEANUP_MARKER&quot; ]; then
            LAST_CLEANUP=$(stat -c %Y &quot;$CLEANUP_MARKER&quot; 2&amp;gt;/dev/null || echo 0)
        fi
        
        if [ $((CURRENT_TIME - LAST_CLEANUP)) -gt 21600 ]; then
            cleanup_pcloud
            touch &quot;$CLEANUP_MARKER&quot;
        fi
    done
}

# pcloud 정리
cleanup_pcloud() {
    log &quot;☁️  pcloud 정리 시작 (${PCLOUD_KEEP_DAYS}일 이상)&quot;
    
    if ! rclone listremotes 2&amp;gt;/dev/null | grep -q &quot;pcloud:&quot;; then
        log &quot;   rclone 미설정, 건너뜀&quot;
        return
    fi
    
    # 연결 확인
    if ! rclone about &quot;$PCLOUD_REMOTE&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
        log &quot;❌ pcloud 연결 실패&quot;
        return
    fi
    
    log &quot;   ${PCLOUD_KEEP_DAYS}일 이전 파일 삭제 중...&quot;
    
    # 삭제 실행
    if rclone delete &quot;$PCLOUD_REMOTE&quot; \
        --min-age &quot;${PCLOUD_KEEP_DAYS}d&quot; \
        --verbose \
        &amp;gt;&amp;gt; &quot;$LOG_FILE&quot; 2&amp;gt;&amp;amp;1; then
        
        log &quot;✅ pcloud 정리 완료&quot;
        
        # 용량 확인
        local PCLOUD_SIZE=$(rclone size &quot;$PCLOUD_REMOTE&quot; 2&amp;gt;/dev/null | grep &quot;Total size:&quot; | awk '{print $3, $4}')
        if [ -n &quot;$PCLOUD_SIZE&quot; ]; then
            log &quot;☁️  pcloud 사용량: $PCLOUD_SIZE&quot;
        fi
    else
        log &quot;⚠️  pcloud 정리 중 오류 발생&quot;
    fi
}

# 시스템 모니터링
monitor_system() {
    while true; do
        sleep 300  # 5분마다
        
        # VLC 프로세스 체크
        if ! pgrep -f &quot;cvlc&quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then
            log &quot;⚠️  VLC 프로세스 미실행&quot;
        fi
        
        # 시스템 리소스
        local CPU_TEMP=&quot;N/A&quot;
        if command -v vcgencmd &amp;amp;&amp;gt; /dev/null; then
            CPU_TEMP=$(vcgencmd measure_temp 2&amp;gt;/dev/null | grep -oP '\d+\.\d+' || echo &quot;N/A&quot;)
        fi
        
        local MEM_USAGE=$(free -m | awk 'NR==2{printf &quot;%.1f%%&quot;, $3*100/$2}')
        local DISK_USAGE=$(df -h &quot;$STORAGE_PATH&quot; | awk 'NR==2{print $5}')
        local CPU_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
        
        log &quot;  시스템 - CPU: ${CPU_TEMP}&amp;deg;C, 부하: ${CPU_LOAD}, 메모리: ${MEM_USAGE}, 디스크: ${DISK_USAGE}&quot;
    done
}

# 종료 핸들러
cleanup_and_exit() {
    log &quot;  종료 신호 수신&quot;
    rm -f &quot;$LOCK_FILE&quot;
    pkill -P $$
    pkill vlc 2&amp;gt;/dev/null
    log &quot;✅ 스크립트 종료&quot;
    exit 0
}

trap cleanup_and_exit SIGINT SIGTERM

# 메인 실행
log &quot;==========================================&quot;
log &quot;  VLC 기반 CCTV 녹화 시스템 시작 (v2.0)&quot;
log &quot;==========================================&quot;
log &quot;  RTSP URL: $RTSP_URL&quot;
log &quot;  저장 경로: $STORAGE_PATH&quot;
log &quot;☁️  pcloud 경로: $PCLOUD_REMOTE&quot;
log &quot;  최대 저장 용량: ${MAX_STORAGE_GB}GB&quot;
log &quot;⏱️  세그먼트 길이: ${SEGMENT_DURATION}초&quot;
log &quot;  백업 주기: ${BACKUP_INTERVAL}초&quot;
log &quot; ️  로컬 보관: ${KEEP_LOCAL_HOURS}시간&quot;
log &quot;☁️  pcloud 보관: ${PCLOUD_KEEP_DAYS}일&quot;
log &quot;  최대 파일: ${MAX_LOCAL_FILES}개&quot;
log &quot;==========================================&quot;

# VLC 확인
if ! command -v cvlc &amp;amp;&amp;gt; /dev/null; then
    log &quot;❌ VLC 미설치: sudo apt install vlc&quot;
    exit 1
fi

# rclone 확인
UPLOAD_DISABLED=0
if ! rclone listremotes 2&amp;gt;/dev/null | grep -q &quot;pcloud:&quot;; then
    log &quot;⚠️  rclone pcloud 미설정 (업로드 비활성화)&quot;
    UPLOAD_DISABLED=1
fi

# 초기 네트워크 확인
if ! check_network; then
    log &quot;⚠️  RTSP 호스트에 연결할 수 없습니다&quot;
    log &quot;   계속 시도하지만 녹화가 실패할 수 있습니다&quot;
fi

# 백그라운드 프로세스 시작
start_recording &amp;amp;
RECORDING_PID=$!

if [ $UPLOAD_DISABLED -eq 0 ]; then
    upload_to_pcloud &amp;amp;
    UPLOAD_PID=$!
fi

cleanup_old_files &amp;amp;
CLEANUP_PID=$!

monitor_system &amp;amp;
MONITOR_PID=$!

log &quot;✅ 모든 프로세스 시작 완료&quot;
log &quot;   녹화 PID: $RECORDING_PID&quot;
[ $UPLOAD_DISABLED -eq 0 ] &amp;amp;&amp;amp; log &quot;   업로드 PID: $UPLOAD_PID&quot;
log &quot;   정리 PID: $CLEANUP_PID&quot;
log &quot;   모니터링 PID: $MONITOR_PID&quot;
log &quot;==========================================&quot;

# 메인 프로세스 대기
wait&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ROG, CPU, RAM, NETWORK 사용률 (BTOP++, LOG)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chgkq5/btsQ0inJA7R/egxWuY8DkhK8ukKOOOsUpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chgkq5/btsQ0inJA7R/egxWuY8DkhK8ukKOOOsUpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chgkq5/btsQ0inJA7R/egxWuY8DkhK8ukKOOOsUpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fchgkq5%2FbtsQ0inJA7R%2FegxWuY8DkhK8ukKOOOsUpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1365&quot; height=&quot;726&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PCLOUD에 정상적으로 업로드도 확인 되었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1041&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NH4Ed/btsQYsyUt0l/L0RwS2NZ8tzC40Gs42DApk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NH4Ed/btsQYsyUt0l/L0RwS2NZ8tzC40Gs42DApk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NH4Ed/btsQYsyUt0l/L0RwS2NZ8tzC40Gs42DApk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNH4Ed%2FbtsQYsyUt0l%2FL0RwS2NZ8tzC40Gs42DApk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1041&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1041&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기타 테스트&lt;/p&gt;
&lt;pre id=&quot;code_1759324981183&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. 실행
./cctv_backup.sh

# 2. 로그 확인 (다른 터미널)
tail -f /var/log/cctv_backup.log

# 3. 확인할 것
# ✓ 녹화 시작 메시지
# ✓ 10분 후 파일 생성 확인
# ✓ 30분 후 업로드 시작 확인
# ✓ pcloud에 파일 업로드 확인

# 4. 파일 확인
ls -lh /home/pi/cctv/uploading/
ls -lh /home/pi/cctv/uploaded/

# 5. pcloud 확인
rclone ls pcloud:Backups/cctv&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Server/Raspbian</category>
      <category>cctv</category>
      <category>RPi</category>
      <category>RTSP</category>
      <category>VNC</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/125</guid>
      <comments>https://roaroa.tistory.com/125#entry125comment</comments>
      <pubDate>Wed, 1 Oct 2025 17:04:32 +0900</pubDate>
    </item>
    <item>
      <title>DBever에서 세미콜론으로 쿼리 구분 실행</title>
      <link>https://roaroa.tistory.com/124</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;DBever에서&amp;nbsp;세미콜론으로&amp;nbsp;쿼리&amp;nbsp;구분&amp;nbsp;실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;DBever에서 SQL이 엔터로 띄어져 있으면 쿼리 실행시 에러가난다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;세미콜론(;)으로 쿼리 구분자로 인식 후 쿼리 실행시 에러 없이 구분해서 잘 실행된다.&lt;/p&gt;
&lt;pre id=&quot;code_1758871985305&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;SQL 에러 구문
-------------------------------------------------------
SELECT *
FROM TEST
WHERE 
                &amp;lt;--여기가 엔터로 띄어져 있을때
id = '123'
-------------------------------------------------------

SQL 세미콜론(;)으로 SQL 구분 되어 실행
-------------------------------------------------------
SELECT *
FROM TEST
WHERE 
				&amp;lt;--엔터로 띄어져 있어도 ;으로 마지막 SQL 인식
id = '123';
-------------------------------------------------------&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DBever 설정&lt;/p&gt;
&lt;pre id=&quot;code_1758871880910&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DBever
윈도우(W) &amp;gt; 환경설정(P) &amp;gt; 편집기 &amp;gt; SQL 편집기 &amp;gt; SQL 실행

Delimiters
Statements delimiter : ;  &amp;lt;-- 세미콜론으로 입력
Blank line is statement delimiter : Never&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFjXrQ/btsQStwcXuV/nWeMk1qxrVSKPuGddzkPCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFjXrQ/btsQStwcXuV/nWeMk1qxrVSKPuGddzkPCk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFjXrQ/btsQStwcXuV/nWeMk1qxrVSKPuGddzkPCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFjXrQ%2FbtsQStwcXuV%2FnWeMk1qxrVSKPuGddzkPCk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;604&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TOOL/DBEVER</category>
      <category>;</category>
      <category>DBEVER</category>
      <category>sql</category>
      <category>세미콜론</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/124</guid>
      <comments>https://roaroa.tistory.com/124#entry124comment</comments>
      <pubDate>Fri, 26 Sep 2025 16:33:58 +0900</pubDate>
    </item>
    <item>
      <title>VSCODE 윈도우 화면 깨짐</title>
      <link>https://roaroa.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;VSCODE를 켜면 윈도우 탐색기, 이클립스, DBever 등등 윈도우 프로그램의 그래픽 깨짐 현상이 있어서 재대로 사용을 하지 못할 정도 였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 PC는 워크스테이션이고 윈도우11 그래픽카드는 NVIDIA Quadro K5000 그래픽카드를 사용중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스만 보면 이렇게 깨지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LoeJO/btsQJ1Hx3Bm/qlwVuoFEya6x5SuzpuzTH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LoeJO/btsQJ1Hx3Bm/qlwVuoFEya6x5SuzpuzTH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LoeJO/btsQJ1Hx3Bm/qlwVuoFEya6x5SuzpuzTH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLoeJO%2FbtsQJ1Hx3Bm%2FqlwVuoFEya6x5SuzpuzTH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;588&quot; data-origin-width=&quot;690&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NVIDIA 제어판 &amp;gt; 3D 설정 &amp;gt; 3D 설정 관리 &amp;gt; 이미지 선명화 (기본 옵션)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 설정 후 재부팅하니 그래픽 깨지는 현상이 없어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 이미지 선명화가 켜기 상태이면 끄기를 선택하고 재부팅해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1758593551755&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;이미지선명화 (끄기) 일경우 &amp;gt; 이미지선명화 (켜기) &amp;gt; 윈도우 재부팅

이미지선명화 (켜기) 일경우 &amp;gt; 이미지선명화 (끄기) &amp;gt; 윈도우 재부팅&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Tr5kr/btsQK78be9q/5UpQrUrPuDrF66Hy4jFKl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Tr5kr/btsQK78be9q/5UpQrUrPuDrF66Hy4jFKl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Tr5kr/btsQK78be9q/5UpQrUrPuDrF66Hy4jFKl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTr5kr%2FbtsQK78be9q%2F5UpQrUrPuDrF66Hy4jFKl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;288&quot; height=&quot;353&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QaAbx/btsQITiWtTO/upfytlDCGdI9KCaFo4Koy0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QaAbx/btsQITiWtTO/upfytlDCGdI9KCaFo4Koy0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QaAbx/btsQITiWtTO/upfytlDCGdI9KCaFo4Koy0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQaAbx%2FbtsQITiWtTO%2FupfytlDCGdI9KCaFo4Koy0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;953&quot; height=&quot;705&quot; data-origin-width=&quot;953&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TOOL/VSCODE</category>
      <category>vscode</category>
      <category>그래픽깨짐</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/123</guid>
      <comments>https://roaroa.tistory.com/123#entry123comment</comments>
      <pubDate>Tue, 23 Sep 2025 11:13:12 +0900</pubDate>
    </item>
    <item>
      <title>vscode로 spring 또는 Apache Struts 개발하기</title>
      <link>https://roaroa.tistory.com/122</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현재 유지보수중인 사이트중에 오래전에 이클립스로 개발되어 있는 spring 프로젝트가 하나 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eclipse Luna(4.4.2), Java-jdk 1.6, Tomcat 7.0, Apache Struts 1.1 개발되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스의 버벅임 때문에 소스를 수정하기 힘이 들때가 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring boot 프로젝트이면 vscode로 실행 및 debug를 할 수 있으나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode의 경우 일반 Spring 또는 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Apache&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Struts 경우 실행할때마다 Build 후 War로 구동시키는 방법 밖에 없는것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그래서 고민 후 이클립스로 프로젝트 구동 후 소스코드 및 로그만 vscode에서 확인하는 걸로 해보니 할결 편해졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜된 소스라 Jsp에 거의 비지니스 로직이 있고 Debug는 거의할 필요없는 수정 요청 정도여서 편집기로만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode로 사용하면 되기에 해당 설정이 나에게는 적당한 방법이 었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;구성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eclipse에서 tomcat 프로젝트를 구동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eclipse 메뉴 &amp;gt; Run &amp;gt; Debug Configurations &amp;gt; 해당 Tomcat 설정 &amp;gt; Common &amp;gt; Standard Input and Ouput &amp;gt; File&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로그 파일 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;621&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tlWH1/btsQDwmUxwl/VIptyYqKBm8szK68hkpNN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tlWH1/btsQDwmUxwl/VIptyYqKBm8szK68hkpNN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tlWH1/btsQDwmUxwl/VIptyYqKBm8szK68hkpNN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtlWH1%2FbtsQDwmUxwl%2FVIptyYqKBm8szK68hkpNN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;794&quot; height=&quot;621&quot; data-origin-width=&quot;794&quot; data-origin-height=&quot;621&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1041&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9pzd3/btsQZfS5YrT/RKXugqzfP7ehzwkDFd3TKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9pzd3/btsQZfS5YrT/RKXugqzfP7ehzwkDFd3TKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9pzd3/btsQZfS5YrT/RKXugqzfP7ehzwkDFd3TKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9pzd3%2FbtsQZfS5YrT%2FRKXugqzfP7ehzwkDFd3TKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;1041&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1041&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편집 및 로그확인을 vscode에서 수행할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode에서 편집은 그냥 프로젝트를 열면 되고 로그는 터미널에서 이클립스 설정한 로그파일을 파워쉘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Get-Content $Path -Wait -Tail 20으로 실시간으로 확인하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vscode에서 터미널에 파월쉘 스크립트로 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 스크립트는 개발 및 운영 로그를 한번에 확인할 수 있게 파워쉘을 작성하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이클립스 및 vscode를 2개를 실행시켜서 하기에 이게 무슨 괴조합이냐라고 할 수 있지만 Eclipse의 멈춤 빡침보다 훨신 쾌적하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1758100644615&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#파워쉘 스크립트 실행 log.bat
@echo off
powershell -NoLogo -ExecutionPolicy Bypass -File &quot;%~dp0log-viewer.ps1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758100741409&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#log-viewer.ps1

$devLog  = &quot;D:\project\dev.log&quot;
$prodLog = &quot;D:\project\prod.log&quot;

# --- DEV 로그 모니터링 Job ---
Start-Job -ScriptBlock {
    $Path = &quot;D:\project\dev.log&quot;
    #$Prefix = &quot;[DEV]&quot;
    $Prefix = &quot;&quot;
    $inSqlBlock = $false
    $inErrorBlock = $false

    Get-Content $Path -Wait -Tail 20 | ForEach-Object {
        $line = $_

        # SQL 블록 시작
        if ($line -match &quot;^-{5,}&quot; -or $line -match &quot;^\s*SQL\s*$&quot; -or $line -match &quot;^\s*select\s&quot; -or $line -match &quot;^\s*insert\s&quot; -or $line -match &quot;^\s*update\s&quot; -or $line -match &quot;^\s*delete\s&quot;) {
            $inSqlBlock = $true
            Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return
        }

        # SQL 블록 종료
        if ($inSqlBlock -and ($line -match &quot;^-{5,}&quot; -or $line -eq &quot;&quot;)) { $inSqlBlock = $false; Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return }

        # SQL 블록 내부
        if ($inSqlBlock) { Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return }

        # Exception / Error 블록 시작
        if ($line -match &quot;Exception&quot; -or $line -match &quot;Error&quot;) { $inErrorBlock = $true; Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; return }

        # Error stack trace
        if ($inErrorBlock -and $line -match &quot;^\s+at &quot;) { Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; return }

        # Error 블록 종료
        if ($inErrorBlock -and $line -eq &quot;&quot;) { $inErrorBlock = $false; Write-Host &quot;$Prefix     $line&quot; -ForegroundColor White; return }

        # 일반 로그 레벨별 색상
        switch -Regex ($line) {
            &quot; INFO &quot;  { Write-Host &quot;$Prefix [INF] $line&quot; -ForegroundColor Cyan; break }
            &quot; WARN &quot;  { Write-Host &quot;$Prefix [WRN] $line&quot; -ForegroundColor Yellow; break }
            &quot; ERROR &quot; { Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; break }
            &quot; DEBUG &quot; { Write-Host &quot;$Prefix [DBG] $line&quot; -ForegroundColor DarkGray; break }
            default   { Write-Host &quot;$Prefix $line&quot; -ForegroundColor White }
        }
    }
}

# --- PROD 로그 모니터링 Job ---
Start-Job -ScriptBlock {
    $Path = &quot;D:\project\prod.log&quot;
    #$Prefix = &quot;[PROD]&quot;
    $Prefix = &quot;&quot;
    $inSqlBlock = $false
    $inErrorBlock = $false

    Get-Content $Path -Wait -Tail 20 | ForEach-Object {
        $line = $_

        if ($line -match &quot;^-{5,}&quot; -or $line -match &quot;^\s*SQL\s*$&quot; -or $line -match &quot;^\s*select\s&quot; -or $line -match &quot;^\s*insert\s&quot; -or $line -match &quot;^\s*update\s&quot; -or $line -match &quot;^\s*delete\s&quot;) {
            $inSqlBlock = $true
            Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return
        }
        if ($inSqlBlock -and ($line -match &quot;^-{5,}&quot; -or $line -eq &quot;&quot;)) { $inSqlBlock = $false; Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return }
        if ($inSqlBlock) { Write-Host &quot;$Prefix $line&quot; -ForegroundColor Green; return }

        if ($line -match &quot;Exception&quot; -or $line -match &quot;Error&quot;) { $inErrorBlock = $true; Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; return }
        if ($inErrorBlock -and $line -match &quot;^\s+at &quot;) { Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; return }
        if ($inErrorBlock -and $line -eq &quot;&quot;) { $inErrorBlock = $false; Write-Host &quot;$Prefix     $line&quot; -ForegroundColor White; return }

        switch -Regex ($line) {
            &quot; INFO &quot;  { Write-Host &quot;$Prefix [INF] $line&quot; -ForegroundColor Cyan; break }
            &quot; WARN &quot;  { Write-Host &quot;$Prefix [WRN] $line&quot; -ForegroundColor Yellow; break }
            &quot; ERROR &quot; { Write-Host &quot;$Prefix [ERR] $line&quot; -ForegroundColor Red; break }
            &quot; DEBUG &quot; { Write-Host &quot;$Prefix [DBG] $line&quot; -ForegroundColor DarkGray; break }
            default   { Write-Host &quot;$Prefix $line&quot; -ForegroundColor White }
        }
    }
}

# --- 두 Job 출력 확인 (실시간 스트리밍)
Get-Job | Receive-Job -Wait -AutoRemoveJob&lt;/code&gt;&lt;/pre&gt;</description>
      <category>TOOL/VSCODE</category>
      <category>Apache Struts</category>
      <category>spring</category>
      <category>struts</category>
      <category>vscode</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/122</guid>
      <comments>https://roaroa.tistory.com/122#entry122comment</comments>
      <pubDate>Wed, 17 Sep 2025 18:22:52 +0900</pubDate>
    </item>
    <item>
      <title>Lively Wallpaper</title>
      <link>https://roaroa.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Lively&amp;nbsp;Wallpaper&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스팀의 Wallpaper Engine 대체&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스팀보다 다양한 테마가 있지는않지만 움직이는 바탕화면을 체험해 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byVFHf/btsQAVNOTFq/r7UbRNu1dXg5J391prew5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byVFHf/btsQAVNOTFq/r7UbRNu1dXg5J391prew5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byVFHf/btsQAVNOTFq/r7UbRNu1dXg5J391prew5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyVFHf%2FbtsQAVNOTFq%2Fr7UbRNu1dXg5J391prew5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;843&quot; height=&quot;752&quot; data-origin-width=&quot;843&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 스팀 Wallpaper Engine인 컨테츠 측명으로 압도적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Review</category>
      <category>lively wallpaper</category>
      <category>steam</category>
      <category>Wallpaper Engine</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/121</guid>
      <comments>https://roaroa.tistory.com/121#entry121comment</comments>
      <pubDate>Tue, 16 Sep 2025 10:00:50 +0900</pubDate>
    </item>
    <item>
      <title>Lazyvim 단축키</title>
      <link>https://roaroa.tistory.com/120</link>
      <description>&lt;h1&gt;LazyVim 생산성 가이드 - 빠른 파일 작업&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;claude.ai의 도움을 받음.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  빠른 파일 탐색 및 이동&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Telescope를 이용한 파일 찾기&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ff  # 파일 찾기 (Find Files)
&amp;lt;leader&amp;gt;fr  # 최근 파일 (Recent Files)  
&amp;lt;leader&amp;gt;fg  # Live grep (파일 내용 검색)
&amp;lt;leader&amp;gt;fb  # 버퍼 목록 (열린 파일들)
&amp;lt;leader&amp;gt;fh  # 도움말 검색
&amp;lt;leader&amp;gt;fc  # 설정 파일 찾기
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 팁:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일명 일부만 타이핑해도 fuzzy 검색&lt;/li&gt;
&lt;li&gt;Ctrl+j/k로 목록 이동, Enter로 선택&lt;/li&gt;
&lt;li&gt;Ctrl+c 또는 Esc로 취소&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Neo-tree 파일 탐색기&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;e   # Neo-tree 토글
&amp;lt;leader&amp;gt;E   # Neo-tree 현재 버퍼 위치로 이동
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Neo-tree 단축키:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;o 또는 Enter: 파일/폴더 열기&lt;/li&gt;
&lt;li&gt;a: 파일/폴더 생성&lt;/li&gt;
&lt;li&gt;d: 삭제&lt;/li&gt;
&lt;li&gt;r: 이름 바꾸기&lt;/li&gt;
&lt;li&gt;x: 잘라내기, c: 복사, p: 붙여넣기&lt;/li&gt;
&lt;li&gt;H: 숨김 파일 토글&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  빠른 파일 생성 및 편집&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;새 파일 생성&lt;/h3&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# Neo-tree에서
a &amp;rarr; 파일명 입력 &amp;rarr; Enter

# 명령어로
:e 새파일명.확장자

# Telescope에서 검색 중
&amp;lt;leader&amp;gt;ff &amp;rarr; 존재하지 않는 파일명 입력 &amp;rarr; Ctrl+Enter
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빠른 버퍼 관리&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;S-h&amp;gt;       # 이전 버퍼로 이동
&amp;lt;S-l&amp;gt;       # 다음 버퍼로 이동
&amp;lt;leader&amp;gt;bd  # 현재 버퍼 삭제
&amp;lt;leader&amp;gt;bD  # 다른 모든 버퍼 삭제
&amp;lt;leader&amp;gt;bo  # 다른 버퍼들 닫기
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚡ 빠른 편집 기능&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;멀티 커서 편집&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;C-n&amp;gt;       # 현재 단어와 같은 다음 단어 선택
&amp;lt;C-p&amp;gt;       # 이전 선택 취소
&amp;lt;C-x&amp;gt;       # 현재 선택 건너뛰기
Alt+j       # 아래 줄에 커서 추가
Alt+k       # 위 줄에 커서 추가
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;코드 접기/펼치기&lt;/h3&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;zc          # 현재 fold 닫기
zo          # 현재 fold 열기
za          # 현재 fold 토글
zM          # 모든 fold 닫기
zR          # 모든 fold 열기
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빠른 검색 및 교체&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;/           # 검색
n           # 다음 검색 결과
N           # 이전 검색 결과
&amp;lt;leader&amp;gt;sr  # 검색 및 교체 (Search &amp;amp; Replace)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Visual 모드 편집&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;v           # 문자 단위 선택
V           # 줄 단위 선택
&amp;lt;C-v&amp;gt;       # 블록 단위 선택
gv          # 이전 선택 영역 다시 선택
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; &amp;zwj;♂️ 빠른 이동&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;줄 이동&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;gg          # 파일 맨 위로
G           # 파일 맨 아래로
{숫자}G     # 특정 줄로 이동
&amp;lt;C-u&amp;gt;       # 반 페이지 위로
&amp;lt;C-d&amp;gt;       # 반 페이지 아래로
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단어/문장 이동&lt;/h3&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;w           # 다음 단어 시작
b           # 이전 단어 시작
e           # 현재/다음 단어 끝
0           # 줄 시작
$           # 줄 끝
^           # 줄의 첫 번째 문자
f{문자}     # 줄에서 문자 찾아 이동
t{문자}     # 문자 앞까지 이동
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;함수/클래스 이동&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;gd          # 정의로 이동 (Go to Definition)
gr          # 참조 찾기 (Go to References)
gi          # 구현으로 이동 (Go to Implementation)
&amp;lt;C-o&amp;gt;       # 이전 위치로 돌아가기
&amp;lt;C-i&amp;gt;       # 다음 위치로 이동
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  프로젝트 작업 최적화&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;작업 공간 관리&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;qq  # 세션 저장하고 종료
&amp;lt;leader&amp;gt;qs  # 세션 저장
&amp;lt;leader&amp;gt;ql  # 마지막 세션 로드
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Git 통합&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;gg  # Lazygit 열기
&amp;lt;leader&amp;gt;gf  # Git 파일 상태
&amp;lt;leader&amp;gt;gb  # Git blame
&amp;lt;leader&amp;gt;gh  # Git hunk 미리보기
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;터미널 통합&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;C-/&amp;gt;       # 플로팅 터미널 토글
&amp;lt;C-_&amp;gt;       # 터미널 토글 (일부 환경)
&amp;lt;leader&amp;gt;ft  # 터미널 탭 열기
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  고급 편집 팁&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빠른 코드 서식&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;cf  # 코드 포맷팅 (Code Format)
&amp;lt;leader&amp;gt;ca  # 코드 액션 (Code Actions)
&amp;lt;leader&amp;gt;rn  # 심볼 이름 바꾸기 (Rename)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자동완성 활용&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;Tab         # 다음 완성 항목
&amp;lt;S-Tab&amp;gt;     # 이전 완성 항목
&amp;lt;C-Space&amp;gt;   # 완성 메뉴 강제 열기
&amp;lt;C-e&amp;gt;       # 완성 취소
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스니펫 활용&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;Tab         # 스니펫 확장
&amp;lt;C-j&amp;gt;       # 다음 스니펫 위치
&amp;lt;C-k&amp;gt;       # 이전 스니펫 위치
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;⚙️ 워크플로우 최적화&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 프로젝트 시작 루틴&lt;/h3&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;cd your-project
nvim .      # 프로젝트 루트에서 시작
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 빠른 파일 작업 패턴&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&amp;lt;leader&amp;gt;e - Neo-tree로 구조 파악&lt;/li&gt;
&lt;li&gt;&amp;lt;leader&amp;gt;ff - 필요한 파일 빠르게 찾기&lt;/li&gt;
&lt;li&gt;&amp;lt;leader&amp;gt;fg - 코드 검색으로 관련 부분 찾기&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 편집 중 효율성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자주 쓰는 파일들은 버퍼로 유지&lt;/li&gt;
&lt;li&gt;&amp;lt;S-h&amp;gt;/&amp;lt;S-l&amp;gt;로 버퍼 간 빠른 전환&lt;/li&gt;
&lt;li&gt;멀티 커서로 반복 작업 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 키보드 중심 워크플로우&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마우스 사용 최소화&lt;/li&gt;
&lt;li&gt;Telescope로 모든 검색 작업&lt;/li&gt;
&lt;li&gt;LSP 기능으로 코드 네비게이션&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  자주 사용하는 조합&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;파일 찾기 &amp;rarr; 편집 &amp;rarr; 저장&lt;/h3&gt;
&lt;pre class=&quot;apache&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ff &amp;rarr; 파일 선택 &amp;rarr; 편집 &amp;rarr; :w
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;텍스트 검색 &amp;rarr; 교체&lt;/h3&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;fg &amp;rarr; 검색어 입력 &amp;rarr; &amp;lt;leader&amp;gt;sr
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;새 파일 생성 &amp;rarr; 편집&lt;/h3&gt;
&lt;pre class=&quot;apache&quot;&gt;&lt;code&gt;&amp;lt;leader&amp;gt;e &amp;rarr; a &amp;rarr; 파일명 &amp;rarr; Enter &amp;rarr; 편집
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 기능들을 익히면 LazyVim에서 매우 빠르게 작업할 수 있습니다!&lt;/p&gt;</description>
      <category>TOOL/Lazyvim</category>
      <category>lazyvim</category>
      <category>Neovim</category>
      <author>로아_</author>
      <guid isPermaLink="true">https://roaroa.tistory.com/120</guid>
      <comments>https://roaroa.tistory.com/120#entry120comment</comments>
      <pubDate>Mon, 15 Sep 2025 13:36:29 +0900</pubDate>
    </item>
  </channel>
</rss>