# stinkpot - SQLite 기반 Bash 셸 히스토리 검색기

> Clean Markdown view of GeekNews topic #31815. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31815](https://news.hada.io/topic?id=31815)
- GeekNews Markdown: [https://news.hada.io/topic/31815.md](https://news.hada.io/topic/31815.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-07-26T09:05:35+09:00
- Updated: 2026-07-26T09:05:35+09:00
- Original source: [tangled.org](https://tangled.org/oppi.li/stinkpot)
- Points: 1
- Comments: 1

## Topic Body

- **stinkpot**은 Bash 명령 기록을 SQLite에 저장해 세션과 무관하게 관리하고, 검색 TUI로 빠르게 찾을 수 있게 함
- Atuin에서 동기화 서버, AI, dotfiles·스크립트 관리자, KV 저장소를 덜어내고 필요한 기능만 **약 400줄의 Go**로 구현함
- 기존 Bash 히스토리는 `stinkpot import`로 가져오며, `Ctrl+R`을 누르면 **역방향 검색 TUI**가 열림
- NixOS에서는 **home-manager 모듈**을 제공하고, 그 외 환경에서는 `.bashrc`에서 `eval "$(stinkpot init)"`으로 초기화함
- 데이터베이스는 `~/.local/share/stinkpot`에 저장되며, 업그레이드 후 손상되면 삭제한 뒤 히스토리를 다시 가져올 수 있음

---

### Atuin에서 필요한 기능만 분리
- **stinkpot**은 Atuin을 사용하면서 세션 독립적 히스토리 관리와 검색 TUI만 필요했던 경험에서 출발함
  - 동기화 서버, Atuin AI, dotfiles 관리자, 스크립트 관리자, KV 저장소는 포함하지 않음
  - 머신마다 설정과 실행 명령이 크게 달라 동기화 기능도 사용하지 않았음
- 프로젝트는 약 **400줄의 Go**로 작성됐으며, 저장소 언어 비중은 Go 82.5%, Nix 17.5%임
- 이름은 작은 거북 종인 `stinkpot`에서 따옴
- 역방향 검색 속도를 높이기 위해 SQLite 실행 계획이 정렬용 임시 B-tree 대신 **커버링 인덱스(covering index)** 를 사용함

### 설치와 히스토리 검색
- 소스에서는 다음 명령으로 빌드함

```bash
go build -o stinkpot .
```

- NixOS home-manager 사용자는 제공되는 `homeManagerModules.default` 모듈을 가져올 수 있음
- 다른 환경에서는 `.bashrc`에 다음 초기화 명령을 추가함

```bash
eval "$(stinkpot init)"
```

- 기존 Bash 히스토리는 다음 명령으로 가져옴

```bash
stinkpot import
```

- 셸에서 `Ctrl+R`을 누르면 검색 TUI가 열림
  - `↑`·`↓`로 이동하고 `Tab` 또는 `Enter`로 선택함
  - 선택 후 `Enter`를 다시 누르면 명령을 실행함
  - `Esc`로 취소함
- 히스토리 DB는 `~/.local/share/stinkpot`에 저장됨
  - 업그레이드 후 DB가 깨지면 파일을 삭제하고 `stinkpot import`를 다시 실행함

## Comments



### Comment 62390

- Author: neo
- Created: 2026-07-26T09:05:36+09:00
- Points: 1

###### [Lobste.rs 의견들](https://lobste.rs/s/bvgaff/stinkpot_sqlite_backed_shell_history) 
- 이번 주 프롬프트에서 실수로 `?`를 입력했다가 Atuin이 **AI 모드**를 활성화할지 묻는 걸 보고 얼마나 비대해졌는지 깨달았음  
  사양하겠음. 소개해 준 덕분에 이제 stinkpot으로 전환했음
- 셸 명령 기록을 잃어버려 고생한 적이 있어 이 프로젝트가 정말 마음에 듦. atuin.sh도 써봤지만 그다지 만족스럽지 않았음  
  특히 **Go 코드 400줄**로 단순한 정적 최소 바이너리를 만든 점이 좋음. Go는 전반적으로 훌륭한 언어이며, stinkpot도 사용해 볼 예정임
- [hstr](https://github.com/dvorka-oss/hstr)나 [fzf](https://github.com/junegunn/fzf#customizing-fuzzy-completion-for-bash-and-zsh)처럼 기록 파일을 직접 읽는 도구와 비교해 여기서 **SQLite**를 사용하면 무엇이 더 좋아지는지 궁금함  
  hstr를 약 15년간 사용했고 최근에는 fzf로 옮겨가고 있음. SQLite 자체는 아주 좋아하지만 이 용도에 필요한 이유는 이해하지 못했음
  - Bash가 명령 실행 후 매번 기록을 파일에 쓰도록 하면 **fzf만으로도** 비슷하게 구현할 수 있음  
    기본 기록 파일은 구조화돼 있지 않지만 SQLite에는 종료 코드와 종료 시각 같은 데이터를 저장할 수 있고, 삽입 시 중복 제거 또는 같은 명령을 다시 실행했을 때 실행 시각 갱신 같은 처리도 빠르게 수행 가능함
  - 각 기록 항목의 **현재 작업 디렉터리**를 저장하고 색인하는 용도를 생각해 봤음  
    이론적으로는 명령 기록에서 문맥을 힘들게 복원할 수 있지만, 프로젝트 디렉터리별로 셸 기록을 빠르게 조회할 수 있다면 꽤 유용할 것 같음
- 확실히 사용해 볼 만함. Atuin은 거의 관심 없는 기능으로 가득한 **기능 동물원**이 됐음  
  그래도 잘 작동한다는 장점은 있지만, 업데이트한 지 오래됐을 가능성이 큼
  - Atuin은 예전부터 알았지만 이번 주에야 처음 써봤음. 지금 추세라면 곧 **이메일까지 읽기 시작할 것** 같음
- 훌륭해 보이는데 기록을 `cwd`로 필터링할 수 있는지 궁금함. 명령 기록의 기준을 디렉터리로 삼을 수 있다는 점이 Atuin을 쓰는 유일한 이유임  
  프로젝트로 `cd`한 뒤 이전에 멈춘 지점부터 바로 이어갈 수 있으며, 매개변수가 많은 긴 명령을 다시 실행할 때 특히 유용함
  - fish는 이 기능을 기본 제공하며 아주 유용함
  - 개인적으로 선호하는 동작은 아니지만 한 가지 제약 아래 구현 가능함. **stinkpot 설치 이후 실행한 명령**만 `cwd`가 기록되며, 기본 `bash_history`에는 이 정보가 없음
- 다른 사람들이 안심하고 코드를 사용하게 하려면 프로젝트에 **라이선스**를 추가하는 편이 좋음  
  괜찮다면 공개 라이선스를 추가한 뒤 [experimental oils readline](https://github.com/Melkor333/oils-readline)에 통합하고 싶음. 동적 위젯을 완성한 다음 처리할 최우선 TODO 중 하나가 명령 기록임
- 기록에서 명령을 얼마나 쉽게 삭제할 수 있는지 궁금함. SQLite 데이터베이스에서 SQL로 직접 행을 지워야 하는지 알고 싶음  
  드물지만 셸 기록에서 명령 몇 줄을 삭제해야 할 때가 있으며, 기존 방식에서는 `bash_history`를 직접 열어 해당 줄을 지울 수 있었음. stinkpot에 **기록 삭제 명령**이 있는지 궁금함  
  이런 특이한 용도와 별개로 프로젝트 자체는 상당히 흥미로워 보임
