Bash, always echo in conditional statement - bash

This may turn out to be more of a thought exercise, but I am trying to echo a newline after some command I'm executing within a conditional. For example, I have:
if ssh me#host [ -e $filename ] ; then
echo "File exists remotely"
else
echo "Does not exist remotely"
fi
And want to throw in an echo after the ssh command regardless of the outcome. The reason is formatting; that way a newline will exist after the prompt for password for ssh.
First Try
if ssh me#host [ -e $filename ] && echo ; then
Because && echo would not change the conditional outcome, but bash would not execute echo if ssh returned false. Similarly,
if ssh me#host [ -e $filename ] || (echo && false) ; then
Does not work because it will short-circuit if ssh returns true.
An answer to the problem would be
ssh me#host [ -e $filename ]
result=$?
echo
if [ $result == 0 ] ; then
but was wondering if there was some similar conditional expression to do this.
Thanks.

While this would work
if foo && echo || ! echo; then
I'd prefer putting the whole thing into a function
function addecho() {
"$#" # execute command passed as arguments (including parameters)
result= $? # store return value
echo
return $result # return stored result
}
if addecho foo; then

What about this?
if ssh me#host [ -e $filename ] && echo || echo; then
I have not thought about precedence order of && and || and surely putting some parenthesis would help, but like that it works already... you get the echo both when ssh fails and when it succeeds...

Add the "echo" before the filename test
if ssh me#host "echo; [ -e $filename ]"; then
echo "File exists remotely"
else
echo "Does not exist remotely"
fi

Related

bash scripting one line shortcut for if test

Is there a shortcut (ie all on one line) for doing the following?
if [ -z "$PASSWORD" ] ; then
echo "PASSWORD envvar required. Exiting..."
exit 1
fi
I'm thinking along the lines of the following. Or maybe there's an even shorter way.
[ -z "$PASSWORD" ] && ...
That is, how do put the echo then exit after the &&
You can do it like this:
[ -z "$PASSWORD" ] && { echo "PASSWORD envvar required. Exiting..."; exit 1; }
Note the extra ; at the end of the line before the }, this is necessary and you cannot leave it out.
It's called a command group.
[[ -z "$PASSWORD" ]] && echo "PASSWORD envvar required. Exiting." && exit 1
Your single brackets will work fine. Consider learning to use the doubles, though.

Bash conditions always evaluate true in script

I have a condition which seems to always be evaluated as true.
#!/bin/bash
checkFolder() {
echo "[checkFolder]"
echo "check $1"
[ -n "$1" ] && [ -d "$1" ] && return 0
echo "[/checkFolder]"
return 1
}
rootFolder=$1
echo "check $rootFolder"
checkFolder "$rootFolder"
echo "res: $res" # !! <--- I omitted this test line, as I thought it was irrelevant.
echo "ret: $?"
When I execute my script, any path will give me a return value of 0. Which means that any string I provide seems to be seen as non-empty as well as an existing directory. I tried with:
./myScript.sh "."
./myScript.sh ""
./myScript.sh "wqert"
I will aways get a return value of 0. How comes?
If I run this command in my terminal:
param=""
[ -n "$param" ] && [ -d "$param" ] && echo ok
# returns nothing
param="hello"
[ -n "$param" ] && [ -d "$param" ] && echo ok
# returns nothing
param="/home"
[ -n "$param" ] && [ -d "$param" ] && echo ok
# returns "ok"
Why doesn't it work in my script?
$? is the exit code of the last executed command. In your case, the last executed command is echo, not checkFolder.
If you want to execute other commands between running a command and checking its status, assign it to a variable with myvar=$?
What the command return changes is the "exit code" of the function.
Add this:
checkFolder "$rootFolder"
echo "the exit code was $?"
And see the effect of your return 0 and return 1.

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"; }

bash determine if variable is empty and if so exit.

