Valutazione discussione:
  • 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5
  Condividi: Facebook Twitter
[Risolto] Lo script bash non esegue il ciclo while
#1
Volendo "croppare" i files multimediali elencati in un flle "lista.txt" presenti in una cartella di lavoro, ho pensato di far fare il lavoro allo script seguente
Codice:
#!/bin/bash
while read -r IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    XY="crop="$X":"$Y":$X1:$Y1" # Imposta i parametri di crop
    ffmpeg -i $IN -vf $XY -acodec copy $OUT
done < lista.txt
che, per qualche motivo che non comprendo, elabora solo il primo file della lista, come se non eseguisse il ciclo wile
Qualcuno ha idea di come dovrei correggere lo script per far sì che vengano elaborati tutti i files multimediali elencati nella lista?
ringrazio sin d'ora chi mi aiuterà.
Cita messaggio
#2
Hai necessità di inserire in fondo allo script un parametro che modifichi la variabile che indica il numero file da elaborare del tipo:
Codice:
numero_flie_da_eseguire =(numero-file_da_eseguire +1)
Cita messaggio
#3
(22/10/2023, 11:11)m3nhir Ha scritto: Hai necessità di inserire in fondo allo script un parametro che modifichi la variabile che indica il numero file da elaborare del tipo:
Codice:
numero_flie_da_eseguire =(numero-file_da_eseguire +1)
Ciao M3nhir.
Non capisco cosa intendi dire...
per quanto ne so, il ciclo while legge le righe una alla volta, quindi, se nella lista ci sono 3 nomi, il ciclo viene eseguito 3 volte.
Inoltre, se modifico lo script per visualizzare la riga contenente il comando ffmpeg senza eseguirla, essa viene visualizzata 3 volte.
Cita messaggio
#4
Non conosco l'opzione "-r" per il comando "read" (non ne trovo traccia nelle pagine man). per spiegarti cosa intendo ti posto un mio vecchio script che usavo per scaricare filmati da un sito (solo quelli che mi interessavano fra i tanti) che avevano un nome_file in sequenza. Magari può aiutarti a capire cosa intendo.
Codice:
#!/bin/bash
#
#script per l'uso di wget in sequenza
#inserisco l'indirizzo del file e i suoi eventuali numeri
#p. es. www.sito/file180_1:mpg
#
EXIT_SUCCESS=0
#
echo "inserire indirizzo"
read ADDRESS
echo "inserire primo numero"
read NUM1
echo "inserire eventuale spaziatore tra numeri"
read SPACE
echo "inserire numero massimo file"
read NUM2
echo "inserire numero di partenza"
read NUM
#
nuovo_file ()    {
while [ $NUM \< $NUM2 ]
do
wget $ADDRESS$NUM1$SPACE$NUM.mpg
NUM=$(( $NUM + 1 ))
done
}
#
while nuovo_file; do
NUM1=$(( $NUM1 + 1 ))
NUM=1
done
#
Cita messaggio
#5
Ciao Ciao m3nhir.
In effetti, la presenza o meno del parametro [-r] non cambia il risultato, quindi l'ho tolto.
Ora il mio listato è
Codice:
#!/bin/bash
while read IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    XY="crop="$X":"$Y":$X1:$Y1" # Imposta i parametri di crop
    echo ffmpeg -i $IN -vf $XY -acodec copy $OUT >> output01.txt
    # ffmpeg -i $IN -vf $XY -acodec copy $OUT
