BASH comparando o erro de cadeias / inteiros

0

Estou trabalhando neste script para verificar os preços. Chega à linha 16 e dispara um erro.

#!/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

Saídas de erro

-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 | -

E este é o verboso

-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'

Por favor, ajude!

    
por b1sr4t 17.11.2017 / 22:51

2 respostas

4

Substituir:

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

Com:

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

No teste ( [ ), o operador para comparação numérica menor do que a comparação é -lt não < . (Isso ocorre porque < é para redirecionamento de entrada.) Assim, se seus preços fossem inteiros, você poderia usar:

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

Mas, seus preços são de ponto flutuante, então precisamos de bc ou equivalente para fazer as contas. bc imprime 1 se uma condição lógica for verdadeira e 0 se for falsa. Seguimos isso com grep -q 1 , que define um código de retorno adequado que if pode usar.

Além disso, observe que o bash suporta elif , que fornece uma sintaxe mais simples do que else if . Por fim, muitos usuários acham que o recuo torna os comandos bash como if-then-else-fi mais fáceis de ler.

    
por 17.11.2017 / 23:07
1

Eu odeio if , então, se eu puder evitá-los:

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

Em câmera lenta: c=$current_price;n=$new_price;(c<n)+2*(c>n) retorna 0, 1 ou 2, se os valores forem iguais, menores ou maiores. Isso é usado para indexar a matriz de símbolos.

    
por 18.11.2017 / 01:13