I am trying to perform this:
i have a test file which md5sum of files located on sftp.
variables should contain an md5sum (string), if the variable is empty it means there is no file on the sftp server.
i am trying this code but it does not work..
if [ -z $I_IDOCMD5 ] || [ -z $I_LEGALMD5 ] || [ -z $I_ZIPMD5 ]
then
echo "ERROR: At least one file not present of checksum missing no files will be deleted" >>$IN_LOG
ERRORS=$ERRORS+2
else
if [[ $I_IDOCMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/idoc/$I_IDOC) ]]
then
echo "rm IDOC/$I_IDOC" >/SAP/commands_sftp.in
else
echo "problem with checksum"
ERRORS=$ERRORS+2
fi
if [[ $I_LEGALMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/legal/$I_LEGAL) ]]
then
echo "rm LEGAL/$I_LEGAL" >>/SAP/commands_sftp.in
else
echo "problem with checksum"
ERRORS=$ERRORS+2
fi
if [[ $I_ZIPMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/zip/$I_ZIP) ]]
then
echo "rm ZIP/$I_ZIP" >>/SAP/commands_sftp.in
else
echo "problem with checksum"
ERRORS=$ERRORS+2
fi
The answer I prefer is following
[[ -z "$1" ]] && { echo "Parameter 1 is empty" ; exit 1; }
Note, don't forget the ; into the {} after each instruction
One way to check if a variable is empty is:
if [ "$var" = "" ]; then
# $var is empty
fi
Another, shorter alternative is this:
[ "$var" ] || # var is empty
In bash you can use set -u which causes bash to exit on failed parameter expansion.
From bash man (section about set builtin):
-u
Treat unset variables and parameters other than the special parameters "#" and "*" as an error when performing parameter
expansion. If expansion is attempted on an unset variable or
parameter, the shell prints an error message, and, if not interactive,
exits with a non-zero status.
For more information I recommend this article:
http://redsymbol.net/articles/unofficial-bash-strict-mode/
You can use a short form:
FNAME="$I_IDOCMD5"
: ${FNAME:="$I_LEGALMD5"}
: ${FNAME:="$I_ZIPMD5"}
: ${FNAME:?"Usage: $0 filename"}
In this case the script will exit if neither of the I_... variables is declared, printing an error message prepended with the shell script line that triggered the message.
See more on this in abs-guide (search for «Example 10-7»).
First test only this (just to narrow it down):
if [ -z "$I_IDOCMD5" ] || [ -z "$I_LEGALMD5" ] || [ -z "$I_ZIPMD5" ]
then
echo "one is missing"
else
echo "everything OK"
fi
echo "\"$I_IDOCMD5\""
echo "\"$I_LEGALMD5\""
echo "\"$I_ZIPMD5\""
"if the variable is empty it means there is no file on the sftp server"
If there is no file on the sftp server, is the variable then really empty ?
No hidden spaces or anything like that ? or the number zero (which counts as non-empty) ?

Bash: if [ "echo test" == "test"]; then echo "echo test outputs test on shell" fi; Possible?

Is it possible with bash to execute a command from shell and if it returns a certain value (or an empty one) execute a command?
if [ "echo test" == "test"]; then
echo "echo test outputs test on shell"
fi
Yes, you can use backticks or $() syntax:
if [ $(echo test) = "test" ] ; then
echo "Got it"
fi
You should replace $(echo test) with
"`echo test`"
or
"$(echo test)"
if the output of the command you run can be empty.
And the POSIX "stings are equal" test operator is =.
something like this?
#!/bin/bash
EXPECTED="hello world"
OUTPUT=$(echo "hello world!!!!")
OK="$?" # return value of prev command (echo 'hellow world!!!!')
if [ "$OK" -eq 0 ];then
if [ "$OUTPUT" = "$EXPECTED" ];then
echo "success!"
else
echo "output was: $OUTPUT, not $EXPECTED"
fi
else
echo "return value $OK (not ok)"
fi
You can check the exit_code of the previous program like:
someprogram
id [[ $? -eq 0 ]] ; then
someotherprogram
fi
Note, normally the 0 exit code means successful finish.
You can do it shorter:
someprogram && someotherprogram
With the above someotherprogram only executes if someprogram finished successfully. Or if you want to test for unsuccessful exit:
someprogram || someotherprogram
HTH
Putting the command betweeen $( and ) or backticks (`) will substitute that expression into the return value of the command. So basically:
if [ `echo test` == "test"]; then
echo "echo test outputs test on shell"
fi
or
if [ $(echo test) == "test"]; then
echo "echo test outputs test on shell"
fi
will do the trick.

Resources