"if [ -z $variable ]" in a shell script is not recognising my variable - linux

When I run the following script it keeps defaulting to the else statement and I'm not sure why. I have even included an echo $workflow which showed me the name that I was expecting to see but it still keeps defaulting to the else statement.
I've tried including an export namecheck=$workflow to see if that was the issue but it still gave the same end result
#!/bin/sh
read -p "Enter the workflow name: " workflowName
workflowName=${workflowName}
curl --request GET --url https://website.com > workflowjson.txt
workflow=$(jq -r .metadata.name workflowjson.txt)
echo $workflow
if [ -z "$workflow" ] then
echo "Workflow is Valid"
else
echo "Workflow is not valid"
fi

man test shows
-z STRING the length of STRING is zero
The code outputs Workflow is Valid when the workflow is empty.
Switch the then and else parts, or negate the condition (use -n instead of -z).

try taking the quotes out around workflow and put then in a separate line
if [ -z $workflow ]
then
echo "Workflow is Valid"
else
echo "Workflow is not valid"
fi

Related

How to get the output of if condition on terminal

I have this example and i want to get on screen both condition and good
Code:
if [ `echo condition` ]; then echo good; fi
The output that i want to get:
condition
good
The output that i got:
good
As the command echo condition will be replaced with another command. The if statement must check the return code of the condition command.
Simply store it in a variable:
cond=$(echo condition)
if [ "$cond" ] ; then
echo "$cond"
echo good
fi
Do not use backticks anymore nowadays.
Store the output of your sub shell in a variable:
if condition=$(echo condition); then
echo "$condition"
echo good
fi
If you want to return the exit value of the sub shell, you have to write a function:
get-condition-result()
{
local condition
local result
if condition=$(echo condition); then
result=$?
echo "$condition"
echo good
else
result=$?
fi
return "$result"
}
Solution found here: https://stackoverflow.com/a/13343457/12953642
You can run your command without any additional syntax. For example, the following checks the exit code of grep to determine whether the regular expression matches or not:
if echo condition
then
echo "good"
fi
if echo "condition" && curl
then
echo "good"
else
echo "error in command"
fi
Output:
condition
good
condition
curl: try 'curl --help' or 'curl --manual' for more information
error in command

Why doesn't string comparison with wildcards work properly?

I wrote this shell code, but it doesn't get the good output.
Even though the $csoport gets the "...: No such user" output, id doesn't echoes the following line I wrote there.
read felhasznalo
while [ "$felhasznalo" != "exit" ]
do
csoport=`groups $felhasznalo`
echo "$csoport"
if [[ "$csoport" == *": No such user"* ]] ; then
echo -n "Nincs ilyen felhasznalo a rendszerben"
else
echo "$csoport"
fi
echo -n "Felhasznalo: "
read felhasznalo
done
You shouldn't try to match the error messsage since you only care if groups fails. You ought to do:
if ! csoport=$(groups "$felhasznalo"); then
printf "Nincs ilyen felhasznalo a rendszerben"
else
echo "$csoport"
fi

How to read two input values in bash?

