Why does running echo $$ in bash return a number like 7190, while running echo $ only returns a $?
- 57,256
- 3,878
- 7
- 32
- 57
3 Answers
Convention.
$$: Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell (see the link to the manual below).
rinzwind@schijfwereld:~$ echo $$
3244
rinzwind@schijfwereld:~$ ps -ef |grep 3244
rinzwind 3244 3237 0 19:06 pts/0 00:00:00 /bin/bash
Very useful when coding software. And it can be used as a crude (mktemp would be the better method) way of creating temp files
1 $ has no special meaning so it gives you what echo always does: return it.
There is a manual page dedicated to this (3.4.2 Special Parameters).
- 309,379
In bash to state using a variable we use $, using $$ with the first dollar sign we are saying that I want to use a variable and using the second one we are telling that the name of that variable is actually a $. it's actually a naming convention, and this variable contains the process id of the current shell.
As you asked in the comments with $$$$ you are returning the same process id twice.
There are other variables too (From here):
$1,$2,$3, ... are the positional parameters."$@"is an array-like construct of all positional parameters,{$1, $2, $3 ...}."$*"is the IFS expansion of all positional parameters,$1 $2 $3 ....$#is the number of positional parameters.$-current options set for the shell.$$pid of the current shell (not subshell).$_most recent parameter (or the abs path of the command to start the current shell immediately after startup).$IFSis the (input) field separator.$?is the most recent foreground pipeline exit status.$!is the PID of the most recent background command.$0is the name of the shell or shell script.
- 57,256
Here is a real life application of $$ taken from Lock Screen Timer:
# Check if lock screen timer already running
pID=$(pgrep -f "${0##*/}") # All PIDs matching lock-screen-timer name
PREVIOUS=$(echo "$pID" | grep -v ^"$$") # Strip out this running copy ($$$)
if [ "$PREVIOUS" != "" ]; then
kill "$PREVIOUS"
rm ~/.lock-screen-timer-remaining
zenity --info --title="Lock screen timer already running" --text="Previous lock screen timer has been terminated."
fi
In this code snippet the line:
PREVIOUS=$(echo "$pID" | grep -v ^"$$") # Strip out this running copy
uses the current running process ($$) to remove it (denoted by not -v) from the list of all processes running under the same name (lock-screen-timer in this case).
If there was a previous running copy the code kills it and delete the work file it was using.
- 105,762