0

I'm working on this script to check pricing. It gets to line 16 and shoots an error.

#!/bin/bash

echo "   Date        Time     Price"
echo "-----------------------------"
while [ true ]
do

new_price=$(curl -s "https://coinbase.com/api/v1/prices/spot_rate" | jq -r ".amount")

balance=0.000001

if [ -z $current_price ]; then
current_price=0
fi

if [ $current_price < $new_price ]; then
ARROW="+"
else if [ $current_price > $new_price ]; then
ARROW="-"
else
ARROW="="
fi
fi

echo "$(date '+%m/%d/%Y | %H:%M:%S') | $new_price | $ARROW"

current_price=$new_price
sleep 30
done

Outputs error

-PC:~/scripts/ticker$ ./arrows.sh
   Date        Time     Price
-----------------------------
./arrows.sh: line 16: 7685.00: No such file or directory
11/17/2017 | 15:45:28 | 7685.00 | -

And this is the verbose

-PC:~/scripts/ticker$ bash -x ./arrows.sh
+ echo '   Date        Time     Price'
   Date        Time     Price
+ echo -----------------------------
-----------------------------
+ '[' true ']'
++ curl -s https://coinbase.com/api/v1/prices/spot_rate
++ jq -r .amount
+ new_price=7685.00
+ balance=0.000001
+ '[' -z ']'
+ current_price=0
+ '[' 0 ']'
+ ARROW=+
++ date '+%m/%d/%Y | %H:%M:%S'
4

Replace:

if [ $current_price < $new_price ]; then
ARROW="+"
else if [ $current_price > $new_price ]; then
ARROW="-"
else
ARROW="="
fi
fi

With:

if echo "$current_price < $new_price" | bc | grep -q 1; then
    ARROW="+" 
elif  echo "$current_price > $new_price" | bc | grep -q 1; then
    ARROW="-"
else
    ARROW="="
fi

In test ([), the operator for numeric less-than comparison is -lt not <. (This is because < is for input redirection.) Thus, if your prices were integers, you could use:

if [ "$current_price" -lt "$new_price" ]; then

But, your prices are floating point so we need bc or equivalent to do the math. bc prints 1 if a logical condition is true and 0 if it is false. We follow that with grep -q 1 which sets a proper return code that if can use.

Also, note that bash supports elif which provides simpler syntax than else if. Lastly, many users think that indentation makes bash commands like if-then-else-fi easier to read.

1

I hate if's, so, if I can avoid them:

arrows=('=' '<' '>')
ARROW=${arrows[$(echo "c=$current_price;n=$new_price;(c<n)+2*(c>n)" | bc)]} 

In slow-motion: c=$current_price;n=$new_price;(c<n)+2*(c>n) returns 0, 1 or 2, if the values are equal, smaller, or bigger. This is used to index the array of symbols.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.