I am writing a bash script which takes multiple user inputs. Before the script will take any action, I want to ensure that all values have been added by a user.
#/bin/bash
read -p "Please enter the domain Name: " domain
read -p "Please Enter path where you want to save your result: " path
if [[ -z "$domain" && "$path"]]; then
echo "You have not entered the Domain Name"
exit 1
else
echo "Do Something Here"
fi
I have checked with 1 user input, working fine, but when trying with 2 user inputs, I am getting an error.
./test.sh: line 5: unexpected token `;', conditional binary operator expected
./test.sh: line 5: syntax error near `;'
./test.sh: line 5: `if [[ -z "$domain" && "$path"]]; then'
Thanks!
Because you're using the [[ double brackets, you can use || to test if either of your conditions is true. In this case, your code would look like this:
#!/usr/bin/env bash
read -p "Please enter the domain Name: " domain
read -p "Please Enter path where you want to save your result: " path
if [[ -z "$domain" || -z "$path" ]]; then
echo "Either you have not entered the Domain Name, or you have not entered the path."
exit 1
else
echo "Do Something Here"
fi
Note that spaces around the brackets are necessary.
As others have pointed out, errors should be specific, so you should consider something like this:
if [[ -z "$domain" ]]; then
echo "You have not entered the Domain Name"
exit 1
elif [[ -z "$path" ]]; then
echo "You have not entered the path"
exit 1
fi
echo "Do something here"
It's a bit more verbose but gives the user more specific feedback.
You are getting syntax error because you forgot to put a space between "$path" and ] (bash uses spaces as delimiters).
If you want to fail when at least one condition is wrong, you should use the || (OR) operator.
#/bin/bash
read -p "Please enter the domain name: " domain
read -p "Please enter the path where you want to save your result: " path
if [[ -z "$domain" ]] || [[ -z "$path" ]] ; then
echo "You didn't enter the domain name or the save path"
exit 1
else
echo "Do something here"
fi

bash - returning value based on process condition

i stumbled in a confusing way of conditionally returning value based on variable. I would like to check if process is successful then echo "process success", but if it's failed, i want to check specific error message then return the error message,
ERRMSG="$(cd /nonexist 2>&1)"
if [ $? -ne 0 ]
then
if [ -z "$ERRMSG|grep -o 'No such file or directory'|head -1" ]
then
echo "empty" >> $FQLOGNAME
else
echo $ERRMSG|grep -o 'No such file or directory'|head -1 >> $FQLOGNAME
fi
else
echo "success" >> $FQLOGNAME
fi
Please advice,
Thanks
You don't need to use grep to check if a string contains a substring. The built-in pattern matching in Bash is sufficient. This code should do something close to what you want:
if ERRMSG=$(cd /nonexist 2>&1) ; then
echo 'process success'
elif [[ $ERRMSG == *'No such file or directory'* ]] ; then
echo 'No such file or directory'
else
echo 'empty'
fi >> "$FQLOGNAME"
See the Conditional Constructs section of the Bash Reference Manual for details of the pattern matching capabilities of [[...]].
I've retained the ERRMSG and FQLOGNAME variables, but note that it's best to avoid ALL_UPPERCASE variable names. There is a danger that they will clash with environment variables or Bash builtin variables. See Correct Bash and shell script variable capitalization.
To find error messages defined by a pattern in multi-line error messages, and only print the first one, you can use regular expression matching (=~) in [[...]]. To provide a concrete example, this code assumes that error messages consist of 'ERROR' followed by one or more spaces followed by a decimal number:
# Example function for testing
function dostuff
{
printf 'Output line A\n'
printf 'Encountered ERROR 29\n' >&2
printf 'Output line B\n'
printf 'Encountered ERROR 105\n' >&2
printf 'Output line C\n'
return 1
}
# Regular expression matching an error string
readonly error_rx='ERROR +[0-9]+'
if ERRMSG=$(dostuff 2>&1) ; then
echo 'process success'
elif [[ $ERRMSG =~ $error_rx ]] ; then
printf '%s\n' "${BASH_REMATCH[0]}"
else
echo 'empty'
fi >> "$FQLOGNAME"
It appends 'ERROR 29' to the log file.
For more information about Bash's built-in regular expression matching see mklement0's answer to "How do I use a regex in a shell script?".
Make it simpler and easier:
if ! ERRMSG=$(cd /nonexist 2>&1); then
if <<<"$ERRMSG" grep -q 'No such file or directory'; then
# if the error string contains the message 'No such file or directory'
echo "empty" >> "$FQLOGNAME"
else
printf "Unhandled cd error: %s" "$ERRMSG" >> "$FQLOGNAME"
fi
else
echo "process success" >> "$FQLOGNAME"
fi
if statements checks for the return status of a COMMAND. [ or test is just a command, which return a status. The return status of assignment is the same as command status. What I mean, is that out=$(cmd); if [ "$?" -eq 0 ]; then is the same as if out=$(cmd); then.
Using HERE-strings is a bit better than echo "$string". Echo is not that much portable, better get used to printf "%s" "$string" which is a portable way. However HERE-strings puts additional EOF at the end of the stream, which sometimes breaks while read loops, but for most cases works ok.
Don't if [ -z "$(echo smth | grep ..)" ]; then. You can just check grep return status, just if echo smth | grep ...; then or with HERE-strings if <<<"smth" grep -q ...; then or if grep -q ... file; then. The -q option which has --quiet or --silent alternatives makes grep produce no output.
The quoting is not needed when assigning a variable from a single command substitution. tmp="$(...)" is just the same as tmp=$(...).

How to display argument in shell script

I have a shell script called displayArg.sh This is how I intend to run it-
./displayArg hello
and the output is entered arg is hello
The following is the script-
if [ $1 == "" ]; then
default="Default"
echo "no value is given. Output is $default"
else
value=$?
echo "entered arg is $value" #I know I am wrong in these 2 lines, but not sure how to fix it
fi
Kindly bear with me. I'm new to Shell scripting
You want:
value="$1"
($? is the status of the last command, which is 1 because the test command is what was executed last.)
Or you can simplify to:
if [ "$1" == "" ]
then
echo "no value is given. Output is Default"
else
echo "entered arg is $1"
fi
Note the quotes around "$1" in the test. If the string is empty, you get a syntax error. Your alternative with bash is to use a [[ $1 == "" ]] test.

Resources