What Is the Meaning of a Double Dollar Sign in Bash/Makefile

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



Leave a reply



Submit