convert read string to integer in bash - bash

I'm trying to read from user and then do the following.
read framechoice
if [ $framechoice -gt 100 ]; then
if [ $framechoice -lt 0 ]; then
framechoice=101
fi
fi
It gives me the following error.
[: -gt: unary operator expected
Can anyone tell me where I am going wrong.

This happens if you don't input anything:
$ cat myscript
read framechoice
if [ $framechoice -gt 100 ]; then
if [ $framechoice -lt 0 ]; then
framechoice=101
fi
fi
$ bash myscript
<enter>
myscript: line 2: [: -gt: unary operator expected
Try instead to actually enter something:
$ bash myscript
42<enter>
The script then exits with success.

Your program needs to cope with empty input. This is most easily achieved by properly quoting the variable; then
if [ "$framechoice" -gt 100 ]; then
evaluates to [ "" -gt 100 ] which is no longer is a syntax error; however, instead, it throws the warning integer expression expected.
Even better, maybe filter the input so that you do not attempt numeric comparisons before making sure the input is numeric.

Related

filtering files by number in bash error unary operator expected

I have a script that will find the distances between two atoms in pdb.
bash does not recognize decimals so I have put printf script to round the decimals.
and echo $b works fine and gives me a integer value.
but the if line for my filtering system does not work.
I get and error stating
[: -ge: unary operator expected
below is part of the script that I am working on.
a=$(awk '$2=='91'{x1=$6;y1=$7;z1=$8} $2=='180' {x2=$6;y2=$7;z2=$8} END{print sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2))}' ${names}.pdb.$i)
b= printf %.0f $a
echo $b
if [ $b -ge 1 ] &&[ $b -le 9 ]; then
any help will be greatly appreciated. Thank you in advanced.
b= printf %.0f $a
This line sets the value of b to nothing for the duration of the printf command, which sends its output to stdout
echo $b
This prints a blank line.
You must not put whitespace around the = in an assignment, and to store the output of a command into a variable, you use this syntax:
b=$( printf %.0f $a )
You're getting the error because $b is empty, and this is what bash sees:
if [ -ge 1 ] &&[ -le 9 ]; then
-ge is expecting operands on both the left and the right, and it doesn't see one.
With bash, you should (almost) always prefer [[ ... ]] over [ ... ] -- the double bracket form is not fooled by variables containing empty strings.
You should always quote your "$variables" -- unless you know exactly when to not quote them.

not found error in shell script

I am trying to run the following code in debian terminal.
read var
if [$var -gt 0]; then
echo "Greater than zero"
fi
When I give 45 as an input to the variable var, the terminal is showing the following error
4:[ 45: Not Found
Why is the error coming and what is it's solution.
Spaces inside [ and ] are mandatory:
Try:
read var
if [ "$var" -gt 0 ]; then
echo "Greater than zero"
fi
/bin/[ is a binary in Unix that takes it's arguments from the string that comes after a space.

Mac Bash - doesn't recognize if[$#=0]

It's been a while since I've scripted in bash so I made a small script to test things out. This is my script (the quoted text is some Dutch, doesnt really matter):
#isingelogd
if[$#=0]
then
echo "Geef user-id's op!" 1>$2 ; exit 1
fi
for uid in $*
do
if who|grep $uid >dev/null
then
echo $uid is ingelogd
else
echo $uid is niet ingelogd
fi
done
If I try to run it it tells me the following:
bash-3.2$ ./isingelogd
./isingelogd
./isingelogd: line 3: if[0=0]: command not found
./isingelogd: line 4: syntax error near unexpected token `then'
./isingelogd: line 4: `then'
If I check my version with bash -v I'm running 3.2 which I thought supported square brackets.
Has someone had a similar problem and found solution?
Look at your errors:
bash-3.2$ ./isingelogd
./isingelogd
./isingelogd: line 3: if[0=0]: command not found
./isingelogd: line 4: syntax error near unexpected token then'
./isingelogd: line 4:then'
See that command not found? you have an error in your script.
The [..] are actual commands, and like all commands, they need to be separated by white spaces. The = is a parameter to the [ command and also needs to be surrounded by white space. Change line #3 to this:
if [ $# -eq 0 ]
Since $# and 0 are numeric, you should use -eq which compares to numbers and not = which compares strings.
Try these commands:
$ ls -li /bin/test
$ ls -li /bin/[
You'll see they have the same inode number. They're links. (Yes, the [ and test are builtins into the shell, but they are linked builtin commands).
$ man test
will give you all of the various tests that [ can do. Again, note the difference between -eq vs. = and -gt vs. >.
Note the following:
if [ 54 > 123 ]
then
echo "54 is greater than 123"
fi
This will print out "54 is greater than 123". This won't:
if [ 54 -gt 123 ]
then
echo "54 is greater than 123"
fi
a.bash works for me in Mac. Content of a.bash is the following :
#!/bin/bash
if [ $# == 0 ]; then
echo "Usage da da do"
fi
export A=$1
echo $A
then execute with the following :
\# ] ./a.bash
Usage da da do

Removing files in Unix using bash

I'm trying to delete a large amount of files from my computer, and I'm trying to write a bash script to do so using the rm command. What I want to know is how to do equality in bash, and why my code (posted below) won't compile. Thank you for your help!
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if ["$i" -eq "$e1"]
then
b="000"
echo $b$
fi
if ["$i" -eq "$e2"]
then
b='00'
fi
if ["$i" -eq "$e3"]
then
b='0'
fi
if ["$i" -eq "$e4"]
then
b =''
fi
if [bash$ expr "$i" % "$e3$ -ne 0]
then
d = $b$c$a
rm d
fi
done
Shell scripts aren't compiled at all.
You need spaces after your [ and before your ].
if [ "$i" -eq "$e1" ]
There's an errant bash$ in there you probably don't want at all. It should probably be a $() operator:
if [ $(expr "$i" % "$e3") -ne 0 ]
You can't have spaces around the = in bash. For example, change b ='' to b='' and d = $b$c$a to d=$b$c$a.
echo $b$ looks like it should be echo $b.
Shell script does not compile it is a scripting language.
Try to fix this line :
if [bash$ expr "$i" % "$e3$ -ne 0]
Make it like below :
if [ $(expr "$i" % "$e3$") -ne 0 ]
You need spaces around the square brackets. The [ is actually a command, and like all commands needs to be delineated by white space.
When you set values for variables in shell, you do not put spaces around the equals signs.
Use quotation marks when doing comparisons and setting values to help delineate your values.
What happens if none of the if conditions are true, and $b isn't set.
What is the logic behind this code. It seems to be a bunch of random stuff. You're incrementing $ from 1 to 10000, but only setting the value of $b on only four of those values. Every 200 steps, you delete a file, but $b may or may not be set even though it's part of the file name.
Did you write this program yourself? Did you try to run it? What errors were you getting? Did you look at the lines referenced by those errors. It looks like you included the bash$ prompt as part of the command.
There were plenty of errors, and I've cleaned most of them up. The cleaned up code is posted below, but it still doesn't mean it will do what you want. All you said is you want to delete "a large amount of files" on your computer, but gave no other criteria. You also said "What I want to know is how to do equality in bash" which is not the question you stated in you header.
Here's the code. Note the changes, and it might lead to whatever answer you were looking for.
#!/bin/bash
# int-or-string.sh
b="0000"
c="linorm"
f=500
e1=2
e2=20
e3=200
e4=2000
for i in {0..10000}
do
a=$(($f*$i))
if [ "$i" -eq "$e1" ]
then
b="000"
elif [ "$i" -eq "$e2" ]
then
b='00'
elif [ "$i" -eq "$e3" ]
then
b='0'
elif [ "$i" -eq "$e4" ]
then
b=''
fi
if ! $(($i % $e3))
then
d="$b$c$a"
rm "$d"
fi
done
ERRORS:
Spaces around the [ and ]
The rm "$d" command was originallyrm dwhich would just remove a file namedd`.
if/then statement converted to if/else if.
Rewrote [ $(expr "$1" % "$e3") -ne 0 ].
No need for expr since BASH has $((..)) syntax.
No need for test command ([) since if automatically evaluates zero to true and non-zero to false.
Added quotes.

Bash script command result inside other variable to define prompt

I would like to define a prompt which will indicate with colors whether the command executed properly and whether the command was found. As for now I have something like this but I does not work properly.
PS1="\`COMMAND_RESULT=\$\?;
if [ $COMMAND_RESULT -eq 127 ]; then echo \[\e[33m\] ---=== Command not found ===--- ;
elif [ $COMMAND_RESULT -ne 0 ]; then echo \[\e[33m\]---=== \[\e[31m\]Oh noes, bad command \[\e[33m\]==---;
fi\`
\n\[\e[0;37m\][\[\e[1;31m\]\#\[\e[0;37m\]]
\[\e[0;32m\]\u\[\033[1;33m\]#\[\033[0;32m\]\h
As for now I get this error on bash start :
-bash: [: -eq: unary operator expected
-bash: [: -ne: unary operator expected
Don't pollute your PS1 with functions. You should use the special PROMPT_COMMAND variable to do this. The value of PROMPT_COMMAND is executed as a command prior to issuing each primary prompt.
Here is an example:
_check_command(){
local COMMAND_RESULT=$?
if [ $COMMAND_RESULT -eq 127 ]
then
echo -e "\e[1;33m---=== Command not found ===---\e[m"
elif [ $COMMAND_RESULT -ne 0 ]
then
echo -e "\e[1;31m---=== Oh noes, bad command ===---\e[m"
fi
}
PROMPT_COMMAND='_check_command'
PS1="\[\e[0;37m\][\[\e[1;31m\]\#\[\e[0;37m\]] \[\e[0;32m\]\u\[\033[1;33m\]#\[\033[0;32m\]\h "
There are many bash prompts you can find online to guide you. Here is one good example.
You probably should not escape $? as \$\?. Looks like it gets interpreted literally.
Also you can check out the Arch Wiki article that shows how to implement something similar to what you want. Look at this line:
PS1="$(if [[ ${EUID} == 0 ]]; then echo '\[\033[01;31m\]\h'; else echo '\[\033[01;32m\]\u#\h'; fi)\[\033[01;34m\] \w \$([[ \$? != 0 ]] && echo \"\[\033[01;31m\]:(\[\033[01;34m\] \")\$\[\033[00m\] "
especially this part:
([[ \$? != 0 ]] && echo \"\[\033[01;31m\]:(\[\033[01;34m\] \")

Resources