What is the meaning of a double dollar sign in bash/Makefile?
As per gnu make official doc:
Variable and function references in recipes have identical syntax and
semantics to references elsewhere in the makefile. They also have the
same quoting rules: if you want a dollar sign to appear in your
recipe, you must double it (‘$$’). For shells like the default shell,
that use dollar signs to introduce variables, it’s important to keep
clear in your mind whether the variable you want to reference is a
make variable (use a single dollar sign) or a shell variable (use two
dollar signs).
So in short:
- makefile variable => use a single dollar sign
- shell variable => use two dollar signs
makefile double dollar sign in user defined function
Yes, used like this it's an error to double the dollar signs. The only time it wouldn't hurt to double them is if you were going to send the results of the call
function to something like eval
which expand the results again. But there's no need for it in either case.
I should point out that this example, while better than most other methods, is somewhat deprecated these days. The GCC compiler has options which can generate pretty much exactly the makefile dependency output you want without postprocessing, and while still creating the object file at the same time. This is actually significantly more efficient because you don't have to run the compiler twice every time you compile.
What does the double dollar sign ($$) mean?
The $
sign is an operator in awk to reference a field. Example:
$ echo "foo bar car" | awk '{print $2}'
bar
This prints bar
, as bar
is the content of the second field.
A double dollar sign is actually a double reference that will use the information of the first field reference to get to the other field reference. Example:
$ echo "foo bar car 1 2 3" | awk '{print $$5}'
bar
$ echo "foo bar car 1 2 3" | awk '{print $5}'
2
Here it prints bar
as $5
is dereferenced as 2
and thus $$5
is equivalent to $2
What does $$ mean in the shell?
In Bash $$
is the process ID, as noted in the comments it is not safe to use as a temp filename for a variety of reasons.
For temporary file names, use the mktemp
command.
Makefile and use of $$
Make needs to distinguish whether you want a $
to use as introducing a make-variable reference, such as ${FOOBAR}
or as a plain $ passed on to the shell. The make specification (Section Macros) says that to do the latter, you must use $$
which is replaced by a single $
and passed to the shell. In effect, your snippet reads as
for file_exe in `find . -name "zip_exe-*"`; do \
./${file_exe} -d some/unzip/path/lib; \
done
to the shell.
Style note: Iterating over file lists created by backticks is considered bad style, since it may overflow the ARG_MAX limit. Better to read the file names one-by-one with
find . -name "zip_exe-*" | \
while read -r file_exe; do \
./${file_exe} -d some/unzip/path/lib; \
done
Dollars in Makefile environment variables
Add a $$
double-dollar and double-quote it.
print_command:
@echo "$$COMMAND"
Like,
$ export COMMAND='My favourite shell is $SHELL'; make print_command
My favourite shell is $SHELL
Check out this How to Use Variables
page from the GNU
make page.
If you just add a single-quote, make
literally prints out the variable:-
e.g. with
print_command:
@echo '$$COMMAND'
$ export COMMAND='My favourite shell is $SHELL'; make print_command
$COMMAND
Because $
carries a special meaning in Makefile and that needs to be escaped. If you need make
to expand the value for the variable defined, use a value
syntax as
print_command:
@echo $(value COMMAND)
$ export COMMAND='My favourite shell is $SHELL'; make print_command
My favourite shell is /bin/bash
In the above case, the value of environment variables being expanded to /bin/bash
.
What does $ (dollar sign + left trianglular bracket) mean in a makefile?
This looks like something from a makefile, not a command line. In that case, $<
expands to the first prerequisite of the current target. That is, the .java
file that the .class
target depends on.
Four Dollar signs in Makefile
If make "secondary expansion" is enabled, $$$$
is required in order to generate a single $
in the actual output. $
is normally used to expand variables, call make functions, etc. $$
with secondary expansion enabled does something else, but otherwise it generates an actual $
in the output.
The shell that make uses to execute command-lines on Unix-like systems normally interprets $$
as expand to shell process ID. So, without secondary expansion enabled, $$$$
will turn into $$
in the output, which the shell will expand to the process ID.
(Using the shell process ID as a suffix is a simple way of trying to guarantee uniqueness of file name for a temporary file.)
How to escape 2 dollar signs inside a Makefile?
$$
in a make file is replaced by $
, try following:
curl -u 'username:pa$$$$word' https://example.com
and see Macros section in make specification.
Related Topics
Format and Then Convert Txt to CSV Using Shell Script and Awk
Convert String to Hexadecimal on Command Line
What Does $@ Mean in a Shell Script
32-Bit Absolute Addresses No Longer Allowed in X86-64 Linux
Facing an Error "*** Glibc Detected *** Free(): Invalid Next Size (Fast)"
How to Permanently Set $Path on Linux/Unix
Where Is the X86-64 System V Abi Documented
How to Exclude a Directory When Using 'Find'
Maximum Number of Threads Per Process in Linux
How to Set Environment Variables That Crontab Will Use
How to Find All Files Containing Specific Text on Linux
How to Write a Bash Script to Restart a Process If It Dies
How to Run a Script At a Certain Time on Linux
How to Delete a Newline If It Is the Last Character in a File
How to Split CSV Files as Per Number of Rows Specified
How to Compare Two Datetime Strings and Return Difference in Hours? (Bash Shell)