sudo -S와 heredoc 충돌
sudo -S에 비번 주려는데 heredoc이 가로채서 에러남.
sudo -S랑 heredoc 같이 쓸 때 문제
/etc/fstab 에 내용 추가하려다 겪음.
echo 'PW' | sudo -S tee -a /etc/fstab > /dev/null <<EOF
UUID=... /mnt/x ext4 defaults 0 2
EOF
실행하니 "Sorry, try again. sudo: no password was provided" 에러. sudo가 비번 못 받음.
원인: sudo -S는 stdin에서 비번 읽음. heredoc (<<EOF)도 stdin을 자기 내용으로 덮어씀. heredoc이 이김. 그래서 파이프된 비번이 sudo에 안 감. heredoc 내용이 비번으로 들어간 셈.
해결: sudo -S랑 heredoc 같이 쓰지 마. 아래 중 하나로 처리.
- sudo bash -c 에 전체 명령을 single-quoted string으로 넘김 (추천)
echo 'PW' | sudo -S bash -c 'printf "line1\nline2\n" >> /etc/fstab'
- tee -a 에 echo/printf로 내용 파이프 (좀 지저분함)
printf 'line1\nline2\n' | { echo 'PW' | sudo -S -p "" tee -a /etc/fstab; }
- 임시 파일 만들고 sudo cp
printf '...' > /tmp/frag && echo 'PW' | sudo -S sh -c 'cat /tmp/frag >> /etc/fstab'
여러 sudo 명령 연달아 쓸 땐 sudo -v로 미리 비번 캐싱해두면 편함.
여기서 배울 것
- sudo -S는 stdin에서 비번 읽음.
- heredoc도 stdin을 덮어씀. 둘이 같이 쓰면 충돌남.
- sudo bash -c '...'로 여러 줄 명령 처리하는 게 깔끔.
- sudo -v로 비번 미리 캐싱 가능.
원본 파일 보기 (.claude/memory/sudo_S_heredoc_stdin_conflict.md)
---
name: sudo -S and heredoc both want stdin
description: Piping a password to sudo -S while the inner command reads a heredoc causes the heredoc to consume the password
date: 2026-04-18
tags: [bash, sudo, shell]
---
## What happened
Tried to append to `/etc/fstab` with:
```
echo 'PW' | sudo -S tee -a /etc/fstab > /dev/null <<EOF
UUID=... /mnt/x ext4 defaults 0 2
EOF
```
Got "Sorry, try again. sudo: no password was provided" — sudo received the heredoc body instead of the password.
## Root cause
`sudo -S` reads the password from stdin. But the heredoc (`<<EOF`) also redirects stdin to the heredoc body. The heredoc wins (it's the final stdin redirection on the command), so the piped password never reaches sudo.
## Next time
When writing files that need sudo, avoid combining `sudo -S` with heredocs. Use one of:
1. **`sudo bash -c` with a single-quoted string** (preferred for multi-line):
```
echo 'PW' | sudo -S bash -c 'printf "line1\nline2\n" >> /etc/fstab'
```
2. **`tee -a` with echo/printf piped in, no heredoc**:
```
printf 'line1\nline2\n' | { echo 'PW' | sudo -S -p "" tee -a /etc/fstab; }
```
(awkward — prefer option 1)
3. **Write to a temp file first, then `sudo cp`**:
```
printf '...' > /tmp/frag && echo 'PW' | sudo -S sh -c 'cat /tmp/frag >> /etc/fstab'
```
Use `sudo -v` first to cache credentials if doing many sudo commands in a row.