Как правильно протестировать команду как переменную, содержащую пробелы?

Здесь уже есть хорошие и более информированные ответы, но я просто хотел отметить, что с sleep у вас есть возможность заморозить процесс на переменное время, скажем, как функцию некоторых других переменных.

Если я пишу скрипт для проверки заряда батареи в процентах и notify-send, если он ниже заданного критического уровня, я могу сделать скрипт sleep на время, которое является функцией текущего уровня батареи в процентах, вместо того, чтобы проверять батарею каждые одну-две минуты с помощью cron, даже если я знаю, что при последней проверке он был 80%.

Battery_notify.sh

#!/bin/bash
CRIT=15
while true; do
    # current battery level
    BAT_LEVEL=`acpi -b |grep -Eo "[0-9]+%"|grep -Eo "[0-9]+"`
    interval=$((($BAT_LEVEL -$CRIT) * 120)) # loose estimate of backup time for each percentage of battery charge.
    # Is AC plugged in?
    state=`acpi -b |grep -Eo "[A-Za-z]+harging"` 
    #only notify if not Plugged in
    if [ "$state" = "Discharging" ] ; then
        # is battery below CRIT level?
        if [ $BAT_LEVEL -le $CRIT ]; then
        aplay ~/apert.wav &
        notify-send "Battery-Low!!!" -i /home/bibek/batt.png -t 900
        sleep 100  # nag me each 100 secs untill I plug the thing 
        else
            sleep $interval
        fi
    else
        # if plugged in sleep 
        if [ $BAT_LEVEL -le $CRIT ]; then
            sleep $interval
        else
            # to check if the AC is unplugged before battery gains charge above CRIT.
            sleep 100 
        fi
    fi
    done
1
25.11.2018, 16:39
3 ответа

No estoy seguro de por qué querrías hacer esto, pero aquí hay una solución que funciona:

FILEPATH=/home/Documents/projectDirectory
CREATE_DIRECTORY="mkdir $FILEPATH 2>/dev/null"
eval $CREATE_DIRECTORY
if [[ $? -eq 0 ]]; then
 echo "Directory created"
else
 echo "Directory already exists"
fi

Esto intentará crear la carpeta y canalizar cualquier mensaje de error a /dev/null (sin mostrarlo ). Luego verifica el estado del comando anterior en la declaración if y si fue exitoso (0 ), luego se lo dice.

0
28.01.2020, 00:39

Su código actual tiene los siguientes defectos:

  • CREATE_DIRECTORY=mkdir $FILEPATH:
    1. Dado que no hay comillas alrededor de mkdir $FILEPATH, CREATE_DIRECTORYsolo tiene mkdircomo su valor.
    2. $FILEPATHestá sujeto a división de palabras.
    3. La variable CREATE_DIRECTORYpuede exportarse al entorno de la expansión resultante de $FILEPATHsi el primer token de dicha expansión es un comando externo.
  • [ -e "${CREATE_COMMAND}" ]:
    1. La variable CREATE_COMMANDno tiene valor, hasta donde sabemos. Supongo que quisiste escribir CREATE_DIRECTORY.
    2. No prueba si mkdirtuvo éxito o no.

Además, el comando compuesto ifpodría usarse para probar si un comando tuvo éxito o no:

if command; then
  # Code to execute if command succeeded
else
  # Code to execute if command failed
fi

Entonces su código podría reescribirse como:

FILEPATH=/home/Documents/projectDirectory

if [ -e "${FILEPATH}" ]; then
    echo "${FILEPATH} exists..."
else
    if mkdir "${FILEPATH}"; then
        echo "File created ${FILEPATH}"
    else
        echo "Error creating the filePath..exiting.."
        error_exit "Error creating the filePath..exiting.."
    fi
fi

Tenga en cuenta que:

  1. La variable CREATE_DIRECTORYno es necesaria.
  2. [ -e "${CREATE_COMMAND}" ]fue reemplazado por mkdir "${FILEPATH}".
0
28.01.2020, 00:39

Realmente no veo por qué no puedes simplemente hacer

dir='/home/Documents/projectDirectory'

if ! mkdir "$dir"; then
    printf 'Something went wrong when trying to create "%s"\n' "$dir" >&2
    exit 1
fi

printf '"%s" created, now doing other things...\n' "$dir"

La llamada a mkdirfallará si $dirya existe.

Si necesita permitir que exista el directorio y solo rescatar si mkdirno puede crearlo, agregue -pa la llamada mkdiranterior, o realice una prueba explícita de la existencia del directorio:

dir='/home/Documents/projectDirectory'

if [ ! -d "$dir" ]; then
    if ! mkdir "$dir"; then
        printf 'Something went wrong when trying to create "%s"\n' "$dir" >&2
        exit 1
    fi

    printf '"%s" created\n' "$dir"
fi

echo 'now doing other things...'

Estoy usando la prueba -daquí para probar si $dirpuede ser un directorio. Hago esto porque asumo que el resto del script requerirá que el nombre no solo exista sino que se refiera a un directorio real.


No intente almacenar comandos en variables,rara vez es lo que necesitas hacer. No es una buena manera de ahorrar en escribir cosas. Si necesita una forma más corta de realizar una acción en un script de shell, cree una función de shell para ello.

Además, adquiera el hábito de siempre duplicar -sus expansiones variables. De esa manera, sus scripts de shell siempre manejarán correctamente los nombres de archivo con espacios en ellos y nunca invocarán accidentalmente el englobamiento de nombres de archivo.

Relacionado:


Otras cosas:

CREATE_DIRECTORY=mkdir $FILEPATH

Esto ejecutará $FILEPATHcomo un comando con CREATE_DIRECTORY=mkdiren su entorno. Fallará porque $FILEPATHes un directorio (si existe )o al menos no es un comando.

Para crear una variable con espacios en su valor, entre comillas el valor.

La línea

if [ -e "${CREATE_COMMAND}" ]; then

no creará un directorio. Probará si el valor en $CREATE_COMMANDcorresponde a un nombre en la jerarquía de archivos.

No sé qué es error_exit, pero probablemente sea una forma abreviada de un simple echoy exit 1o similar, ¿verdad?

0
28.01.2020, 00:39

Теги

Похожие вопросы