Skip to content
shellmap

bang-dollarHistory expansion `!$` — last argument of the previous command across all 5 shells

Equivalents in every shell

Bashunix
!$

Expands to the LAST argument of the previous command, parse-time. `!^` is the FIRST argument; `!*` is ALL arguments; `!:N` picks argument N (zero-indexed: `!:0` is the command itself). `Esc-.` (also `Alt-.`) is the inline keyboard equivalent — inserts the value into the current line for editing.

Zshunix
!$

Identical POSIX-style word designators (`!$`, `!^`, `!*`, `!:N`) plus zsh-specific modifiers — `!$:h` (head, drop file from path), `!$:t` (tail, drop dir), `!$:r` (root, drop extension), `!$:e` (extension only). Composable: `!$:h:t` is the parent directory name.

Fishunix
$history[1][-1]

No `!$` shortcut. `$history[1]` is the last command (a string); split it with `string split " " -- $history[1]` if you want fields. Most fish users press `Alt-.` (history-token-search-backward) to insert the previous command's last word inline, edit, then run.

PowerShellwindows
((Get-History -Count 1).CommandLine -split ' ')[-1]

No first-class `!$`. PSReadLine binds `Alt-.` to `YankLastArg` — same UX as bash's `Esc-.` keystroke. `Set-PSReadLineKeyHandler -Chord Alt+. -Function YankLastArg` to confirm or rebind.

cmd.exewindows
(no equivalent)

cmd.exe has no last-argument operator. Workaround: copy from console with mouse selection (Quick Edit Mode) and paste with right-click. The `for /f` loop can split the previous command if you captured it, but there is no live history-arg recall.

Worked examples

Touch a file, then edit it (the canonical bang-dollar example)

Bash
touch report.md && vim !$
Zsh
touch report.md && vim !$
Fish
touch report.md; and vim $history[1][-1]
PowerShell
New-Item report.md; vim ((Get-History -Count 1).CommandLine -split ' ')[-1]

Strip the filename to get just the parent directory of the last argument

Bash
cd "$(dirname !$)"
Zsh
cd !$:h

Use ALL arguments from the previous command

Bash
cp !* /backup/
Zsh
cp !* /backup/

Gotchas

  • Inside DOUBLE-quotes bash still expands `!$` — `echo "use !$"` will substitute, not print literal `!$`. Single-quote (`echo 'use !$'`) or escape (`echo "use \!$"`) for the literal form. Same gotcha as `!!`; same fix.
  • Bang expansion is PARSE-TIME, not lazy. By the time you press Enter, `!$` is already the previous command's last word — there is no live preview unless you use `:p` (`!$:p` echoes without running). On a destructive command, `!$:p` first then re-up-arrow is the safety dance.
  • In zsh, modifier composition is left-to-right but order matters: `!$:t:r` (basename, then strip extension) ≠ `!$:r:t` (strip extension first, then take basename) — for `/var/log/app.log.gz`, the first gives `app.log`, the second gives `app.log.gz`. Read the chain right-to-left in your head if the result surprises you.
  • Fish's `$history[1][-1]` index-of-index syntax does naive whitespace splitting; it breaks on quoted arguments containing spaces (`vim "report draft.md"` becomes `draft.md"`). For string-aware splitting use `string split` with care, or rely on `Alt-.` interactive insertion.
  • PSReadLine's `Alt-.` repeatedly walks BACKWARDS through previous commands' last arguments (press multiple times). Bash's `Esc-.` does the same. This is the keyboard ergonomics most people actually use day-to-day — `!$` is for scripts, not for typing.

WSL & PowerShell Core notes

pwsh`Alt-.` (YankLastArg) is bound by PSReadLine on every pwsh-supported platform — Windows, macOS, Linux — and walks backwards through previous commands' last arguments. `Get-History` returns `HistoryInfo` objects with `.CommandLine`, `.StartExecutionTime`, `.EndExecutionTime`, `.Duration` — useful for scripted last-arg fishing too.
WSLIn WSL bash/zsh, `!$` works exactly as on Linux. Across the WSL ↔ Windows boundary there is no shared history — `!$` in wsl bash sees only commands run inside that wsl session, not commands run earlier in the launching pwsh window.

Related commands