Condense an if statement into one line in bash - bash

I have the following script:
#!/usr/bin/bash
arch=`uname -p`
if [[ "$arch" == "x86_64" ]]
then
echo "Yes"
else
echo "No"
fi
Is there a way to write this as a short one-liner on the command prompt, $ instead of having it as a script. Something like:
$ test uname -p == "x86_64" ? "Yes" : "No"
Though I'm not sure of the ternary usage (?) in bash.

You could use the following, where the && part would run if the statement evaluates to True, and || would run run otherwise:
[ "`uname -p`" = "x86_64" ] && echo "Yes" || echo "No"

Related

Yes/No shell script causing "==Yes" loop?

I'm creating a shell script to automatically do sudo apt update/upgrade/autoremove/autoclean (first bash script of my life), everything works but the yes or no section
Here's my code:
#!/bin/bash
echo "Updating and upgrading system components"
sudo apt update
sudo apt upgrade
echo "Starting cleaning and removing unnecessary files"
sudo apt autoremove
sudo apt autoclean
echo "Do you want to check if a new distribution update is available? Y/N"
read -p "Check system distribution updates?" answer
if ["$answer" == "Y" || "$answer" == "Yes" || "$answer" == "y" || "$answer" == "yes"]
then
sudo do-release-upgrade
else
exit
fi
After answering one of these option shell starts printing in loop "==Yes"
Any idea?
[ needs to be separated by space from its arguments. ["$answer" gets parsed as a single command with two arguments, == and Y. Such a command doesn't exist, so it fails, and || tries the next command. The next command is yes: it's a command that prints its arguments infinitely. The arguments in this case are == and Yes.
The correct way to write the condition is
if [ "$answer" == "Y" ] || [ "$answer" == "Yes" ] || [ "$answer" == "y" ] || [ "$answer" == "yes" ]
or
if [ "$answer" == "Y" -o "$answer" == "Yes" -o "$answer" == "y" -o "$answer" == "yes" ]
or, if you're using bash
if [[ $answer == Y || $answer == Yes || $answer == y || $answer == yes ]]
You can also use parameter expansion to lowercase the answer (but it includes yEs etc. among the accepted answers)
if [[ ${answer,} == y || ${answer,,} == yes ]]
Or you can use a regex with the =~ operator
if [[ ${answer,,} =~ ^y(es)?$ ]]
Under shopt -s extglob, you can use a pattern to match both the cases in one expression:
if [[ ${answer,,} == y?(es) ]]

How to do character comparison in bash scripts?

Here is my code
#! /bin/bash
read var
if [ $var="Y" -o $var="y" ]
then
echo "YES"
else
echo "NO"
fi
I want to print YES if the user presses y or Y, otherwise I want to print NO. Why doesn't this code work?
Basically, your Condition is wrong. Quote your variables and leave spaces between operators (like shellter wrote). So it should look like:
#! /bin/bash
read var
if [ "$var" = "Y" ] || [ "$var" = "y" ]
then
echo "YES"
else
echo "NO"
fi
Edit: for POSIX ccompatibility
Replaced == with = - see comments
Replaced -o syntax with || syntax - see comments
With Bash, you can also use regular expression in your test with the =~ operator:
read var
[[ "$var" =~ [Yy] ]] && echo "YES" || echo "NO"
Or as Benjamin W. mentionned, simply use character range with the == operator:
read var
[[ "$var" == [Yy] ]] && echo "YES" || echo "NO"
There is minor syntax error in your code.
Correction : There should be a white space between operators and variables
read var
if [ $var = "Y" -o $var = "y" ]
then
echo "YES"
else
echo "NO"
fi
Try the above bash script.
Hope it would work fine.
Happy Coding!
If all you require is a upper/lowercase comparison, use the ,, operator on the variable being compared ( note the ${var,,} ):
#!/bin/bash
read var
if [ ${var,,} = "y" ]
then
echo "YES"
else
echo "NO"
fi
or more succinctly:
#!/bin/bash
read var
[ ${var,,} = 'y' ] && echo 'YES' || echo 'NO'
or the way I might actually do it:
#!/bin/bash
read var
[[ "${var,,}" == 'y' ]] && echo 'YES' || echo 'NO'
Below is the code that I tried.
#! /bin/bash
read -p "Are you Sure?(Y/N) " answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
echo "Do your stuff."
else
echo "Do your other stuff"
fi
Add whitespace around '=' and your code will run fine.
#! /bin/bash
read var
if [ $var = "Y" -o $var = "y" ]
then
echo "YES"
else
echo "NO"
fi
Try this code.
#! /bin/bash
read var
echo -e "YES\nNO\n" | grep -i $var

curious case of shell exit values

bash# sh -c "true && [[ $? = 0 ]] && echo XXX"
I expect this to echo XXX , as true should set the exit value as 0 .
But I figured out to my amazement that it depends on what the exit value was before we ran sh -c , i.e.
bash# true
bash# sh -c "true && [[ $? = 0 ]] && echo XXX"
returns XXX
but ,
bash# false
bash# sh -c "true && [[ $? = 0 ]] && echo XXX"
doesn't.
Which implies that any command we run inside sh doesn't set the exit value.
is it right behaviour , or am I misunderstanding something ?
$? is expanded inside double quotes, just like any other variable. So it is replaced with the exit code of the previous command before sh even sees it. You probably meant to use single quotes.
Try this:
$ false
$ sh -c 'true && [[ $? -eq 0 ]] && echo XXX'
XXX
Or:
$ false
$ sh -c 'true && [[ "$?" = "0" ]] && echo XXX'
XXX
Make sure that $? is not substituted before hand.

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

Easy Bash if-else

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

Resources