date command is giving erroneous output while using inside rpm spec file - linux

I have to perform some necessary steps before installing my package, such as taking back up of previous datastore snapshot.
For that purpose I'm using a %pre script as follows.
%pre
#!/bin/sh
--------
--------
stamp=`date +%Y%m%d%H%M%S`
echo ${stamp}
-------------
-------------
The output is as follows: 20161103123325OURCE
It is printing some random characters along with date. "OURCE" is not present anywhere in my spec file.
The same script works perfectly as standalone. The platform is CentOS7.

rpmbuild knows a whole set of macros. Apparently a certain macro is defined as:
%S = %SOURCE
I didn't manage to find something that tells rpmbuild not to expand that macro; but there is a way in tricking him not to do so. I know this is a little workaround, but it's the best I could come up with:
stamp=$(date '+%Y%m%d%H%M%''S')
note that I replaced the backticks with the recommanded $() invocation
I just inserted two '' to split the string in two parts; this avoids macro replacement.

If you escape the percent '%' in your date command with a second percent symbol '%%' as described at the following link, that should correct the behavior you're seeing with expanding %S to "OURCE" as you're seeing in your output.
stamp=`date +%%Y%%m%%d%%H%%M%%S`
See section "Writing a Macro" here
http://rpm.org/user_doc/macros.html

Related

How to pass multiple variables in grep

I have a json file that is download using curl. It has some information of a confluence page. I want to extract only 3 parts that downloaded information - that is page: id, status and title.
I have written a bash script for this and my constraint is that I am not sure how to pass multiple variables in grep command
id=id #hardcoded
status=status #hardcoded
echo Enter title you are looking for: #taking input from user here read title_name echo echo echo Here are details
curl -u username:password -sX GET "http://X.X.X.X:8090/rest/api/content?type=page&start=0&limit=200" | python -mjson.tool | grep -Eai "$title_name"|$id|$status"
Aside from a typo (you have an unbalanced quote - please always check the syntax for correctness before you are posting something), the basic idea of your approach would work in that
grep -Eai "$title_name|$id|$status"
would select those text lines which contain those lines which contain the content of one of the variables title_name, id or status.
However, it is a pretty fragile solution. I don't know what can be the actual content of those variables, but for instance, if title_name were set to X.Z, it would also match lines containing the string XYZ, since the dot matches any character. Similarily, if title_name would contain, say, a lone [ or (, grep would complained about an unmatched parentheses error.
If you want to match the string literally and not be taken as regular expressions, it is better to write those pattern into a file (one pattern per line) and use
grep -F -f patternfile
for searching. Of course, since you are using bash, you can also use process substitution if you prefer not using an explicit temporary file.

Linux: Replace first string in file with contents of other file containing quotes and slashes.

I have spent all day today trying to find a proper solution, but I am not able to. My problem:
I have an XML file with tags containing multiple of the same.
Example:
<TASK INSTANCE />
<WORKFLOWLINK CONDITION=""/>
<WORKFLOWLINK CONDITION=""/>
I want to add the contents of an other XML file before the first <WORKFLOWLINK. The issue I've ran into is that this file is full of double quotes and slashes. I've tried replacing them and escaping them, but to no avail.
My tries mainly culminated on something like:
sed -e "0,/<WORKFLOWLINK/ /<WORKFLOWLINK/{ r ${filename}" -e "}" ${sourcefile}
If this isn't clear enough I'll get the exact data so you can see.
For the fun of sed:
sed -e "0,/<WORKFLOWLINK/{/<WORKFLOWLINK/{r ${sourcefile}" -e"}}"
The trick is to start a new "pattern/command" pair after your first address range condition 0,/<WORKFLOWLINK/.
Two nested patterns/addresses are not understood, there must be a command after the first pattern. Using an additional pair of curlies {} does that for you.
Apart from the brain exercise to do it in sed, #EdMorton is right in recommending to use an XML-processor. Also his request for an MCVE is appropriate. I had to do some guessing to see what you want and I hope I guessed right.
The mcve should at least have included
the error message or problem description defining your problem
the initialisation of your environment variables
some sample input; not the original data
You surely would have had an answer earlier and (in case mine does not satisfy you) probably a better one by now.
So, before your next question, please take the https://stackoverflow.com/tour
GNU sed version 4.2.1
GNU bash, version 3.1.17(1)-release (i686-pc-msys)
Everyone,
Thank you for thinking with me, even if I apparently broke some rules.
I have figured out a solution, granted it is not as pretty as can be, but for a one time action it is good enough.
I have moved from a single command to a combination of first detecting the location I want to put my data:
sed -e "0,/<WORKFLOWLINK/ s/<WORKFLOWLINK/##MARKER##\n\t<WORKFLOWLINK'" which will put the marker string in the desired location.
After this I replace the marker with the contents of the file I have. I managed to make the individual statements working when I was trying to do it all in a single statement before, so I just execute them separately.
sed -e "/##MARKER##/{r ${sourcefile}" -e 'd}'

