바쁜 분은 이것만
명령 | pbcopy하면 출력이 그대로 클립보드에 들어가요pbpaste | sort | uniq처럼 클립보드 내용을 바로 가공할 수 있어요- 한글이 깨지면
LANG=ko_KR.UTF-8이 있는지 먼저 확인 (파이썬에서도 env로 넣기)
터미널 출력을 마우스로 드래그해서 복사하다 보면 줄이 빠지거나 프롬프트까지 같이 딸려 와요. 맥에는 pbcopy와 pbpaste라는 명령이 기본으로 들어 있어서, 파이프 하나로 출력을 클립보드에 넣고 꺼낼 수 있습니다. 직접 돌려 보면서 한글이 깨지는 조건까지 같이 정리했어요.
1. 명령 출력을 바로 클립보드로: | pbcopy
앞 명령의 출력을 | pbcopy로 넘기면 화면에는 아무것도 안 나오고 클립보드에 들어가요. 확인은 pbpaste로 합니다.
$ ls | pbcopy; echo "exit=$?"
exit=0
$ pbpaste
a.py
b.py
fruits.txt
hello.txt
notes.md
파일 내용을 통째로 복사할 때는 cat 파일 | pbcopy도 되고, 리다이렉트 <로 넣어도 같아요.
$ cat fruits.txt | pbcopy
$ pbpaste | wc -l
6
$ pbcopy < hello.txt
$ pbpaste
안녕하세요
클립보드 테스트
한 가지 알아 둘 점은 끝의 줄바꿈도 같이 복사된다는 거예요. echo는 마지막에 줄바꿈을 붙이니까 글자 수가 하나 더 많아요. 경로 한 줄처럼 붙여넣을 곳이 입력창이면 printf를 쓰는 편이 깔끔합니다.
$ echo hello | pbcopy; pbpaste | wc -c
6
$ printf hello | pbcopy; pbpaste | wc -c
5
에러 메시지는 표준 에러로 나오기 때문에 | pbcopy만으로는 안 들어가요. 에러를 복사해서 검색하고 싶을 땐 2>&1을 붙입니다.
$ ls nofile 2>&1 | pbcopy; pbpaste
ls: nofile: No such file or directory
2. 클립보드 내용 가공: pbpaste | sort | uniq
반대로 어딘가에서 복사해 온 목록을 터미널 명령으로 정리할 수도 있어요. 아래는 apple, banana, apple, cherry, banana, apple 여섯 줄이 클립보드에 있는 상태입니다.
$ pbpaste | sort | uniq
apple
banana
cherry
$ pbpaste | sort | uniq -c | sort -rn
3 apple
2 banana
1 cherry
uniq는 바로 옆에 붙은 중복만 지우기 때문에 앞에 sort가 꼭 있어야 해요. uniq -c는 몇 번 나왔는지 세 주고, 다시 sort -rn으로 많은 순으로 줄 세웠어요.
정리한 것을 다시 클립보드에 넣으면 복사 → 정리 → 붙여넣기가 한 줄로 끝나요. 파일로 남기고 싶으면 >로 보내면 됩니다.
$ pbpaste | sort -u | pbcopy
$ pbpaste
apple
banana
cherry
$ pbpaste > fruits_sorted.txt; wc -l fruits_sorted.txt
3 fruits_sorted.txt
3. 한글이 깨질 때: LANG 확인
man pbcopy를 보면 pbcopy·pbpaste는 로캘 환경 변수(LANG)를 보고 문자 인코딩을 정한다고 나와 있어요. 터미널 앱은 보통 이 값을 자동으로 넣어 주지만, 비어 있는 환경도 있어요. 실제로 이번에 테스트한 셸이 그랬습니다.
$ echo "[$LANG]"
[]
그래서 LANG을 넣은 경우와 뺀 경우를 섞어서 '한글 테스트'를 주고받아 봤어요(U는 env LANG=ko_KR.UTF-8, N은 env -u LANG -u LC_ALL -u LC_CTYPE로 감싼 함수).
--- A. 복사 UTF-8, 붙여넣기 UTF-8
한글 테스트
--- B. 복사 UTF-8, 붙여넣기 LANG 없음
�ѱ� ��Ʈ
--- B 바이트 확인
00000000: c7d1 b1db 20c5 d7bd bac6 ae0a .... .......
한글 테스트
--- C. 복사 LANG 없음, 붙여넣기 UTF-8
pbcopy exit=0
0
«class utf8», 0, «class ut16», 2, string, 0, Unicode text, 0
--- D. 영어만이면 LANG 없어도 그대로
abc 123
- B: LANG 없이
pbpaste하면 이 맥에서는 EUC-KR 바이트로 나왔어요. 'B 바이트 확인'의 마지막 줄은 같은 출력을iconv -f EUC-KR -t UTF-8로 바꾼 것인데, 제대로 읽혀서 인코딩 문제라는 게 확인됩니다. - C가 더 위험해요. LANG 없이 한글을
pbcopy하면 exit 0인데 클립보드가 빈 채로 남았어요.osascript -e 'clipboard info'로 봐도 텍스트가 0바이트입니다. 에러가 없어서 모르고 지나가기 쉬워요. - 영어·숫자만 있으면 LANG이 없어도 멀쩡해요(D). 한글을 다룰 때만 티가 납니다.
고치는 법은 간단해요. 스크립트 맨 위에 export LANG=ko_KR.UTF-8을 두거나(en_US.UTF-8도 UTF-8이면 됩니다), 한 번만 쓸 때는 명령 앞에 붙이면 돼요.
echo '한글 테스트' | LANG=ko_KR.UTF-8 pbcopy
cron이나 launchd처럼 환경 변수를 거의 안 넘겨주는 곳에서 돌리는 스크립트라면 LANG이 비어 있을 수 있으니, 처음부터 넣어 두는 게 안전해요.
4. 파이썬 subprocess로 클립보드 쓰고 읽기
파이썬에서도 별도 패키지 없이 subprocess로 pbcopy·pbpaste를 부르면 됩니다. 3번에서 본 문제 때문에 env에 LANG을 직접 넣어 주는 게 포인트예요.
import os
import subprocess
# pbcopy/pbpaste가 UTF-8로 주고받도록 LANG을 넣어 준다
ENV = {**os.environ, "LANG": "ko_KR.UTF-8"}
def copy(text: str) -> None:
subprocess.run(["pbcopy"], input=text, text=True, encoding="utf-8", env=ENV, check=True)
def paste() -> str:
r = subprocess.run(["pbpaste"], capture_output=True, text=True, encoding="utf-8", env=ENV, check=True)
return r.stdout
copy("파이썬에서 넣은 글자\nsecond line")
print(repr(paste()))
# 클립보드의 줄을 정리해서 다시 넣기
copy("b\na\nb\nc\n")
lines = sorted(set(paste().splitlines()))
copy("\n".join(lines))
print(paste().splitlines())
# LANG 없이 부르면?
bad = {k: v for k, v in os.environ.items() if k not in ("LANG", "LC_ALL", "LC_CTYPE")}
subprocess.run(["pbcopy"], input="한글", text=True, encoding="utf-8", env=bad, check=True)
print(repr(paste()))
$ .venv/bin/python p4.py
'파이썬에서 넣은 글자\nsecond line'
['a', 'b', 'c']
''
input=으로 넘긴 문자열이 pbcopy의 표준 입력이 되고, pbpaste는capture_output=True로 받아요.- 마지막 줄처럼 LANG을 빼고 한글을 넣으면
check=True인데도 예외 없이 빈 문자열이 돼요. 셸에서 본 C 경우와 같습니다. encoding="utf-8"은 파이썬 쪽,LANG은 pbcopy 쪽 설정이라 둘 다 맞춰야 해요.
5. 쓰기 전에 알아 둘 점: 기존 클립보드는 덮어씌워진다
pbcopy를 한 번 부르면 원래 클립보드에 있던 것은 사라져요. 이미지가 들어 있던 경우도 마찬가지입니다. 그리고 pbpaste는 텍스트만 꺼내기 때문에, 이미지가 들어 있을 때 pbpaste > 백업.txt로 저장해 두려 해도 0바이트 파일만 생겨요. 이번 테스트도 처음 클립보드에 이미지가 있어서 pbpaste로는 백업이 안 됐고, 다른 방법으로 저장했다가 끝나고 되돌렸어요.
스크린샷을 파일 대신 클립보드로 보내는 screencapture -c도 같은 이유로 조심해야 하는데, 옵션 정리는 맥 screencapture 명령어 정리에 적어 두었어요.
정리
| 하고 싶은 것 | 명령 | 주의 |
|---|---|---|
| 출력 복사 | ls | pbcopy |
에러까지면 2>&1 |
| 파일 내용 복사 | pbcopy < 파일 |
끝 줄바꿈도 복사됨 |
| 줄바꿈 없이 복사 | printf 글자 | pbcopy |
echo는 줄바꿈 붙음 |
| 중복 빼고 다시 넣기 | pbpaste | sort -u | pbcopy |
uniq는 sort 다음에 |
| 한글 깨짐 | export LANG=ko_KR.UTF-8 |
없으면 빈 클립보드도 exit 0 |
| 파이썬 | subprocess.run(["pbcopy"], input=..., env=ENV) |
env에 LANG 넣기 |
참고: macOS man page — pbcopy(1) (LANG 환경 변수와 인코딩 설명) / Python 공식 문서 — subprocess.run
