On 05/28/2015 02:41 PM, Arthur Schwarz wrote: > > So let's try this with your make rule. The lines starting with a > "+" character are the actual commands being executed by the shell: > > % make SHELL='sh -x' test3.abc > echo '#!/bin/bash' > test3.abc > + echo '#!/bin/bash' > echo "echo test3.abc $# ' [' $@ ']'>> test3.log" >> test3.abc
This is what make passed to the shell... > + echo 'echo test3.abc 0 '\'' ['\'' '\'']'\''>> test3.log' ...and this is what the shell executed, after doing shell expansions. > echo "echo I am a test script >> test3.log" >> test3.abc > + echo 'echo I am a test script >> test3.log' > > (to get snarky) I saw the problem before. The issue is that the $#/$@ > expands inside make (when test.abc: is executed and not in the shell script. > I can do this if I put the script into the appropriate directory and take > creation out of Makefile.am. I know this. I just wish there was another way. No, $# did NOT expand inside make, but inside the shell that make was running when asked to execute the commands that will create test3.abc. You were not using correct shell quoting. It sounds like you want to defer expansion of $@ not only in make, but also in the shell that make runs. Let's look more closely at your attempt: echo "echo test3.abc $# ' [' $@ ']'>> test3.log" >> test3.abc says to do shell interpolation of $# and $@ inside the double quotes, then append the resulting string to test3.abc. After executing that statement in shell, the last line in test3.abc will be: echo test3.abc 0 ' [' ']'>> test3.log Whereas if you had used different quoting, as in: echo 'echo test3.abc $# " [" $@ "]">> test3.log' >> test3.abc so that you were telling the shell to NOT interpret $, then the last line in test3.abc will be: echo test3.abc $# " [" $@ "]">> test3.log Of course, that is still underquoted, if you intend to avoid globbing/splitting on the results of $@ when executing the file test3.abc. You want the $@ to be inside double quotes. Ultimately, it sounds like you are not quite sure of how many layers of processing text will go through. So let's work backwards: First, figure out what you want in the file test3.abc. Probably something like this (and note that things are a lot easier by avoiding ' in this script): #!/bin/bash echo test3.abc "$# [ $@ ]">> test3.log echo I am a test script >> test3.log Next, figure out how to generate test3.abc using shell scripting (note that I'm using '' quoting here to suppress all expansions in the text being put in the generated file, which is why I avoided ' in the script I am generating): echo '#!/bin/bash' > test3.abc echo 'echo test3.abc "$# [ $@ ]">> test3.log' >> test3.abc echo 'echo I am a test script >> test3.log' >> test3.abc Finally, write that shell script inside a make rule (make passes everything to shell except for $, which is escaped by adding another $): test3.abc: echo '#!/bin/bash' > test3.abc echo 'echo test3.abc "$$# [ $$@ ]">> test3.log' >> test3.abc echo 'echo I am a test script >> test3.log' >> test3.abc Before you can write effective makefile rules for invoking complicated shell scripting, you first need to know the difference between '' and "" in shell quoting rules, and practice writing shell scripts that generate shell scripts to get a feel for using nested layers of quoting when generating files. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature