yes — Endlessly emit a string for piping into interactive prompts across all 5 shells
Equivalents in every shell
yes | apt remove some-package`yes` prints `y\n` forever; `yes word` prints `word\n` forever. Outputs at hundreds of MB/s, so ALWAYS pipe — bare `yes` will fill a terminal scrollback in seconds. The canonical use is to satisfy `[y/N]` prompts in scripts that have no `--yes`/`-y` flag.
yes | apt remove some-packageCalls the same external `/usr/bin/yes` binary. Identical behaviour.
& { while ($true) { "y" } } | pip uninstall some-packageNo native `yes` cmdlet. The idiom is `& { while ($true) { "y" } }` — wrap in a script block so the loop runs as a child pipeline and can be killed cleanly when the consumer closes its stdin. `1..[int]::MaxValue | ForEach-Object { "y" }` works but allocates 2B integers upfront. Long-form: `Set-Alias yes { while ($true) { "y" } }` for muscle-memory parity.
for /L %i in (1,0,2) do @echo yNo native `yes` binary. The infinite-loop trick: `for /L %i in (1,0,2)` runs forever (start=1, step=0, end=2 — start ≠ end and step=0 means never reach end). Pipe into the consumer. In batch files double the `%`: `for /L %%i in (1,0,2) do @echo y`. Ctrl-C kills both.
Worked examples
Auto-accept apt-remove prompts
yes | sudo apt remove docker docker-composeyes | sudo apt remove docker docker-compose& { while ($true) { "y" } } | wsl -d Ubuntu sudo apt remove dockerfor /L %i in (1,0,2) do @echo y | wsl sudo apt remove dockerStress-test stdin (saturate a fifo or test rate limit)
yes | pv > /dev/null # watch throughputyes | pv > /dev/null& { while ($true) { "y" } } | Measure-Object -Linefor /L %i in (1,0,2) do @echo y | find /c "y"Auto-answer with a custom string instead of "y"
yes maybe | head -3yes maybe | head -3& { while ($true) { "maybe" } } | Select-Object -First 3for /L %i in (1,0,2) do @echo maybeGotchas
- Bare `yes` (no pipe) floods your terminal at memory-bandwidth speeds — hundreds of MB per second of `y\n`. ALWAYS pipe to a consumer, or your scrollback explodes. Killing with Ctrl-C works but a slow terminal emulator (Apple Terminal, mintty) can take a few seconds to catch up.
- `yes | cmd` keeps writing AFTER `cmd` exits, briefly, until `yes` gets a SIGPIPE on the next write to a closed pipe. Most of the time this is invisible, but in pipelines where you care about exit codes (`set -o pipefail`), `yes` returning 141 (128+SIGPIPE=13) can surface — handle with `yes 2>/dev/null | cmd; (( PIPESTATUS[1] ))`.
- On macOS, `/usr/bin/yes` IS a real binary (not a builtin), inherited from BSD. Behaves identically to GNU `yes` for the common case but slower throughput (BSD `yes` writes one `y\n` per write() syscall; GNU `yes` batches 8KB at a time, ~100× faster). Almost never matters in practice.
- pwsh `& { while ($true) { "y" } }` pipes via PowerShell's OBJECT pipeline — each "y" goes through the formatting layer. When piping to a native command (`pip`, `apt` under WSL), pwsh converts strings to UTF-16 LE on Windows pwsh 5.1 or UTF-8 on pwsh 6+, then re-encodes as the child's stdin codepage. For tools that expect ASCII `y\n`, pwsh 5.1's UTF-16 BOM-prefixed output can break the prompt match — pwsh 6+ resolves it.
- cmd `for /L %i in (1,0,2) do @echo y` is a real infinite loop — kills the host shell on Ctrl-C, not just the for. To run as a one-shot inside a batch script, prefer `:loop` + `echo y` + `goto loop` with a counter, or shell out to PowerShell. Some Windows AV (Defender SmartScreen) flags the `(1,0,2)` zero-step pattern as suspicious, since malware uses it for sleep-loops.