Newsgroup: it.comp.os.linux.iniziare
Titolo: sito di verifica per shellscript

navigando tra i link di stumbleupon ho trovato questo sito:
 
http://www.shellcheck.net/
 
automatically detects problems with sh/bash scripts and commands.
 
mi sembra utile, che ne pensate?
 
io ho provato a far esaminare un semplicissimo script di una riga sola 
(non sono una cima con la bash)
 
for f in *.mp3; do ffmpeg -i $f -ar 8000 -ab 8k ${f%.mp3}-8k.mp3; done
 
e i suggerimenti sono stati di aggiungere i doppi apici
 
*Double quote to prevent globbing and word splitting*
 
for f in *.mp3; do "ffmpeg -i $f -ar 8000 -ab 8k ${f%.mp3}-8k.mp3"; done
 
mi pare utile per chi è all'abc degli script
-- 
Puppy Linux wiki:  
http://dokupuppylinux.info
 
Puppy Linux Forum: 
http://www.italianpuppy.org/
 
Windows me genuit, Ubuntu rapuere / tenet nunc Puppy Linux...
dropbox 2GB free - 
http://db.tt/Vc6IeN4
 

 mi sembra utile, che ne pensate?
 
 
Un altro LINT per la BASH? Ok, bene ma priman passa da Greg:
 
http://mywiki.wooledge.org/BashPitfall
 
 
PS Perché non scarichi il lint? Mi pare più semplice e veloce
 
--- news://
freenews.netfront.net/
 - complaints: 
ne...@netfront.net
 ---

 mi pare utile per chi è all'abc degli script
 
  Almeno in questo caso però da consigli del menga:
 
alessandro@hal9k ~ $ for I in uno due tre ; do echo Un cammello con $I
passeggero ; done
Un cammello con uno passeggero
Un cammello con due passeggero
Un cammello con tre passeggero
alessandro@hal9k ~ $ for I in uno due tre ; do "echo Un cammello con $I
passeggero" ; done
-bash: echo Un cammello con uno passeggero: command not found
-bash: echo Un cammello con due passeggero: command not found
-bash: echo Un cammello con tre passeggero: command not found
alessandro@hal9k ~ $
 
  Si lascia come esercizio la determinazione della causa dell'errore.
 
 
  Ciao,
 
 
-- 
Alessandro Selli 
http://alessandro.route-add.net
 
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.

   Si lascia come esercizio la determinazione della causa dell'errore.
 
http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29
 



 
Semmai i doppi apici li metterei attorno a $f in modo da prevenire i 
file che hanno spazio nel nome
Metterli prima di ffmpeg non ha alcun senso logico
 

 Metterli prima di ffmpeg non ha alcun senso logico
 
Ti ostini a non leggere la Greg's Wiki dove è spiegato per file e 
per segno perché usare le virgolette con il for è inutile e dannoso.


     [ -e "$f" ] || continue
     some command "$f"
done
 
 
 
questa è corretta
 
 

 questa è corretta
 
 
No, non è corretto, è inefficiente, non fuziona con i file MP3 (che
notoriamente contengono spazi nel nome). in poche parole  è un 
costrutto che un analizzatore statico dovrebbe segnalare come 
deprecato.
 
 
 
 


$ > "file .mp3"
$ > "file 1.mp3"
 
$ for f in *.mp3;do echo ">$f<"; done
 >file .mp3<
 >file 1.mp3<
 
$bash -version
GNU bash, versione 4.2.25(1)-release (x86_64-pc-linux-gnu)
 
 
 
 
Cosa ha che non va ?
 
 
 
 
 
 

 Cosa ha che non va ?
 
