[: too many arguments when taking * as an input - linux

So I have to make this little calculator in bash with some simple functions which you can see below in the code(which is the debug version). However during execution I'm having an issue where inputting * into operation2 is giving me [: too many arguments, this however does not occur with operation1.
I need the calculator to take this input for inputs like 1+1*2 etc as the script needs to keep going till the user enters "=" hence the while ! loop. I am new to batch scripting so I have no clue what I have to change. I know from debugging it is calling up a list of the files in the dictionary this script is located in, so I believe it must be misinterpreting the command.
The code is as follows with the issue happening when reading in * on either operation2. It works however for all the other inputs (+, -, /, =)
#bin/bash +x
begin=$(date +"%s")
echo "Please Enter Your Unix Username:"
read text
userdata=$(grep $text /etc/passwd | cut -d ":" -f1,5,6 | tr -d ',')
echo "The User: $userdata" >> calcusers.txt
date=$(date)
echo "Last Ran calculator.sh on: $date " >> calcusers.txt
echo "---------------------------------------------------------" >> calcusers.txt
name=$(grep $text /etc/passwd | cut -d ":" -f5 | cut -d\ -f1)
echo -n "Hello" $name && echo ", Welcome to calculator.sh."
echo "To begin using calculator.sh to do some calculations simply type a number"
echo "below, followed by the type of sum you want to perform and the input for"
echo "a second number, third and so on. To output the equation simply type =."
set -x
echo "Please Enter a Number:"
read number1
echo "Would you like to Add(+), Subtract(-), Multiply(*) or Divide(/) that number?"
read operation1
echo "Please Enter a Number:"
read number2
total=$(echo "$number1$operation1$number2" | bc)
echo "Would you like to Add(+), Subtract(-), Multiply(*), Divide(/) or Equals(=) that equation?"
read operation2
while [ ! $operation2 = "=" ]
do
echo "Please Enter a Number:"
read number3
total=$(echo "$total$operation2$number3" | bc)
echo "Would you like to Add(+), Subtract(-), Multiply(*), Divide(/) or Equals(=) that equation?"
read operation2
done
set +x
echo -n "The total of the equation is" $total && echo "."
termin=$(date +"%s")
difftimelps=$(($termin-$begin))
echo "Thanks for using calculator.sh!"
echo "$(($difftimelps / 60)) minutes and $(($difftimelps % 60)) seconds has passed since the Script was Executed."
exit 0

Quote your variables everywhere:
while [ ! "$operation2" = "=" ]
# ........^............^
Also, you should expect invalid input from your users
while [ ! "$operation2" = "=" ]
do
case "$operation2" in
[*/+-])
echo "Please Enter a Number:"
read number3
total=$(echo "$total$operation2$number3" | bc)
;;
*) echo "Invalid operation: '$operation2'"
;;
esac
echo "Would you like to Add(+), Subtract(-), Multiply(*), Divide(/) or Equals(=) that equation?"
read operation2
done

Related

(standard_in) 1: syntax error in my bash script - bc error [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed last year.
I'm trying to create a calculator that makes basic math operations on shell script but it keeps returning me this syntax error (standard_in) 1: syntax error when I try to multiply two numbers, I tried to find some resolution but nothing helped me until now.
Heres is my code:
echo "====== Calculator ======"
echo " "
# It will save both numbers to the variables
echo "Type a number: "
read numA
echo "Type another number: "
read numB
echo " "
# It will give a list of possible operations
echo "Choose an option"
echo "------------------"
echo "1)Addition"
echo "------------------"
echo "2)Subtraction"
echo "------------------"
echo "3)Multiplication"
echo "------------------"
echo "4)Division"
echo "------------------"
echo " "
read -s opt
# It will make the math behind each operation
case $opt in
1)result=`echo $numA + $numb | bc`;;
2)result=`echo $numA - $numB | bc`;;
3)result=`echo $numA * $numB | bc`;;
4)result=`echo "scale=2; $numA / $numB" | bc`;;
esac
echo "Result: $result"
Put a back slash before the "*", i.e.
3)result=`echo $numA \* $numB | bc`;;

