2 votos

convertir o parsear float a int en bash script falla de varias maneras

Tenemos:

MINUTES_UNTIL_ASK_TO_CLOSE="0,2"
number_of_iterations=$((MINUTES_UNTIL_ASK_TO_CLOSE * 60 / 5))

Hay un par de comportamientos extraños al hacer eso.

En primer lugar, el resultado debería ser:

número_de_iteraciones = 0,2 * 60 / 5 = 2,4

Sin embargo, la salida de: echo "number_of_iterations" $((MINUTES_UNTIL_ASK_TO_CLOSE * 60 / 5)) es:

24

En segundo lugar, quiero usarlo en el bucle for ((a=1; a<=$number_of_iterations; a++)); do debe ser un número entero. Así que en realidad la salida final deseada es:

2

¿Cómo hacer este redondeo de variables de float a int en applescript correctamente?

He probado lo siguiente, pero se bloquea el script:

echo "number_of_iterations" $((round(MINUTES_UNTIL_ASK_TO_CLOSE * 60 / 5))

Después de los comentarios pidiendo que lo aclare y lo muestre entero, me alegra compartir el script completo. Funciona (siéntete libre de usarlo por ti mismo) si pones DEFAULT_MINUTES_1 con un int como DEFAULT_MINUTES_1="1" . Falla si pongo un flotador como: DEFAULT_MINUTES_1="0,2" . Tampoco funciona si lo hago: DEFAULT_MINUTES_1="0.2"

#!/bin/bash

PROCESS_NAME="Telegram" 

DIALOG_TEXT_1="Minutes to remember to close $PROCESS_NAME:"
BUTTON_TEXT_OPEN_1="Open $PROCESS_NAME"
BUTTON_TEXT_CLOSE_1="Close $PROCESS_NAME & take a break"
DEFAULT_MINUTES_1="0,2"

DIALOG_TEXT_2="Minutes to remember to close $PROCESS_NAME:"
BUTTON_TEXT_OPEN_2="Keep Open $PROCESS_NAME"
BUTTON_TEXT_CLOSE_2="Close $PROCESS_NAME & take a break"
DEFAULT_MINUTES_2="0,2"

osascript -e 'tell application "Terminal" to set visible of front window to true'

# Got help from here: https://apple.stackexchange.com/q/458152/177042 and here: https://apple.stackexchange.com/q/460004/177042
DIALOG_RESULTS="$(osascript -e 'set {T,B} to {text returned, button returned} of (display dialog "'"$DIALOG_TEXT_1"'" default answer "'"$DEFAULT_MINUTES_1"'" with icon caution buttons {"'"$BUTTON_TEXT_OPEN_1"'", "'"$BUTTON_TEXT_CLOSE_1"'"} default button 2)' -e 'return T & "\t" & B')" &&MINUTES_UNTIL_ASK_TO_CLOSE="$(echo "$DIALOG_RESULTS" |cut -f 1)" &&BUTTON_RETURNED="$(echo "$DIALOG_RESULTS" |cut -f 2)"

echo "DIALOG_RESULTS" $DIALOG_RESULTS
echo "MINUTES_UNTIL_ASK_TO_CLOSE" $MINUTES_UNTIL_ASK_TO_CLOSE
echo "BUTTON_RETURNED" $BUTTON_RETURNED

MINUTES_APP_OPENED=$(($MINUTES_UNTIL_ASK_TO_CLOSE))

if [ "$BUTTON_RETURNED" = "$BUTTON_TEXT_OPEN_1" ] ; then
    open -a "$PROCESS_NAME"
else 
    exit
fi

echo "number_of_iterations" $((MINUTES_UNTIL_ASK_TO_CLOSE * 60 / 5))

for ((i=0; i<=1000; i++)); do

    # Sleep during the time indicated on the variable: MINUTES_UNTIL_ASK_TO_CLOSE
    # But each 5 seconds, checks if the app has been closed or not to close this terminal if so     
    number_of_iterations=$((MINUTES_UNTIL_ASK_TO_CLOSE * 60 / 5))
    for ((a=1; a<=$number_of_iterations; a++)); do
        if pgrep "$PROCESS_NAME"; then
            sleep 5
        else
            exit
        fi
    done

    MINUTES_APP_OPENED=$((MINUTES_APP_OPENED+$MINUTES_UNTIL_ASK_TO_CLOSE*$i))
    echo "----"
    echo
    echo "$PROCESS_NAME has been openened during $MINUTES_APP_OPENED minutes"
    DIALOG_RESULTS="$(osascript -e 'set {T,B} to {text returned, button returned} of (display dialog "'"$DIALOG_TEXT_2"'" default answer "'"$DEFAULT_MINUTES_2"'" with icon caution buttons {"'"$BUTTON_TEXT_OPEN_2"'", "'"$BUTTON_TEXT_CLOSE_2"'"} default button 1)' -e 'return T & "\t" & B')" &&MINUTES_UNTIL_ASK_TO_CLOSE="$(echo "$DIALOG_RESULTS" |cut -f 1)" &&BUTTON_RETURNED="$(echo "$DIALOG_RESULTS" |cut -f 2)"

    echo "In $MINUTES_UNTIL_ASK_TO_CLOSE minutes, you will be asked again if you want close $PROCESS_NAME "

    if [ "$BUTTON_RETURNED" = "$BUTTON_TEXT_CLOSE_2" ] ; then
        pkill -x "$PROCESS_NAME"
        echo "OK pressed. $PROCESS_NAME should be closed now"
        exit
    else
        echo "Cancel pressed. $PROCESS_NAME won't be killed... Yet :D"
        echo
        echo "----"
    fi
done

exit

2voto

No se pueden realizar operaciones matemáticas en coma flotante directamente en los scripts del shell, consulte la sección "evaluación aritmética" en man bash para más detalles.

Puede utilizar bc en su lugar (véase https://stackoverflow.com/questions/14222250/floating-point-arithmetic-in-unix-shell-script ), pero para tu script eso es demasiado complicado. Es mejor utilizar segundos en lugar de minutos para todos los números y ajustar los cálculos en consecuencia. Si quieres dar a los usuarios la oportunidad de seguir introduciendo minutos, simplemente multiplícalo por 60 después.

PD: Algunos comentarios más sobre tu código:

  • Parece que no utiliza el i del bucle exterior, por lo que podría sustituir for ((i=0; i<=1000; i++)); do con while true; do para obtener un bucle sin fin.
  • MINUTES_APP_OPENED=$(($MINUTES_UNTIL_ASK_TO_CLOSE)) sólo sería necesario si MINUTES_UNTIL_ASK_TO_CLOSE es una expresión aritmética como 5*12 . No estoy seguro de lo que espera que los usuarios introduzcan en el cuadro de diálogo, pero si la entrada es sólo un número, MINUTES_APP_OPENED=MINUTES_UNTIL_ASK_TO_CLOSE lo hará.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X