Semplicemente andrebbe usato in casi molto semplici,
tipo l'esempio proposto da te (o meglio copiato dalla Wiki)
perché già con l'esempio postato dall'OP va un poco stretto
(anche non considerando i bug dell'analizzatore statico)
Io non userei un ``for'' in uno script.
 


Sono d'accordo, meglio un while in pipe (non  ha limitazioni come il for)
Ma dove è che non funziona con i nomi che contengono spazi ?
 

 
È solo usare prudenza: se sai di avere con caratteri strani che danno
problemi (ed i file multimediali sono le peggiori schifezze in circolazione)
usi una soluzione robusta fin dal principio (e il for non è una soluzione
robusta).
 
 


Se  i files non sono molti (fino a 1000 forse) il for non ha problemi
La bash costruisce gli argomenti espandendoli e fino ad una certa 
lunghezza ci va, a parte qualche rallentamento
Oltre è meglio usare altri metodi che sono sia piu veloci e che non 
risentono della lunghezza max tipo un
 
ls | while read; do echo "$REPLY"; done
 
Passando i nomi in pipe la bash non deve costruirsi gli  argomenti in un 
colpo solo
 
 
 
 

 ls | while read; do echo "$REPLY"; done
 
ls per generare una lista di file?   Meglio non discutere con te.
 
 

 ls | while read; do echo "$REPLY"; done
 
ls per generare una lista di file? I cretini prima ti portano al loro
livello e poi ti battono con l'esperienza.

 ls | while read; do echo "$REPLY"; done
 
ls per generare una lista di file? Non ho tempo da perdere.


Cosa è tutta questa offesa ?
E' solo uno dei modi
echo * | while read; ....
 
find . | while read; ...
 
e ne esisteranno altri
 

 e ne esisteranno altri
 
Okay, ma sei sicuro che il "while" sia meglio del ciclo "for"?
Nei manuali per il linguaggio C ho sempre letto il contrario.
Citando ad esempio da qui:
http://www.webmasterpoint.org/programmazione/programmazione/c/for.html
 
 
In effetti si potrebbe dire che l'istruzione while, in C, è
assolutamente inutile, in quanto può essere sempre sostituita dalla for,
la quale, anzi, consente generalmente di ottenere una codifica più
compatta ed efficiente dell'algoritmo. La maggiore compattezza deriva
dalla possibilità di utilizzare contestualmente alla condizione, se
necessario, anche un'istruzione di inizializzazione ed una di
variazione. La maggiore efficienza invece dipende dal comportamento
tecnico del compilatore, il quale, se possibile, gestisce
automaticamente i contatori dei cicli for come variabili register.
 

 automaticamente i contatori dei cicli for come variabili register.
 
E qui si aprirebbe una polemica infinita che però riguarda il linguaggio C
ma siamo già andati troppo fuori tema.



E cosa ha a che fare il for della shell con il for del C ?
 
sono due cose ben diverse
 

 Sono d'accordo, meglio un while in pipe (non  ha limitazioni come il for)
 
Ecco, e` questo che non ho capito: perche` il for non va bene? Quali
sono queste limitazioni che while non ha?
 

 sono queste limitazioni che while non ha?
 
Ma scusa (mi riferisco anche al tuo precedente post) ma son due cose ben
diverse, e for solo in un caso numerico puo' fare come while. For
assegna ad i un elemento alla volta da una lista e poi esegue per ognuno
i comandi, cosa che while non puo' mai fare a meno di farglielo fare noi
con acrobazie.
D'altra parte, a parte bash, anche col C while puo' anche non eseguire
neppure una volta, for invece esegue sempre la prima volta, o ricordo
male in questo momento? Questa e' un'altra differenza.
 
-- 
Tanti saluti
 


quando scrivi for i in *; do ...
 
la shell espande il carattere asterisco in nomi di file della directory 
corrente
Questi argomenti vengono poi passati a for
Questi argomenti devono essere tenuti in memoria e se sono tanti occorre 
una certa quantità di memoria
Inoltre la shell limita comunque questo numero massimo (dipende da 
parametri di compilazione,se ricordo bene va comunque da 32000 caratteri 
in su)
La while in pipe non ha questi problemi
 
ls | while read; ...
 
 
 
il comando ls emette i file su stdout, il comando while fa terminare il 
comando associato se esce con codice != 0, la lettura  viene passata in 
pipe  al comando associato (di solito read)
L' unica memoria che serve è il buffer di lettura per una riga
Poi read senza argomenti emette la riga letta nella variabile speciale 
REPLY altrimenti nelle variabili speciali passati come argomenti 
spezzettando la riga usando la variabile IFS  (che di solito contiene 
tab e spazio) ed anche qui la memoria  che serve è quello di una riga
 
 
 
 
 
 
 

 sono queste limitazioni che while non ha?
 
In realtà nè il ``for'' nè il ``while'' vanno bene.
Ti hanno già dato una risposta, il buffer dei comandi di lunghezza
fissa, ma è parziale, incompleta e fuorviante. I veri problemi sono
la portabilità, la compatibilità e la robustezza, causati da un 
complesso di cose dovute per prima cosa alla storia di UNIX; 
rimando alla Greg's Wiki per un discorso approfondito. Dirò solo 
poche cose.
 
La lunghezza del buffer sarebbe la cosa minore, il guaio è che è
è risolubile con la BASH poiché solo le nuove versioni e solo se
compilate appositamente risolvono il problema in maniera pulita.
Sembra un dettaglio ma cosa succederà quando aggiornerai il 
sistema o ti sposterai su una nuova macchina o cambi distribuzione?
Per esempio Debian per ottimi motivi ha da tempo cambiato dalla 
BASH alla DASH e la probabilità di non risolvere il problema è alta.
 
Del resto il ``while'' non risolve il problema perché, almeno da 
come è come è stato presentato da alcuni saccenti, perché la 
soluzione non sta nel particolare ciclo usato ma nel modo in cui
effettuare il ciclo sui vari file. Intendo la soluzione sta nell'usare 
``find''. Inoltre  nell'usare ``find'' insieme col ``while'' si devono
prendere molti accorgimenti per fare funzionare la cosa e non è 
immediato. Detto in altre parole dire usare ''find'' e ``while'' non
basta e dire usa ``ls'' e ``while'' è una stronzata megagalattica
e chi lo dice è un cretino vestito e calzato.
 
La soluzione non è semplice, il metodo tradizionale è usare ``xargs'' 
magari congiuntamente a ``find`` ma anche questa soluzione è 
problematica. La GNU offre un modo molto semplice e pulito  per
cavarsela a patto di adottare gli strumenti dalla GNU ma a questo 
punto si torna al discorso precedente sulla BASH.
Inoltre ``xargs'' non è detto sia adattabile ad ogni problema per cui
ritorna in ballo la soluzione con il ``while''.
 
Il discorso sarebbe ancora lungo per cui finisco qui rimandando al
fottuto WEB per ulteriori approfondimenti e propongo una soluzione
finora non presa finora in considerazione, con l'avvertenza che però,
come al solito, va bene in generale ma non allo specifico problema
dell'OP: io farei uno script semplice, senza cicli, che processa un 
solo file alla volta e poi richiamare questo script con 
`'find ... -exec...''