BASH scripting - menu not showing echos

I'm extremely new to this, but can anyone tell me why when I run this, it doesn't show my echo's?
It accepts all my inputs, but say when I do the subtraction one it doesn't display
echo "$a - $b = $(($a-$b))"
It worked if I put an Exit after each case, but I would like it to keep going after it completes one input.
#!/bin/bash
while true; do
clear
cat <<EOF
Please Select:
Option 1. Quit
Option 2. Display Options Again
Option 3. Subtraction
Option 4. Division
Option 5. Who am I?
EOF
read -p "Enter selection [1-5] > "
case "$REPLY" in
1)
break
;;
2)
;;
3)
read -p "Enter the First Number: " a
read -p "Enter the Second Number: " b
echo "$a - $b = $(($a-$b))"
;;
4)
printf "Enter the First Number: "
read a
printf "Enter the Second Number: "
read b
echo "$a / $b = $(($a/$b))"
;;
5)
echo "My name is Michelle"
;;
*)
echo "Invalid entry."
;;
esac
done
echo "Program terminated."
Any help would be greatly appreciated.
Problem here is that the first command in the loop is clear. This removes the output immediately after it was displayed.

RHEL 7 Bash script not recognizing $args

Below is my simple function to get user inputted file name, but for some reason my input validation isn't working.
function getname
{
echo "Please enter the name of the file to install: "
read filename
if (($args > 1))
then
echo "You entered to many arguments."
echo $USAGE
exit
fi
}
getname
Bash -x test1 yields these results, as if it doesn't see any value for $args:
bash -x test1
+ getname
+ echo 'Please enter the name of the file to install: '
Please enter the name of the file to install:
+ read filename
testfile
+ (( > 1 ))
test1: line 9: ((: > 1: syntax error: operand expected (error token is "> 1")
Why isn't this working?
Thanks!
There are many ways to ignore parts after spaces (awk, cut, sed could do the work), and even warning about such thing:
#!/bin/bash
echo "Input filename:"
read input
filename=$(echo $input | awk '{ print $1 }')
echo "Filename entered is: $filename"
[ "${filename}" != "${input}" ] && echo "(warning: parts after spaces were ignored)"
Also, using read conveniently, you could directly read what you want:
read filename garbage
You could consider convert spaces to underscores (or keep spaces as part of filename like windows guys ...):
read input
filename=$(echo $input | tr ' ' '_')
BRs

How To Create Simple Log File From Script

I'm trying to create a simple log file called "users.txt" that contains the username, full name, and home directory of the username entered. I also want to include the time that the script was initially running.
Any suggestions?
The script name is called catbash.sh
I have tried things such as
catbash.sh > user.txt
But I have no idea how to get specific information etc.
clear
LOGFILE=/home/student/gg193/FileTypes/TextFiles/ShellScripts/user.txt
read -p "What is your username?" username
read -p "May I know your name please? " name surname
echo "$(date) $username $name $surname $LOGFILE" >> $LOGFILE
TIME=$(date "+%H")
if [ $TIME -ge 0 -a $TIME -lt 12 ]
then
echo "\nGood Morning, $surname"
elif [ $TIME -ge 12 -a $TIME -lt 18 ]
then
echo "\nGood afternoon $surname"
else
echo "\nGood evening $surname"
fi
echo "1. nonblank\n2. number\n3. ends\n4. nends\n"
while :
do
read INPUT_STRING
case $INPUT_STRING in
nonblank)
NonEmptyLine=$(cat catbash.sh | sed '/^\s*$/d' | wc -l)
echo "\nNumber of Non-Empty Lines are:" $NonEmptyLine
break
;;
number)
EmptyLine=$(grep -cvP '\S' catbash.sh)
echo "\nNumber of Empty Lines are:" $EmptyLine
break
;;
ends)
echo "================================================================================="
sed 's/$/$/' catbash.sh
echo "================================================================================="
break
;;
nends)
NonEmptyLine=$(cat catbash.sh | sed '/^\s*$/d' | wc -l)
echo "\nNumber of Non-Empty Lines are:" $NonEmptyLine
EmptyLine=$(grep -cvP '\S' catbash.sh)
echo "\nNumber of Empty Lines are:" $EmptyLine
echo "================================================================================="
sed 's/$/$/' catbash.sh
echo "================================================================================="
break
;;
*)
echo "\nSorry, I don't understand"
;;
esac
done
DURATION=$(ps -o etime= -p "$$")
echo "\nAmount of time that has passed since the script was initially executed:" $DURATION
echo "\nThanks for using catbash.sh!"
You have to do the logging from inside the sh script. For ex, you could echo the info that you want on the terminal (which you are already doing) and then append | tee -a $LOGFILE (define LOGFILE at the top so you only have to change once if you need a different file name/location).
As further improvements you can look at defining your own logger function or even explore existing ones. For ex a simpler logger func could take 2 args - message, file name. The message itself could be composed of the user name, date/timestamp etc as you want.
With the info currently in your question, this is the best pointer I can give.

