I wrote a shell script(beginner), which works fine but it includes a number of parameters.
I assign the value to them as show below.
url=$2
name=$3
ipadd=$5
netmask=$6
vlanid=$4
vlname=$7
Is there is any better approach, I can use ?
Thanks.
You can use read instead of multiple assignments:
f=$'\6' # or any other control character
IFS=$f read -d'' -r _ url name vlanid ipadd netmask vlname _ < <(printf "%s$f" "$#")
_ will ignore $1 and anything after $8.
The only way I would see really doing a better job would be to change to a --flag=value setup, if only to not make the order of arguments as important.
./myscript.sh --url=http://www.example.com --ip=10.42.56.23 --netmask=24
This would then require parsing each argument for the --flag part, then if it is found splitting the variable at the = and setting the value of your real internal value. Worth it for something you are shipping out to users, but maybe not so much for something you are using for yourself.
Related
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 2 variables that I want to use to derive a 3rd variable:
export REGION_NAME=phx
export phx_url=https://www.google.com
I am trying to do the following:
echo "$((${REGION_NAME}_url))"
And I get the following error:
-sh: https://www.google.com: syntax error in expression (error token is "://www.google.com")
All I am trying to do is to derive an environment variable from an other one but it does not work simple like that. I think it has to be escaped and could not find anything online.
Thanks in advance for the help.
$((...)) is arithmetic expansion. You didn't mean that. Try normal variable expansion (with indirection) instead.
REGION_NAME=phx
phx_url=https://www.google.com
R_VAR=${REGION_NAME}_url
echo "${!R_VAR}"
One possible solution is using eval like:
var="phx"
eval "${var}_url='some'"
echo $phx_url #prints "some"
But, I not recommending this (because the eval could be pretty dangerous).
Instead of use associative arrays (aka hash variable), like:
declare -A urls
var="phx"
urls[$var]="some2"
echo "${urls[phx]}" #prints "some2"
I don't know exactly how to ask this in English, but I want to have the value of a variable as a new variable...
The script also has a loop with increasing numbers, and in the end I want to have the variables VAR1, VAR2 etc.
I'm trying this:
COUNT=$(echo 1)
DEFINE=$(echo VAR$COUNT)
$DEFINE=$(echo gotcha!)
When I try this way, I have this error message:
~/script.sh: line n: VAR1=gotcha!: command not found
I played a bit around with brackets and quotation marks, but it didn't work... any solutions?
The problem is that bash expects a command as a result of expansions, not an assignment. VAR1=gotcha! is not a command, hence the error.
It would be better to use an array:
COUNT=$(echo 1)
VAR[COUNT]='gotcha!'
echo ${VAR[COUNT]}
I guess $(echo 1) stands for a more complex command, otherwise you can just use COUNT=1.
You can use declare to create such a "dynamic" variable, but using an array is probably a better choice.
COUNT=1
DEFINE="VAR$COUNT"
declare "$DEFINE=gotcha"
I have a bash scripting question. I am trying to create the following code, however, it does not work properly. This leads me to wonder if it is even possible. I hope someone on here can figure it out.
MYSQL_DB_MyDatabase_USERS_username_PASSWORD=Password
DATABASE_NAME=MyDatabase
DATABASE_USER=username
DATABASE_PASS_TEMP=MYSQL_DB_${DATABASE_NAME}_USERS_${DATABASE_USER}_PASSWORD
echo $DATABASE_PASS_TEMP
I would want the output to be "Password" (the original variable). I am getting an error and I know I have incorrect syntax. I have googled around and found that using one variable in the variable name, one would use echo "${!DATABASE_PASS_TEMP}", but that does not work when using two dynamic variables. Thanks in advance for any help you can give.
Use BASH's variable indirection:
echo "${!DATABASE_PASS_TEMP}"
Password
Using an associative array would tidy things up some:
declare -A MYSQL_DB_PASSWORDS=(
[MyDatabase,username]=Password
)
DATABASE_NAME=MyDatabase
DATABASE_USER=username
DATABASE_PASS_TEMP=${MYSQL_DB_PASSWORDS["$DATABASE_NAME","$DATABASE_USER"]}
echo "$DATABASE_PASS_TEMP"
Password
Normally when a parameter is passed to a shell script, the value goes into ${1} for the first parameter, ${2} for the second, etc.
How can I set the default values for these parameters, so that if no parameter is passed to the script, we can use a default value for ${1}?
You can't, but you can assign to a local variable like this: ${parameter:-word} or use the same construct in the place you need $1. this menas use word if _paramater is null or unset
Note, this works in bash, check your shell for the syntax of default values
You could consider:
set -- "${1:-'default for 1'}" "${2:-'default 2'}" "${3:-'default 3'}"
The rest of the script can use $1, $2, $3 without further checking.
Note: this does not work well if you can have an indeterminate list of files at the end of your arguments; it works well when you can have only zero to three arguments.
#!/bin/sh
MY_PARAM=${1:-default}
echo $MY_PARAM
Perhaps I don't understand your question well, yet I would feel inclined to solve the problem in a less sophisticated manner:
! [[ ${1} ]] && declare $1="DEFAULT"
Hope that helps.