echo $$ linux is a shell command that outputs the process ID (PID) of the current shell session by expanding the special parameter $$.
echo $$
Tested on Ubuntu 22.04 with Linux 5.15.x; verify against vendor docs for non-Debian distributions or older kernels.
Syntax
echo [SHORT-OPTION]... [STRING]...
echo LONG-OPTION
The $$ is not a flag but a shell variable expanded before echo runs. Standard syntax:
echo "PID: $$"
Options and Flags
| Flag | Type | Default | Description |
|---|---|---|---|
-n |
Short | Off | Do not output the trailing newline. |
-e |
Short | Off | Enable interpretation of backslash escapes (e.g., n, t). |
-E |
Short | On | Disable interpretation of backslash escapes (default). |
--help |
Long | N/A | Display help and exit. |
--version |
Long | N/A | Output version information and exit. |
Usage Examples
Display the PID of the Current Shell
echo "This shell's PID is $$"
Outputs This shell's PID is 12345 (actual PID varies). Useful for logging script instance identifiers or debugging process trees.
Store PID in a Variable for Later Use
MYPID=$$
echo "Starting long-running process with PID $MYPID"
# Use $MYPID with kill/wait
Capturing the PID at script start allows cleanup or monitoring of the parent process.
Suppress Newline in PID Output
echo -n "Current PID: "
echo $$
Outputs Current PID: 12345 on the same line. The -n flag removes the trailing newline from the first echo.
Use $$ with printf for Consistent Behavior
printf "PID: %dn" $$
Preferred in scripts when portability across shells matters, as printf has fewer behavioral differences.
Troubleshooting & Common Errors
| Error / Symptom | Root Cause | Resolution Command |
|---|---|---|
echo $$ outputs nothing |
Shell variable expansion failed (very rare; $$ is always defined). Check if executing from a non-shell context (e.g., exec with no shell). |
Run echo "$$" with quotes; still empty? Use sh -c 'echo $$' |
| Unexpected newline or no newline | Using -n or default behavior mix-up |
Check flags; use echo -n to suppress, omit for newline. Verify shell type (echo $0) |
/bin/echo $$ vs builtin differences |
/bin/echo does not expand variables; shell expands $$ before execution. |
Use the builtin (default in bash). To force builtin, builtin echo $$ |
Exit Codes
| Code | Meaning | Operational Impact |
|---|---|---|
| 0 | Successful execution | String written to stdout. Normal operation. |
| 1 | Write error | Usually indicates full disk, broken pipe, or permission issue. Check stderr for details. |
Note: echo built-in always returns 0 unless a write error occurs. The exit code does not reflect string content.
echo $$ linux — Performance Considerations and Tuning
The command echo $$ prints the shell’s PID. Since echo is a built‑in in bash, no process is forked and no getpid() syscall is made; the PID is stored internally. Performance tuning here is about I/O buffering when output is redirected.
- PID limit: Kernel parameter
pid_maxcaps process IDs. View withcat /proc/sys/kernel/pid_max. - Pipe buffer: Controlled by
fs.pipe-max-size. Read viacat /proc/sys/fs/pipe-max-size. Larger buffers reduce context switches for bulk output. - Terminal speed: Serial line rate can be tuned with
stty speed; inspect withstty -a. - Batch PID capture: Store PID once:
MYPID=$$; echo "$MYPID". Avoids repeated expansion in loops.
# Kernel PID limit
cat /proc/sys/kernel/pid_max
# Pipe buffer max size
cat /proc/sys/fs/pipe-max-size
# Terminal speed
stty -a | grep speed
echo $$ linux — Security and Operational Best Practices
Outputting the PID of the current shell can leak process identifiers in multi‑user or containerized environments. Mitigate as follows:
- Least‑Privilege: Run shells under dedicated, non‑root system accounts. Restrict IAM roles that grant shell access in cloud VMs.
- Authentication: Lock down remote shells:
PermitEmptyPasswords no,MaxAuthTries 3,LogLevel VERBOSEinsshd_config. Useseccompprofiles to block built‑in echoes in restricted containers. - Audit & Logging: Monitor shell executions via
auditdandjournalctl. Enable timestamped history:HISTTIMEFORMAT="%F %T ".
# Audit shell execution
sudo auditctl -w /bin/bash -p x -k shell_pid
sudo auditctl -w /bin/sh -p x -k shell_pid
# Search for recent echo $$ usage via audit logs
sudo ausearch -k shell_pid --format text -i | grep "echo $$"
# View recent shell audit events through systemd journal
journalctl _COMM=auditd -n 10 --no-pager
# Enable detailed SSH session logging (in /etc/ssh/sshd_config)
echo "LogLevel VERBOSE" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
No native cloud CLI subcommand; echo and shell PID expansion are available within compute instances across providers.
Frequently Asked Questions
What is the difference between echo $$ and echo $? in Linux?
Answer: $$ expands to the PID of the current shell; $? expands to the exit code of the last foreground command.
Both are shell variables, not flags. echo $$ prints the process ID of the shell instance, useful for logging or creating lock files. echo $? outputs an integer from 0 to 255, indicating success or failure of the last executed command. Example:
$ echo $$ # e.g., 12345
$ echo $? # 0
When should I use echo $$ in a Linux script?
Answer: Use echo $$ to capture the current shell PID for log files, PID file creation, or inter-process signaling.
Commonly used in init scripts or daemon startups to record the PID: echo $$ > /var/run/myapp.pid. Avoid calls inside subshells, as $$ then reflects the parent shell, not the subshell. For the subshell PID, use $BASHPID instead.
#!/bin/bash
echo "Script PID: $$" >> /var/log/script.log
How do I fix echo $$ returning an empty string on Linux?
Answer: Switch to a POSIX-compliant shell like Bash, Dash, or Zsh.
In Fish shell, use echo $fish_pid. For scripts, always set shebang to #!/bin/bash or #!/bin/sh. Verify the current shell with echo $0.
# In Fish:
echo $fish_pid
Does echo $$ work on all Linux distributions and major cloud platforms (AWS, Azure, GCP)?
Answer: Yes.
It is a POSIX shell feature, not OS- or cloud-specific. Works in all default shells (Bash, Dash, Zsh) and within Docker/containers. No extra dependencies required.
$ echo $$ # Works identically on Amazon Linux, Ubuntu, and Google Cloud Shell
What is the fastest way to capture the current shell PID using echo $$ in a Linux script?
Answer: Assign directly: MYPID=$$.
Variable assignment in POSIX shells is immediate and zero-overhead.
# Fast (no subshell):
MYPID=$$
# Slow (subshell fork):
MYPID=$(echo $$)
For inline output, echo $$ alone is efficient—echo is a shell builtin.

Command Line Expert & Software Engineer
Welcome! I’m Thomas Heinrich, a software engineer and system administrator with a deep passion for the Command Line Interface (CLI). With years of experience navigating the terminal, building backend architectures, and automating server deployments, I created this space to share practical, real-world terminal knowledge.
Whether you are a beginner taking your first steps in a Linux environment or a seasoned DevOps engineer looking to optimize your deployment scripts, you will find actionable solutions here. My goal is to help you ditch the mouse, speed up your workflow, and harness the full power of the command line.