bash "echo" including ">" in the middle creating file - please explain

When I write:
echo 2*3>5 is a valid inequality
In my bash terminal, a new file named 5 is created in my directory which contains:
2*3 is a valid inequality
I want to know what exactly is going on here and why am I getting this output?
I believe it's obvious that I'm new to Linux!
Thanks
In bash, redirections can occur anywhere in the line (but you shouldn't do it! --- see the bash-hackers tutorial). Bash takes the >5 as a redirection, creates output file 5, and then processes the rest of the arguments. Therefore, echo 2*3 is a valid inequality happens, which gives you the output you see in the output file 5.
What you probably want is
echo "2*3>5 is a valid inequality"
or
echo '2*3>5 is a valid inequality'
(with single-quotes), either of which will give you the message you specify as a printout on the command line. The difference is that, within "", variables (such as $foo) will be filled in, but not within ''.
Edit: The bash man page says that the
redirection operators may precede or appear anywhere within a simple command or may follow a command. Redirections are processed in the order they appear, from left to right.
bash does the output redirection first i.e. >5 is done first and a file named 5 is created (or truncated if it already exists). The resultant file descriptor remains open for the runtime of the echo command.
Then the remaining portion, 2*3 is a valid inequality, runs as the argument to echo and standard output is saved in the (already-open) file 5 eventually.
To get the whole string as the output, use single or double quotes:
echo '2*3>5 is a valid inequality'
This is an example of output redirection. You're instructing the echo statement to, instead of writing to standard out, write to a filename. That filename happens to be "5".
You can avoid that behavior by quoting:
echo "2*3>5 is a valid inequality"

How to use a properties file that contains numbers properties in shell

This is my first question on StackOverflow. I am pretty sure it would have been answered already (it is a pretty dumb question, I think, as I just started to learn Linux scripting), but I did'nt succeed to find an answer yet.
Sorry for that.
Here is my problem: I try to use in a shell a number given in a property file, I have an error because the number is not taken "as it is".
I have a prop.properties file :
sleepTimeBeforeLoop=10
and a test.sh shell :
#!/bin/sh
. prop.properties
echo "time="$sleepTimeBeforeLoop
sleep $sleepTimeBeforeLoop
When I launch test.sh I have the following Output:
time=10
sleep: invalid time interval `10\r'
Try `sleep --help' for more information.
What I understand is that my properties files was correctly sourced, but that the property was taken as a string, with some special character to indicate the end of the line, or whatever.
How can I do to take only the "10" value?
Thank you in advance for your answer.
This is line endings issue / make sure your script files are terminated by \n (the unix way)
eg. write it in UNIX text editor or use a windows one capable of saving in "unix style"

What does "#$" mean in bash?

Say for example a script begins like this
#!/bin/bash
#$ -S /bin/bash
#$ -l hostname=qn*
and then later down the page the actual script comes into play. My question is what does the "#$" symbol mean or do?
Are you by any means running on a batch cluster? Like Sun Grid Engine? There might be special meanings in scripts intended to run as a batch job.
https://www.wiki.ed.ac.uk/display/EaStCHEMresearchwik/How+to+write+a+SGE+job+submission+script
Update:
above link blocks when used from stackoverflow.com (works from google.com)
alternatives:
http://www.cbi.utsa.edu/sge_tutorial
http://web.njit.edu/all_topics/HPC/basement/sge/SGE.html
Lines beginning with # are comments. The first line may begin with #!, but it's still a comment to bash and is merely used to indicate the interpreter to use for the file. All other lines beginning with # are absolutely unimportant to bash, whether the next character is $ or anything else.
They seem to be parameters for the Oracle (ex-Sun) Grid Engine, look at this SO question or this one.
They are heavily using these kind of comments.
Those line are important for queue systems like sbatch.

Resources