Easy Bash if-else - bash

OK, I can’t get this to work for some reason:
if /etc/mysql/my.cfn exist
then goto end;
else bash install.sh;
end exit;;

Check for non-existence and run install.sh if true.
[[ ! -e /etc/mysql/my.cfn ]] && bash install.sh

Here's a relatively literal translation:
if [ -e /etc/mysql/my.cfn ]; then
exit # Note: bash does not have a goto command
else
bash install.sh
fi
Or, eliminate the irrelevant then condition, and invert the test:
if [ ! -e /etc/mysql/my.cfn ]; then
bash install.sh
fi

The : command in bash with no arguments is a no-op, so you can use that in an if-body if you need to do nothing.
if something; then
:
else
do something else
fi
Of course, you'd normally want to write that as:
if ! something; then
do something else
fi
or
something || do something else

Your four lines in one line of Bash:
[[ -e /etc/mysql/my.cfn ]] && exit || bash install.sh
Did you mean my.cnf ?

(One) correct syntax is:
if [[ expression ]]; then
command
else
command
fi
The traditional style would be:
if test -f filename; then
command
fi

Related

Run command in script and check return value

I am trying to run the diff command on two folders, check the return value and then output a message.
I have this:
#!/bin/bash
result='diff dir1 dir2'
if result == 0
then
echo "OK"
else
echo "ERROR"
fi
But I am getting result: command not found
How should I execute the command and return the value, to be compared in the IF?
Quite some problems here. This is an example, but you should do more research in the future.
#!/bin/bash
result="$(diff dir1 dir2)"
ret=$?
if [[ $ret -eq 0 ]]; then
then
echo "OK"
else
echo "ERROR"
fi
exit $ret
The simplest way is to check it directly:
#!/bin/bash
if diff dir1 dir2; then
echo "OK"
else
echo "ERROR"
fi
If you don't want diff to print anything, use the -q flag.
please use ${result} instead.
Also, note the backticks on the actual command
#!/bin/bash
result=`diff dir1 dir2`
if [[ -z ${result} ]]
then
echo "OK"
else
echo "ERROR"
fi

shell - var length with if condition gives error

