Please explain what following code snippet could do in Perl script,
if (! -e '/etc/httpd') {
print "Something";
}
I can't find exact scenario or condition that makes this condition 'true'. This question also not explain much regarding this.
Exactly, what -e switch does in this condition?
The -e filename is one of filetests ("-X"), which checks for existence of a "file" (an entry, not only a plain file).
So the condition tests whether /etc/httpd does not exist, since the unary operator ! does logical negation of what is on its right-hand side using Perl's rules for truth and falsehood.
Related
How to test if a string variable in Robot Framework is empty?
My first naïve attempt looked like this:
Run Keyword If ${myVar}!=${EMPTY}
but it failed:
Evaluating expression '!=' failed: SyntaxError: unexpected EOF while parsing (, line 1)
I then found this issue at Github but it didn't suggest a solution, just that the error message was unclear. An alternative solution was presented here:
${length}= Get Length ${Portfolio_ste}
Run Keyword If ${length} Go To Edit Portfolio
but is this really the best practice?
(The context is that I use a variable argument list and if a certain variable contains a value something should be done, otherwise just ignore it)
The expression needs to be a valid python expression after variable substitution. Assuming for the moment that myVar might be something like the number 42, your expression would end up looking like this after substitution:
Run Keyword if 42!=
When comparing against the empty string you need to add quotes to guarantee that the expression is a proper python expression after substitution. For example:
Run Keyword If "${myVar}"!="${EMPTY}"
Try Get Variable Value. It solved my problem.
for my $item (#array) {
if (index($item, '$n') != -1) {
print "HELLO\n";
}
}
Problem is: Perl critic gives below policy violation.
String may require interpolation at line 168, near '$item, '$n''. (Severity: 1)
Please advise how do I fix this?
In this case the analyzer either found a bug or is plain wrong in flagging your code.
Are you looking for a literal "$n" in $item, or for what $n variable evaluates to?
If you want to find the literal $n characters then there is nothing wrong with your code
If you expect $item to contain the value stored in $n variable then allow it to be evaluated,
if (index($item, $n) != -1)
If this is indeed the case but $n may also contain yet other escaped sequences or encodings which you need as literal characters (so to suppress their evaluation) then you may need to do a bit more, depending of what exactly may be in that variable.
In case you do need to find characters $ followed by n (what would explain a deliberate act of putting single quotes around a variable) you need to handle the warning.
For the particular policy that is violated see Perl::Critic::Policy::ValuesAndExpressions
This policy warns you if you use single-quotes or q// with a string that has unescaped metacharacters that may need interpolation.
To satisfy the policy you'd need to use double quotes and escape the $, for example qq(\$n). In my opinion this would change the fine original code segment into something strange to look at.
If you end up wanting to simply silence the warning see documentation, in Bending The Rules
A comment. The tool perlcritic is useful but you have to use it right. It's a static code analyzer and it doesn't know what your program is doing, so to say; it can catch bad practices but can't tell you how to write programs. Many of its "policies" are unsuitable for particular code.
The book that it is based on says all this very nicely in its introduction. Use sensibly.
When I look at the question where this comes from it appears that you are looking for index at which substrings were matched, so you need the content of $n variable, not literal "$n". Then perlcritic identified a bug in the code, good return for using it!
I have the following string being exported from a program that is analyzing the certificate on a website which will be part of a bugfix analysis
CERT_SUMMARY:127.0.0.1:127.0.0.1:631:sha256WithRSAEncryption:
/O=bfcentos7-test/CN=bfcentos7-test/emailAddress=root$bfcentos7-
test:/O=bfcentos7-test/CN=bfcentos7-test/emailAddress=root$bfcentos7-
test:170902005715Z:270831005715Z:self signed certificate
(consider output above to be a single line)
What I need is the best way in a bash shell to extract the sha256WithRSAEncryption. This could be anything like sha384withRSAEncryption or something else.
After the CERTSUMMARY it will always be 127.0.0.1:127.0.0.1:portnum above its port 631, but it could be anything.
This runs internally on a system and returns this string along with SSL or TLS (not pictured)
Here is another example of a return
CERT_SUMMARY:127.0.0.1:127.0.0.1:52311:sha256WithRSAEncryption:
/CN=ServerSigningCertificate_0/name=Type`Administrator
/name=DBName`ServerSigningCertificate_0:/C=US/CN=BLAHBLAH/
ST=California/L=Address, Emeryville CA 94608/O=IBM BigFix Evaluation
License/OU=Customer/emailAddress=blahblay#gmail.com/name=
Hash`sha1/name=Server`bigfix01/name=CustomActions`Enable
/name=LicenseAllocation`999999/name=CustomRetrievedProperties`Enable:
170702212459Z:270630212459Z:unable to get local issuer certificate
Thanks in advance.
Novice at shell programming, but learning!!
you need the best way and yet do not seem to provide the best description - "This could be anything like sha384withRSAEncryption or something else."
Given the examples, the string you are looking for is the 4th, when : is a separator, so the command should be OK:
cut -f4 -d":"
If the output string has a strict length format, one easy option is the 'cut' command with -c. This is not the case though since there is a port number.
CERT_SUMMARY:127.0.0.1:127.0.0.1:631:sha256WithRSAEncryption:
as #cyrus pointed out, this was as simple as picking the right column with awk... I am learning.
This worked
awk -F ":" '/CERT_SUMMARY/ {print $5}'
Thanks for the help!!
| sed -E 's/^([^:]*:){4}([^:]*):.*/\2/'
Regular expressions are you friend. If there is one thing one really should be familiar with if one needs to do a lot of string parsing or string processing, it's definitely regular expressions.
echo 'CERT_SUMMARY:127.0.0.1:127.0.0.1:52311:sha256WithRSAEncryption:
/CN=ServerSigningCertificate_0/name=Type`Administrator
/name=DBName`ServerSigningCertificate_0:/C=US/CN=BLAHBLAH/ST=California
/L=Address, Emeryville CA 94608/O=IBM BigFix Evaluation
License/OU=Customer/emailAddress=blahblay#gmail.com/name=Hash`sha1
/name=Server`bigfix01/name=CustomActions`Enable
/name=LicenseAllocation`999999
/name=CustomRetrievedProperties
`Enable:170702212459Z:270630212459Z:unable to get local issuer
certificate'
| sed -E 's/^([^:]*:){4}([^:]*):.*/\2/'
prints
sha256WithRSAEncryption
It's probably a bit overkill here, but there is almost nothing that cannot be done with regular expressions and as you have also built-in regex support in many languages today, knowing regex is never going to be a waste of time.
See also here to get a nice explanation of what each regex expression actually means, including an interactive editing view. Basically I'm telling the regex parser to skip the first 4 groups consisting of any number of characters that are not :, followed by a single : and then capture the 5th group that consists of any number of characters that are not : and finally match anything else (no matter what) to the end of the string. The whole regex is part of a sed "replace" operation, where I replace the whole string by just the content that has been captured by the second capture group (everything in round parenthesis is a capture group).
Could you please use following also, not printing it by field's number so if your Input_file's sha256 location is a bit here and there too than shown one then this could be more helpful too.
awk '{match($0,/sha.*Encryption:/);if(substr($0,RSTART,RLENGTH)){print substr($0,RSTART,RLENGTH-1)}}' Input_file
Pipe the output to:
awk ‘BEGIN{FS=“:”} {print $5}’
You could also take a step back to the openssl x509 command 'name options'. Using sep_comma_plus avoids the slashes in the output and therefore your regex will be simpler.
I have this code...
if $hostname in $var_slave {
file {
"/var/spool/cron/mysql":
ensure => present,
owner => $mysqlUser,
group => $mysqlGroup,
mode => "0600",
source => 'puppet:///modules/eikonappdbcron/mysql-slave',
}
}
I want a way of checking if a value is not in a file.
I tried "if $hostname not in $var_master" but this doesn't work. After doing some research I believe I need to use an "!". I can't get the syntax correct.
Puppet does not have a single, combined "not in" operator. Instead, it has the in operator, and it has a general-purpose boolean negation operator (!). You can use these together to write a compound expression that evaluates the condition you want.
If you already realized that, then perhaps you ran into a problem with operator precedence. The negation operator has the higher precedence than does in. Indeed, ! has the highest precedence of any Puppet operator, so if its operand is intended to be a binary expression then you must enclose the operand in parentheses.
Thus, the negation of the boolean expression
$hostname in $var_master
is
! ($hostname in $var_master)
I am trying to perform a simple integer comparison in bash, which I am new to using, and my methods are causing an error. Any advice would be appreciated.
My basic logic is that I am reading in hurricane track points. There may be multiple entries for the same track_id, with different pressure values. What I want to do is store only one entry per track_id into the array track_id_poly; the case with the lowest pressure. So I am looping through each line, and attempting to compare the current pressure (for $int), with the previous track pressure ($int - 1), and if it is lower, replace the previous array value with the new lower pressure. I hope that makes sense. My code is below.
int=0
while read track_id ppres_inter
do
printf -v pres_inter "%.0f" "$pres_inter"
echo pressure $pres_inter
case $int in
0)
Track_id_poly[$int]=$track_id
Pres_inter_poly[$int]=$pres_inter
((int=int+1)) ;;
*)
if [[ $track_id == ${Track_id_poly[$int-1]} ]]
then
if (( $pres_inter -lt ${Pres_inter_poly[$int-1]} ))
then
Track_id_poly[$int-1]=$track_id
Pres_inter_poly[$int-1]=$pres_inter
fi
else
Track_id_poly[$int]=$track_id
Pres_inter_poly[$int]=$pres_inter
((int=int+1))
fi ;;
esac
done <$file_poly
int_poly=$int
echo Number of polygon crossings from set $i is $int_poly
The line that is causing me problems is the integer comparison for $pres_inter.
if (( $pres_inter -lt ${Pres_inter_poly[$int-1]} ))
I get the following error:
line 41: 96800 -lt 98759 : syntax error in expression (error token is "98759 ")
Any tips to fix this problem would be appreciated. Probably a simple fix!
The ((...)) operator does not accept the same syntax as the test, [..], or [[...]] commands. To compare two numbers in ((...)), you would use actual > or < symbols:
$ (( 4 > 2 )) && echo '4 is bigger!'
4 is bigger!
See the ARITHMETIC EVALUATION section of the bash(1) man page for more information (or here).
My shell scripting is rusty for good reason but you may to review that line and either use "[[ ]]" instead of "(( ))", or use "<" instead of "-lt" . See bash: double or single bracket, parentheses, curly braces
However, the main tip I'd give to you is to stop using bash for things that involve anything beyond simple program invocation and switch to a scripting language (Perl, Python, ...) because it won't only be more robust, it'll be easier to get the job done and it'll also run faster.
In bash "((expression))" is differently evaluated. So you cannot use the operator "-lt", instead you can use the normal operator <.
For further info see the man page of bash:
((expression))
The expression is evaluated according to the rules
described below under ARITHMETIC EVALUATION. If the value of the
expression is non-zero, the return status is 0; otherwise the return
status is 1. This is exactly equivalent to let "expression".
And the paragraph ARITHMETIC EVALUATION explains further possibilities.