done < lista.txt
(altre differenze dal precedente listato: le righe contenenti il comando ffmpeg ora sono 2: una preceduta da [echo] e seguita da [>> output01.txt], e l'altra #commentata, in modo che non venga eseguita)
Se io avvio lo script suddetto, ottengo un file di testo chiamato output01.txt contenente le 3 righe seguenti:
Codice:
ffmpeg -i 20231005_224603.mp4 -vf crop=720:480:300:100 -acodec copy elaborato-20231005_224603-crop.mp4
ffmpeg -i 20231012_223758.mp4 -vf crop=720:480:300:100 -acodec copy elaborato-20231012_223758-crop.mp4
ffmpeg -i 20231019_230246.mp4 -vf crop=720:480:300:100 -acodec copy elaborato-20231019_230246-crop.mp4
e fin qui ci siamo.
Quindi, se cancello il file di testo chiamato output01.txt, tolgo il commento all'altra riga contenente il comando ffmpeg, e ri-avvio lo script, nella cartella di lavoro, assieme ai files pre-esistenti, mi aspetto di trovare un nuovo file di testo chiamato output01.txt avente il medesimo contenuto del precedente file di testo omonimo, più i 3 nuovi files mp4 croppati, invece, accanto ai files pre-esistenti, trovo solo un nuovo file di testo chiamato output01.txt contenente unicamente la riga
Codice:
ffmpeg -i 20231005_224603.mp4 -vf crop=720:480:300:100 -acodec copy elaborato-20231005_224603-crop.mp4

più elaborato-20231005_224603-crop.mp4

come se la prima esecuzione del comando ffmpeg avesse provocato la fine anticipata del ciclo while. 0032
Perché?
Cita messaggio
#6
Prova a spostare in alto nello script la riga di ffmpeg, portandola sopra a quella echo
Cita messaggio
#7
(22/10/2023, 18:47)m3nhir Ha scritto: Prova a spostare in alto nello script la riga di ffmpeg, portandola sopra a quella echo
Fatto. Il risultato non cambia.
Se nella cartella di lavoro metto lo script contenente
Codice:
#!/bin/bash
while read IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    XY="crop="$X":"$Y":$X1:$Y1" # Imposta i parametri di crop
    ffmpeg -i $IN -vf $XY -acodec copy $OUT
    echo ffmpeg -i $IN -vf $XY -acodec copy $OUT >> output01.txt
done < lista.txt
nella cartella di lavoro, assieme ai files pre-esistenti, trovo file di testo chiamato output01.txt contenente un'unica riga, più l'unifo file mp4 croppati corrispondente.
Evidentemente, il comando ffmpeg non provoca l'interruzione dello script, ma la fine del ciclo while.

---
edit:
ho provato anche lo script
Codice:
#!/bin/bash
while read IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    XY="crop="$X":"$Y":$X1:$Y1" # Imposta i parametri di crop
    COMANDO='ffmpeg -i '$IN' -vf '$XY' -acodec copy '$OUT
    echo $COMANDO  >> output01.txt
    $COMANDO
    echo "Questo messaggio viene visualizzato per 3 secondi"; sleep 3
done < lista.txt
echo "Altro messaggio visualizzato per 3 secondi"; sleep 3

stesso risultato.
Cita messaggio
#8
Se ho ben capito la variabile $IN contiene l'elenco di tutti i files da modificare.
Secondo me è quello il problema. ffmpeg probabilmente non accetta quel tipo di input.
Potresti provare da usare "for" per ottenere quello che vuoi  (anche all'interno di un ciclo  while)
https://wwwcdf.pd.infn.it/AppuntiLinux/a...lindex5904
Cita messaggio
#9
(22/10/2023, 19:50)m3nhir Ha scritto: Se ho ben capito la variabile $IN contiene l'elenco di tutti i files da modificare.
Secondo me è quello il problema. ffmpeg probabilmente non accetta quel tipo di input.
Potresti provare da usare "for" per ottenere quello che vuoi  (anche all'interno di un ciclo  while)
https://wwwcdf.pd.infn.it/AppuntiLinux/a...lindex5904
Si, ma non contemporaneamente.
La variabile $IN contiene il nome di tutti i files da modificare, ma non contemporaneamente, bensì uno alla volta.
tant'è che lo script
Codice:
!/bin/bash
echo "#!/bin/bash"  > ESEGUE.txt
while read IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    COMANDO='ffmpeg -i '$IN' -vf crop='$X':'$Y':'$X1':'$X2' -acodec copy '$OUT # Costruisce il comando
    echo $COMANDO  >> ESEGUE.txt # Crea script intermedio
    # $COMANDO # Questo comando, se eseguito, termina il ciclo while
done < lista.txt
./ESEGUE.txt
funziona, ma mi sembra strano che si debba per forza creare uno script intermedio...
Ma forse è un problema proprio del ciclo while... cercherò qualche alternativa ...

---
edit
---
il ciclo until non fornisce risultati diversi...
Lo script
Codice:
#!/bin/bash
# ./elaboraLista02.txt
echo "#!/bin/bash"  > ESEGUE.txt
COUNTER=3
until [  $COUNTER -lt 1 ]; do
    read IN
    echo $IN
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    COMANDO='ffmpeg -i '$IN' -vf crop='$X':'$Y':'$X1':'$X2' -acodec copy '$OUT # Costruisce il comando
    echo $COMANDO  >> ESEGUE.txt
    $COMANDO # Questo comando, se eseguito, termina il ciclo until
done < lista.txt
# ./ESEGUE.txt
ha il medesimo problema... in più, se avviato da terminale, mostra la riga
Codice:
./elaboraLista02.txt: riga 8: -4: expressione di sottostringa < 0

---
edit
---
Nemmeno il ciclo for fornisce risultati diversi...
lo script
Codice:
#!/bin/bash
# ./elaboraLista03.txt
echo "#!/bin/bash"  > ESEGUE.txt
COUNTER=3
for COUNTER in `seq 1 3`; do
    read IN
    echo $IN
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0)) # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2)) # Imposta la larghezza del file audiovisivo elaborato
    X1=300 # Imposta la distanza dal lato sinistro
    Y1=100 # Imposta la distanza dal lato superiore
    COMANDO='ffmpeg -i '$IN' -vf crop='$X':'$Y':'$X1':'$X2' -acodec copy '$OUT # Costruisce il comando
    echo $COMANDO  >> ESEGUE.txt
    $COMANDO # Questo comando, se eseguito, termina il ciclo for
done < lista.txt
# ./ESEGUE.txt
ha il medesimo problema... e anche questo, se avviato da terminale, mostra la riga

Codice:
./elaboraLista03.txt: riga 8: -4: expressione di sottostringa < 0
Se nessuno ha un'idea su cos'hanno che non va questi 3 script, mi sa che mi dovrò accontentare della soluzione con script intermedio.
Cita messaggio
#10
[quote pid="18555" dateline="1698003607"]

Codice:
./elaboraLista03.txt: riga 8: -4: expressione di sottostringa < 0
Se nessuno ha un'idea su cos'hanno che non va questi 3 script, mi sa che mi dovrò accontentare della soluzione con script intermedio.
[/quote]
A cosa serve il parametro "-4"? potrebbe essere la causa dell'errore (forse non viene correttamente interpretato)
Cita messaggio


Vai al forum:


Utenti che stanno guardando questa discussione: 3 Ospite(i)