[CLI] 하나의 기기에서 Codex(chatgpt) 다계정 사용하기
한도 다 쓰면 로그아웃하고 다른 계정으로 로그인하는 게 귀찮아서 정리함.
빠르게 적용하기: 이 글의 url을 당신의 ai에게 던져서 이대로 해달라고 하세요.
TLDR:
- 여러 개의 CLI를 만든다. (이 글에선 2개로 가정)
- 모든 걸 공유한다. 대화내역, 메모리, 스킬 등 전부 하나처럼 유지된다. (사실 하나다. symlink니까)
- 로그인정보만 다르게 하면 된다.
- 이 방식으로 2개 이상의 계정을 동시에 사용할 수 있다.
- CLI만 설명한다. 앱을 두 개 이상 만드는 건 다음 글에서 설명한다.
- Codex말고 Claude code도 동일한 방식 적용 가능하다.
방법
기존의 command가 codex이고 새로 만드는 command를 codex2라고 하자.
1) alias
# ~/.zshrc
alias codex2='CODEX_HOME="$HOME/.codex2" codex'
codex2를 처음 실행해 로그인하면 ~/.codex2/auth.json이 생기고 이용 가능하다.
다만 이러면 codex와 codex2의 대화내역, 메모리, 스킬 등이 다르게 관리된다.
2) symlink 설정하기
~/.codex2를 ~/.codex의 선택적 미러로 만든다. 계정 파일(auth.json)과 실행 중 생기는 런타임 파일만 각자 두고, 나머지는 전부 심볼릭 링크로 공유한다. 아래를 ~/.local/bin/codex2-sync로 저장:
#!/usr/bin/env bash
set -euo pipefail
SRC="$HOME/.codex"; DST="$HOME/.codex2"
# 공유하지 않고 각자 가질 것: 계정 + 휘발성 런타임
EXCLUDE=(auth.json ipc tmp .tmp cache log mcp-oauth-locks
process_manager node_repl shell_snapshots computer-use
.DS_Store .stfolder .stignore)
excluded(){ local n="$1"; for e in "${EXCLUDE[@]}"; do [[ "$n" == "$e" ]] && return 0; done; return 1; }
mkdir -p "$DST"
for path in "$SRC"/* "$SRC"/.*; do
name="$(basename "$path")"
[[ "$name" == "." || "$name" == ".." ]] && continue
[[ -e "$path" ]] || continue
excluded "$name" && continue
target="$DST/$name"
if [[ -L "$target" ]]; then
[[ "$(readlink "$target")" == "$path" ]] || { rm -f "$target"; ln -s "$path" "$target"; }
elif [[ ! -e "$target" ]]; then
ln -s "$path" "$target"
fi
done
# 원본이 사라진 끊긴 링크 정리
for link in "$DST"/* "$DST"/.*; do
[[ -L "$link" && ! -e "$link" ]] && rm -f "$link"
done
echo "Synced $DST"
chmod +x ~/.local/bin/codex2-sync && codex2-sync
이제 codex(기존 cli)와 codex2(새로 만든 cli)를 동시에 띄워도 된다.
원리
codex의 모든 상태는 CODEX_HOME(기본값 ~/.codex) 아래에 있고, "계정"은 사실상 auth.json 하나다. 그래서 auth.json만 갈라주면 별개 계정이 된다. 나머지 설정·기록을 심볼릭으로 공유해도, 상태 DB(sqlite)가 WAL 모드라 두 프로세스가 동시에 접근해도 안전하다. 소켓·잠금 같은 휘발성 런타임만 분리하면 둘이 나란히 돌아간다.
주의: 데스크톱 앱은 이야기가 다르다
CLI는 이걸로 끝이다. 하지만 ChatGPT 데스크톱 앱은 살짝 번거롭다. 다음 글에서.