es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué mi bucle for no está iterando en el Shell de Linux?

Estoy intentando ejecutar una secuencia alfabética en la terminal de Linux. Creo que mi sintaxis es correcta, pero en lugar de darme cada letra, me muestra todas juntas {a..z}. Esto es lo que tengo:

“`shell
COUNTER=0;
for X in {a..z};
do
# Asegurarse de que el USB esté montado antes de hacer algo
sudo mkdir /media/mounts/sd${X}1
sudo mount /dev/sd${X}1 /media/mounts/sd${X}1

Encontrar el número del dispositivo a partir del punto de montaje en Linux

DATA_DIR=/media/mounts/sd${X}1;
PLAYER_FILE_PATH=find $DATA_DIR -name "player.*";
PLAYER_FILE_ONLY=basename -- $PLAYER_FILE_PATH;
PLAYER_NUMBER=echo "${PLAYER_FILE_ONLY##*.}";

Asegurarse de que el dispositivo USB exista y el número del reproductor no esté vacío

if [ -n "$PLAYER_NUMBER" ] && [ $PLAYER_NUMBER -gt 0 ]
then
# Informar al usuario qué trazador se encontró
echo "Se encontró el trazador $PLAYER_NUMBER, creando directorio para almacenar sus archivos .dat" | tee -a $ERR_LOG_PATH;
echo "${PLAYER_NUMBER}: " >> $LOG_PATH;
let COUNTER++;

# Crear directorio para el número del reproductor y volcar los archivos .dat, y registrar cualquier error en la salida
sudo mkdir $DUMP_DIR/$PLAYER_NUMBER;
NUMBER_DATS=`ls $DATA_DIR/MountsData/*.dat | wc -l`;
DAT_COUNT_ARRAY[$PLAYER_NUMBER]=$NUMBER_DATS
echo "El USB $PLAYER_NUMBER tiene $NUMBER_DATS archivos .dat";
echo "${NUMBER_DATS}\r\n" >> $LOG_PATH;
cp $DATA_DIR/MountsData/*.dat $DUMP_DIR/$PLAYER_NUMBER 2>> $ERR_LOG_PATH;

# Eliminar todos los archivos .dat directamente del USB y registrar cualquier error en la salida
sudo rm $DATA_DIR/MountsData/*.dat 2>> $ERR_LOG_PATH;

fi
“`shell

He intentado cambiar los nombres de las variables, la capitalización y referirme a ellas como $X en lugar de ${X}. Actualmente estoy usando una Raspberry Pi con Raspbian y una terminal estándar de Raspbian. Ejecuté algunas pruebas para asegurarme de que la sintaxis fuera correcta en la terminal y parece que la estructura del bucle for es correcta. ¿Me estoy perdiendo algo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema parece estar en la línea for X in {a..z};. El uso de llaves con .. es una forma abreviada de especificar un rango en la expansión de llaves. En este caso, se está expandiendo al rango del alfabeto de la ‘a’ a la ‘z’. Sin embargo, no se reconoce como un nombre de dispositivo válido en el comando mount subsiguiente.

    Para solucionar este problema, puedes especificar manualmente el rango de nombres de dispositivos que quieres verificar. Por ejemplo, si solo deseas verificar sda, sdb y sdc, puedes reemplazar el bucle for con for X in a b c; do y luego reemplazar todas las instancias de ${X} con sd${X}. Esto recorrerá los nombres de dispositivo sda1, sdb1, y sdc1.

    Alternativamente, puedes usar un bucle que verifique todos los dispositivos disponibles utilizando el comando lsblk para listar todos los dispositivos de bloque disponibles, luego filtrar los que no son extraíbles (es decir, los que son parte del sistema) y luego recorrer los que quedan. Aquí tienes un ejemplo:

    CONTADOR=0;
    for devpath in $(lsblk -rpo PATH,NAME | awk '$1 !~ /^(\/|\/dev\/loop)/ { print $1,$2 }');
    do
        # Extraer el nombre del dispositivo como sda, sdb, etc.
        devname=$(echo $devpath | awk '{ print $2 }' | sed 's/.$//')
    
        # Omitir si no es un dispositivo extraíble
        if ! [[ $(cat /sys/block/$devname/removable) -eq 1 ]] ; then
            continue
        fi
    
        # Asegurarse de que usb esté montado antes de intentar cualquier cosa
        sudo mkdir /media/mounts/$devname
        sudo mount $devpath /media/mounts/$devname
    
        # Encontrar el número de jugador a partir del punto de montaje de Linux
        DATA_DIR=/media/mounts/$devname;
        PLAYER_FILE_PATH=`find $DATA_DIR -name "player.*"`;
        PLAYER_FILE_ONLY=`basename -- $PLAYER_FILE_PATH`;
        PLAYER_NUMBER=`echo "${PLAYER_FILE_ONLY##*.}"`;
    
        # Asegurarse de que el dispositivo usb exista y el número de jugador no esté vacío
        if [ -n "$PLAYER_NUMBER" ] && [ $PLAYER_NUMBER -gt 0 ]
        then
            # Informar al usuario qué rastreador se encontró
            echo "$PLAYER_NUMBER se encontró, creando directorio para almacenar sus archivos .dat" | tee -a $ERR_LOG_PATH;
            echo "${PLAYER_NUMBER}: " >> $LOG_PATH;
            let CONTADOR++;
    
            # Crear directorio para el número de jugador para volcar archivos .dat y registrar cualquier error en la salida
            sudo mkdir $DUMP_DIR/$PLAYER_NUMBER;
            NUMBER_DATS=`ls $DATA_DIR/MountsData/*.dat | wc -l`;
            DAT_COUNT_ARRAY[$PLAYER_NUMBER]=$NUMBER_DATS
            echo "USB $PLAYER_NUMBER tiene $NUMBER_DATS archivos .dat";
            echo "${NUMBER_DATS}\r\n" >> $LOG_PATH;
            cp $DATA_DIR/MountsData/*.dat $DUMP_DIR/$PLAYER_NUMBER 2>> $ERR_LOG_PATH;
    
            # Eliminar todos los archivos .dat directamente del usb y registrar cualquier error en la salida
            sudo rm $DATA_DIR/MountsData/*.dat 2>> $ERR_LOG_PATH;
        fi
    
        # Desmontar el dispositivo después de procesarlo
        sudo umount $devpath
    done
    

    Esto recorrerá todos los dispositivos extraíbles de bloque que no forman parte del sistema, montará cada uno, lo procesará según sea necesario y luego lo desmontará.

Comments are closed.