If multiple IFs are null, do something - bash

I am looking for suggestions for a solution and on best approaches to handle figuring out if multiple IFs are null.
I have:
if [ -n "$sfcompname" ]; then
echo $sfcompname
fi
if [ -n "$sfcompip" ]; then
echo $sfcompip
fi
if [ -n "$lacompname" ]; then
echo $lacompname
fi
if [ -n "$lacompip" ]; then
echo $lacompip
fi
.. I'm sure that can be done better, but my main problem at the moment is trying to then say:
if (all those IFs) = null
echo "Please check the name you entered and try again"

Somewhat silly, but should work
if ! [[ ${sfcompname}${sfcompip}${lacompname}${lacompip} ]]
then
echo "Please check the name you entered and try again"
fi

You can use another variable for this which you initialise to a value and then change if any of the if statements fire. Then at the end, if it hasn't changed, then you know that none of them fired. Something like this will suffice:
fired=0
if [ -n "$sfcompname" ]; then
echo $sfcompname
fired=1
fi
if [ -n "$sfcompip" ]; then
echo $sfcompip
fired=1
fi
if [ -n "$lacompname" ]; then
echo $lacompname
fired=1
fi
if [ -n "$lacompip" ]; then
echo $lacompip
fired=1
fi
if [[ ${fired} -eq 0 ]] ; then
echo 'None were fired'
fi

Another possibility is to use the variable check short-cut:
name="$sfcompname$sfcompip$lacompname$lacompip"
${name:?"Please check the name you entered and try again"}
This will exit the program if none of the variables are set. The message is optional, it overrides the standard "parameter null or not set".

Related

Bash - Check of multiple environment variables and list all missing

I'm working on a few scripts where I need to check for a few environment variables and list all the ones missing. I'm seeing a lot of posts where it would check for one and exit.
if [ -z "$BLAH" ]; then
echo "Missing BLAH"
exit 1
fi
However, I would like to print all the missing ones and then exit if anything is not set. I'm doing something like this right now, Is there any more elegant way to do this?
function check_env_vars {
status=0
for name in $*; do
value="${!name}"
echo "$value"
if [[ -z "$value" ]]; then
echo "$name environment variable must not be empty"
status=1
fi
done
return $status
}
if [[ check_env_vars "BLAH" "BLAH1" "BLAH2" -ne 0 ]]; then
exit 1
fi
Appreciate any thoughts or ideas.
if already checks the exit status; that's what it does with [[ ... ]] in the first place.
if ! check_env_vars "BLAH" "BLAH1" "BLAH2"; then
exit 1
fi
That said, bash already has syntax for verifying that a variable is set and non-null:
check_vars () {
for name; do
: ${!name:?$name must not be empty}
done
}

Passing argument function not working

valid()
{
if [[ "$1" = "0" ]]; then
echo "Pass a file name as argument"
exit 1
fi
}
valid
if [ -f $1 ]; then
echo "$1 exists"
else
echo "$1 doesnt exist"
fi
In the above example, the vaild() function is not working, why so? When a valid argument is passed it checks the file name and prints but when not passed, it prints "exists".
You should check for null strings when taking a string as argument and not compare it with 0. You also need to pass the argument to the valid function.
valid()
{
if [ -z "$1" ]; then
echo "Pass a file name as argument"
exit 1
fi
}
valid $1
if [ -f "$1" ]; then
echo "$1 exists"
else
echo "$1 doesnt exist"
fi
Instead of if [[ "$1" = "0" ]]; then you can simply change it to:
if [[ "$1" = "" ]]; then
and it will work as expected.
And you need to double quote your variables inside [ ] syntax too. [[ ]] syntax can handle white spaces without needing any double quotation, but [ ] can't.

How to check if multiple variables are defined or not in bash