Bash: Counting instances of a string in text file with a loop

I am trying to write a simple bash script in which it takes in a text file, loops through the file and tells me how many times a certain string appears in the file. I want to eventually use this for a custom log searcher (for instance, search for the words 'log in' in a particular log file, etc.), but am having some difficulty as I am relatively new to bash. I want to be able to quickly search different logs for different terms at my will and see how many times they occur. Everything works perfectly until I get down to my loops. I think that I am using grep wrong, but am unsure if that is the issue. My loop codes may seem a little strange because I have been at it for a while and have been constantly tweaking things. I have done a bunch of searching but I feel like I am the only one who has ever had this issue (hopefully not because it is incredibly simple and I just suck). Any and all help is greatly appreciated, thanks in advance everyone.
edit: I would like to account for every instance of the string and not just
one instance per line
#!/bin/bash
echo "This bash script counts the instances of a user-defined string in a file."
echo "Enter a file to search:"
read fileName
echo " "
echo $path
if [ -f "$fileName" ] || [ -d "$fileName" ]; then
echo "File Checker Complete: '$fileName' is a file."
echo " "
echo "Enter a string that you would like to count the occurances of in '$fileName'."
read stringChoice
echo " "
echo "You are looking for '$stringChoice'. Counting...."
#TRYING WITH A WHILE LOOP
count=0
cat $fileName | while read line
do
if echo $line | grep $stringChoice; then
count=$[ count + 1 ]
done
echo "Finished processing file"
#TRYING WITH A FOR LOOP
# count=0
# for i in $(cat $fileName); do
# echo $i
# if grep "$stringChoice"; then
# count=$[ $count + 1 ]
# echo $count
# fi
# done
if [ $count == 1 ] ; then
echo " "
echo "The string '$stringChoice' occurs $count time in '$fileName'."
elif [ $count > 1 ]; then
echo " "
echo "The string '$stringChoice' occurs $count times in '$fileName'."
fi
elif [ ! -f "$fileName" ]; then
echo "File does not exist, please enter the correct file name."
fi
To find and count all occurrences of a string, you could use grep -o which matches only the word instead of the entire line and pipe the result to wc
read string; grep -o "$string" yourfile.txt | wc -l
You made basic syntax error in the code. Also, the variable of count was never updating as the the while loop was being executed in a subshell and thus the updated count value was never reflecting back.
Please change your code to the following one to get desired result.
#!/bin/bash
echo "This bash script counts the instances of a user-defined string in a file."
echo "Enter a file to search:"
read fileName
echo " "
echo $path
if [ -f "$fileName" ] ; then
echo "File Checker Complete: '$fileName' is a file."
echo " "
echo "Enter a string that you would like to count the occurances of in '$fileName'."
read stringChoice
echo " "
echo "You are looking for '$stringChoice'. Counting...."
#TRYING WITH A WHILE LOOP
count=0
while read line
do
if echo $line | grep $stringChoice; then
count=`expr $count + 1`
fi
done < "$fileName"
echo "Finished processing file"
echo "The string '$stringChoice' occurs $count time in '$fileName'."
elif [ ! -f "$fileName" ]; then
echo "File does not exist, please enter the correct file name."
fi

Resources