I am trying to see if I found something using grep or not with this
found=`grep -F "something" somefile.txt`
if ((${#found} == 0)); then
echo "Not Found"
else
echo "Found"
fi
I succeeded using above logic that if grep found something it stores the output in found variable but the issue I am facing is with if condition. Whenever found=0 it gives me some error like that
final.sh: 13: final.sh: 0: not found
FYI: final.sh is the script name
The problem is that you're writing bash specific code, but running it with sh. In bash, (( .. )) is an arithmetic context, while in POSIX sh, it's merely two nested subshells, causing it to try to execute the number as a command.
You can run it with bash instead of sh by specifying #!/bin/bash in the shebang, and/or using bash yourfile instead of sh yourfile if you invoke it that way.
The correct way for your example, however, is to use grep's exit status directly:
if grep -q something somefile
then
echo "found"
else
echo "not found"
fi
To check whether some string is in your file, you can use the return status from grep
grep -q something somefile.txt
if [ $? -eq 0 ]
then
echo "found"
else
echo "not found"
fi
a shorter form will be
grep -q something somefile.txt && echo found || echo not found
found=$(grep -F "something" somefile.txt)
if [ $? = 0 ]; then # $? is the return status of a previous command. Grep will return 0 if it found something, and 1 if nothing was found.
echo "Something was found. Found=$found"
else
echo 'Nothing was found'
fi
I find this code more elegant than other answers.
But anyway, why are you writing in sh? Why don't you use bash? Are you sure that you need that portability? Check out this link to see if you really need sh
Here's how I do that sort of thing:
found=$(grep -F "something" somefile.txt)
if [[ -z $found ]]; then
echo "Not found"
else
echo "Found"
fi

How to check if a file contains a specific string using Bash

I want to check if a file contains a specific string or not in bash. I used this script, but it doesn't work:
if [[ 'grep 'SomeString' $File' ]];then
# Some Actions
fi
What's wrong in my code?
if grep -q SomeString "$File"; then
Some Actions # SomeString was found
fi
You don't need [[ ]] here. Just run the command directly. Add -q option when you don't need the string displayed when it was found.
The grep command returns 0 or 1 in the exit code depending on
the result of search. 0 if something was found; 1 otherwise.
$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0
You can specify commands as an condition of if. If the command returns 0 in its exitcode that means that the condition is true; otherwise false.
$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$
As you can see you run here the programs directly. No additional [] or [[]].
In case if you want to check whether file does not contain a specific string, you can do it as follows.
if ! grep -q SomeString "$File"; then
Some Actions # SomeString was not found
fi
In addition to other answers, which told you how to do what you wanted, I try to explain what was wrong (which is what you wanted.
In Bash, if is to be followed with a command. If the exit code of this command is equal to 0, then the then part is executed, else the else part if any is executed.
You can do that with any command as explained in other answers: if /bin/true; then ...; fi
[[ is an internal bash command dedicated to some tests, like file existence, variable comparisons. Similarly [ is an external command (it is located typically in /usr/bin/[) that performs roughly the same tests but needs ] as a final argument, which is why ] must be padded with a space on the left, which is not the case with ]].
Here you needn't [[ nor [.
Another thing is the way you quote things. In bash, there is only one case where pairs of quotes do nest, it is "$(command "argument")". But in 'grep 'SomeString' $File' you have only one word, because 'grep ' is a quoted unit, which is concatenated with SomeString and then again concatenated with ' $File'. The variable $File is not even replaced with its value because of the use of single quotes. The proper way to do that is grep 'SomeString' "$File".
Shortest (correct) version:
grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"
can be also written as
grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"
but you dont need to explicitly test it in this case, so the same with:
grep -q "something" file && echo "yes" || echo "no"
##To check for a particular string in a file
cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi
grep -q [PATTERN] [FILE] && echo $?
The exit status is 0 (true) if the pattern was found; otherwise blankstring.
if grep -q [string] [filename]
then
[whatever action]
fi
Example
if grep -q 'my cat is in a tree' /tmp/cat.txt
then
mkdir cat
fi
In case you want to checkif the string matches the whole line and if it is a fixed string, You can do it this way
grep -Fxq [String] [filePath]
example
searchString="Hello World"
file="./test.log"
if grep -Fxq "$searchString" $file
then
echo "String found in $file"
else
echo "String not found in $file"
fi
From the man file:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of
which is to be matched.
(-F is specified by POSIX.)
-x, --line-regexp
Select only those matches that exactly match the whole line. (-x is specified by
POSIX.)
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero
status if any match is
found, even if an error was detected. Also see the -s or --no-messages
option. (-q is specified by
POSIX.)
Try this:
if [[ $(grep "SomeString" $File) ]] ; then
echo "Found"
else
echo "Not Found"
fi
I done this, seems to work fine
if grep $SearchTerm $FileToSearch; then
echo "$SearchTerm found OK"
else
echo "$SearchTerm not found"
fi
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"

Find substring in shell script variable

I have a string
$VAR="I-UAT";
in my shell script code. I need a conditional statement to check if "UAT" is present in that string.
What command should I use to get either true or false boolean as output?
Or is there any other way of checking it?
What shell? Using bash:
if [[ "$VAR" =~ "UAT" ]]; then
echo "matched"
else
echo "didn't match"
fi
You can do it this way:
case "$VAR" in
*UAT*)
# code when var has UAT
;;
esac
The classic way, if you know ahead of time what string you're looking for, is a case statement:
case "$VAR" in
*UAT*) : OK;;
*) : Oops;;
esac
You can use an appropriate command in place of the : command. This will work with Bourne and Korn shells too, not just with Bash.
found=`echo $VAR | grep -c UAT`
Then test for $found non-zero.
In bash script you could use
if [ "$VAR" != "${VAR/UAT/}" ]; then
# UAT present in $VAR
fi
try with grep:
$ echo I\-UAT | grep UAT
$ echo $?
0
$ echo I\-UAT | grep UAX
$ echo $?
1
so testing
if [ $? -ne 0 ]; then
# not found
else
# found
fi
I like this a little better than using case/esac (and it'll work with non-bash shells):
#!/bin/sh
full_string="I-UAT"
substring="UAT"
if [ -z "${full_string##*$substring*}" ]; then
echo "Found substring!"
else
echo "Substring is MIA!"
fi
If the string returned is zero-length (-z), then the substring was found.

Bash, always echo in conditional statement

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

Resources