This question already has an answer here:
Trying to implement a loop in Makefile target
(1 answer)
Closed 1 year ago.
I am writing a Makefile for a simple projects. The Makefile should produce the README.md of the project which should include a time & date make was run.
Here's what I've got so far:
README.md:dependent_file.sh
now=$(date)
echo "Generated on $now"
clean:
rm *.md
For now, all I want my Makefile to do is append the current date to the README.md
My problem is that I cannot get the actual date-it coms up as blank.
Any help would be appreciated.
Thanks.
Each line of a recipe is executed in a separate shell, so now is not defined in the shell that executes the echo statement. You can use line continuations to join multiple physical lines into a single logical line.
README.md: dependent_file.sh
now=$$(date) \
echo "Generated on $$now"
or use a semicolon to combine both commands on a single line.
README.md: dependent_file.sh
now=$$(date); echo "Generated on $$now"
In both cases, you'll have to use $$ to prevent any expansions from happening in the Makefile before the recipes are executed.
Related
This question already has answers here:
How to store curly brackets in a Bash variable
(2 answers)
Closed 4 years ago.
I'm trying to use this variable
MediaExt="*.{mp4,mkv,avi}"
in this command
mv ${MediaSource}/${MediaExt} ${UploadDir}
but it doesn't seem to work.
Could someone help me, please? Thanks!
A command in bash is parsed in several passes. The pass that decides whether globbing (expanding *, or *.{mp4,mkv,avi}) should be performed, is occurring before the pass that expands the variables. Once the variables are expanded, there are candidate for globbing, but the decision that no globbing is required has already been made
It will work if you write the expression as:
mv ${MediaSource}/*.{mp4,mkv,avi} ${UploadDir}
You'll probably find some advise that you can use eval. Please don't!
This:
eval mv ${MediaSource}/${MediaExt} ${UploadDir}
will execute as you intended, but eval can be dangerous if you don't control the values of the variables. For example, if UploadDir could be set to:
UploadDir="somedirectory; rm -rf ~"
then eval will execute your request as two statements and remove all your files.
This question already has answers here:
Bash mkdir and subfolders [duplicate]
(3 answers)
Closed 6 years ago.
I'm sure this question has been asked elsewhere but I can't seem to phrase it in a way that returns a useful Google result.
I am creating a dozen directories that all have the same root path and I don't want to have to cd into it to be able to make these directories. The current command looks like something like, which is awful and repetitive:
$ mkdir frontend/app/components/Home frontend/app/components/Profile \
frontend/app/components/Post frontend/app/components/Comment
An ideal syntax would be something along the lines of:
$ mkdir frontend/app/components/{Home, Profile, Post, Comment}
Is there something like this already that I just haven't found? I don't want to have to run a for loop just to make a few directories.
Your wish is granted :-).
mkdir doesn't know and doesn't have to, but shells like bash or zsh understand the syntax {...,...,...}.
Just remove the spaces from your "along the lines of" and it works:
mkdir frontend/app/components/{Home,Profile,Post,Comment}
The shell will expand it to
mkdir frontend/app/components/Home frontend/app/components/Profile frontend/app/components/Post frontend/app/components/Comment
Since it is done by the shell, it works with any command.
Remove spaces around comma and use -p option:
mkdir -p frontend/app/components/{Home,Profile,Post,Comment}
This question already has answers here:
Bash: using the result of a diff in a if statement
(5 answers)
Closed 7 years ago.
I'm using a diff operation to check a couple of files, but am wondering if I can simultaneiously use it to trigger an event (e.g. echo-ing a line to terminal etc) without having to 'manually' check for the existence of the output report.
I had thought about using the report creation as a trigger, but as far as I know the file would be created regardless, it would just be empty in the event of no differences?
Basically, is it possible to have diff output a file, whilst inside an if statement, to keep my bash profile and the script itself as tidy as possible?
(If it helps, this is a follow on question to the wonderful help I received in this question: Notifications on next ssh login)
e.g. something to this effect?:
if [ diff filex filey > report.txt == true ]
# So the report.txt is created but the 'state' of
# the diff query is preserved and evaluated...
then echo "Files are different"
else
break
fi
Hope that makes sense.
This is in Ubuntu bash FYI.
Yes, diff exits with a status of 0 if there is no diffs (that's shell for "true"), so you can do it like this:
if ! diff <file1> <file2>
then
do the thing when there are diffs
else
do the thing when all is same
fi
This should work even if you redirect the output.
This question already has answers here:
How can I debug a Bash script? [closed]
(12 answers)
Closed 8 years ago.
For example, I'm writing a bunch of iptables rules in a bash script. When I run the script, shell says iptables: No chain/target/match by that name. I don't know what's going on so I copy and paste every line into shell and run them separately to figure out which line is causing trouble. BTW. it turns out that I put "OUTUT" instead of "OUTPUT" in one rule.
Is there anyway that shell can tell me like [line 53]: iptables: No chain/target/match by that name., so I know where the problem is?
I'm not bash expert but what I was doing is adding echo with information regarding the progress and read (wait until keypressed) that will let me do the process step by step.
Nearly all programs return success and error conditions. You can include error checking for each program your script calls, and take appropriate action on error (like undoing previous work, exiting out, etc). This is particularly useful if line 4 should never execute if line 3 fails.
The exit status of the program you just called is stored in $? .
Example (pseudocode - you'll need to modify the syntax to be correct)
Iptables foo bar baz; if ($? != 0) echo 'failed to update iptables' && exit 1; fi
additionally, you can turn on various levels of tracing with set -f , set -v , and set -x . See the links below for full details.
http://tldp.org/LDP/abs/html/exit-status.html
http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html
This question already has answers here:
What do $< and $# represent in a Makefile?
(2 answers)
Closed 7 years ago.
I am trying to understand a simple command-line string that executes Javac and passes it some simple arguments. The complete command line is:
javac -d $(OUTPATH) -sourcepath $(SOURCEPATH) $<
Everything in this line is straightforward and understandable to me except for the final tokens: $<.
What do these tokens mean?
ADDENDUM: Indeed, the commenters are correct. This line occurs within a makefile. It is obvious to me now, but not when I wrote this question, that a makefile is passed to make and is not a shell script.
Please note: What do $< and $# represent in a Makefile? also discusses this (I did not see it when I looked for previous questions about this).
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.