I want to check, if multiple variable are set or not, if set then only execute the script code, otherwise exit.
something like:
if [ ! $DB=="" && $HOST=="" && $DATE=="" ]; then
echo "you did not set any variable"
exit 1;
else
echo "You are good to go"
fi
You can use -z to test whether a variable is unset or empty:
if [[ -z $DB || -z $HOST || -z $DATE ]]; then
echo 'one or more variables are undefined'
exit 1
fi
echo "You are good to go"
As you have used the bash tag, I've used an extended test [[, which means that I don't need to use quotes around my variables. I'm assuming that you need all three variables to be defined in order to continue. The exit in the if branch means that the else is superfluous.
The standard way to do it in any POSIX-compliant shell would be like this:
if [ -z "$DB" ] || [ -z "$HOST" ] || [ -z "$DATE" ]; then
echo 'one or more variables are undefined'
exit 1
fi
The important differences here are that each variable check goes inside a separate test and that double quotes are used around each parameter expansion.
If you are ok with writing a function for this purpose, it can be pretty convenient.
This solution uses the ${!VAR_NAME} syntax to check whether the variable is empty and has the added benefit of telling you which variable names are empty.
check_vars()
{
var_names=("$#")
for var_name in "${var_names[#]}"; do
[ -z "${!var_name}" ] && echo "$var_name is unset." && var_unset=true
done
[ -n "$var_unset" ] && exit 1
return 0
}
# Usage for this case
check_vars DB HOST DATE
echo "You are good to go"
I wound up using variable-variables to loop through an easily managed HEREDOC list of variable names:
# Ensure non-empty values.
# Loop through HEREDOC, test variable-variable isn't blank.
while read var; do
[ -z "${!var}" ] && { echo "$var is empty or not set. Exiting.."; exit 1; }
done << EOF
KUBE_NAMESPACE
DOCKER_REGISTRY
DOCKER_DEPLOY_USER
DOCKER_DEPLOY_PASSWORD
DOCKER_DEPLOY_EMAIL
EOF
You can check it also by put the variables name in a file
DB=myDB
HOST=myDB
DATE=myDATE
then test them if currently empty or unset
#!/bin/bash
while read -r line; do
var=`echo $line | cut -d '=' -f1`
test=$(echo $var)
if [ -z "$(test)" ]; then
echo 'one or more variables are undefined'
exit 1
fi
done <var.txt
echo "You are good to go"
Nice solution from #joe.still !
improvement is to exit after checking all variables
i=0
while read var; do
[ -z "${!var}" ] && { echo "$var is empty or not set. Exiting.."; let i=i+1; }
done << EOF
KUBE_NAMESPACE
DOCKER_REGISTRY
DOCKER_DEPLOY_USER
DOCKER_DEPLOY_PASSWORD
DOCKER_DEPLOY_EMAIL
EOF
if [ $i -gt 0 ]; then
echo $i
echo "exiting"
exit 1
fi
Good Day Everyone.
I've personally used this method in my bash scripts. Verified works on bash 4.4 and later in Ubuntu, openSUSE, and ClearLinux.
Can RHEL|CentOS|Alma and Arch Based users let me know it it works fine for you?
( [ "$VAR1""$VAR2""$VAR3""$VAR4""$VAR5" ] && echo -e " Warning: StackIsNotClear" ) || { echo -e " GoodNews: StackIsClear"; }

Check config files for key value pair and prompt message if some values are not set

I would like to read a configuration file and check all the key value pairs and in case some values are not set prompt user for those particular key value is not set.
I am trying to achieve this by sourcing in the configuration file and then checking the keys as appropriate:-
if [ ! -r "${file}" ]; then
echo "Lfile is not readable kindly verify"
elif [ ! -r "${file1}"]; then
echo "file1 is not readable kindly verifry"
elif [ -z $key ];then
echo "KEY_ is not set"
elif.....
.....
fi
however in this case the issue I am having is, it will list all the key value paris and move further in script however I want it to abort in case some values are not set and prompt that value on terminal
if I use exit in between for example:-
if [ ! -r "${file}" ]; then
echo "Lfile is not readable kindly verify"
exit
elif [ ! -r "${file1}"]; then
echo "file1 is not readable kindly verify"
exit
it will only prompt one undefined value at a time.
So my question is how I can enable my script to check the entire key value pair and list the all keys which are not set.
You can write your script like this:
if [ ! -r "${file}" ]; then
echo "Lfile is not readable kindly verify"
exit 1
elif [ ! -r "${file1}"]; then
echo "file1 is not readable kindly verify"
exit 1
fi
# list of all keys you want to check for
allKeys=("key1" "key2" "key3" "key4")
missing=()
for k in ${allKeys[#]}; do
[[ -z "${!k}" ]] && missing+=($k)
done
if [[ ${#missing[#]} -gt 0 ]]; then
printf "Missing keys are: %s\t" "${missing[#]}"
echo ""
exit 1
fi
You could use an array
arr=()
key1="hi"
key2="bye"
arr+=($key1)
arr+=($key2)
echo ${arr[#]}

Printing out wrong output in bash

Hi I am writing a program that ask the user to enter a directory, contact name and number.
What the program does is that it create a .contact file like <contactname>.contact and adds the contact number inside it. If the file already exists in the specified directory, then the program creates a new file called contact(1).contact, if that exists then contact(2).contact etc.
When a contact(1).contact already exists, I want the program to create contact(2).contact, but the program creates contact(1)(2).contact file instead. I don't know what the problem is. Any help would be appreciated ! :)
The code I have written so far in bash.
#!/bin/bash
directory=
if(($# == 0))
then
echo -n "Please enter directory path:"
read directory
cd $directory
echo -n "Please enter contact name:"
read name
echo -n "Please enter contact number:"
read number
else
directory=$1
cd ${directory}
name=$2
number=$3
fi
if [ -e $name.contact ];
then
exists=1
count=1
while [ $exists -eq 1 ];
do
name=$name\($count\)
count=$(($count+1))
if [ ! -f $name.contact ];
then
exists=0
fi
done
echo $number > $name.contact
name=5
else
echo $number > $name.contact
fi
You keep appending to the modified name. Use the original name instead.
And that condition...
origname="$name"
while [ -f $name.contact ];
do
name="$origname($count)"
count=$(($count+1))
done
Probably you need to save original name:
Try changing that part:
while [ $exists -eq 1 ];
do
name=$name\($count\)
count=$(($count+1))
if [ ! -f $name.contact ];
then
exists=0
fi
done
to this:
origname=$name
while [ $exists -eq 1 ];
do
name=$origname\($count\)
count=$(($count+1))
if [ ! -f $name.contact ];
then
exists=0
fi
done

Resources