GNU/Linux >> Linux Esercitazione >  >> Linux

Estrai i percorsi mancanti dall'array di percorsi bash

Hai già scoperto il motivo immediato per cui il tuo codice non ha funzionato come previsto:errori da ls vengono segnalati a stderr (come suggerito da POSIX), che non viene catturato come input dalla pipe. Hai quindi ottenuto un misto di output normale (che è passato invariato dal tuo sed statement) e stderr (che li ha aggirati). Non so perché il tuo ls uscita cambiata tra le chiamate; reindirizzare stdout a /dev/null dovrebbe avere l'effetto di rimuovere tutti i "normali" (percorsi esistenti) dall'output. La soluzione per questo non per spingere stderr in stdout, però.

Post-elaborazione dell'output da ls è un'idea pericolosa se vuoi uno script affidabile. Un buon articolo sull'argomento è "Perché non dovresti analizzare l'output di ls(1)", disponibile sul sito wooledge.org. Un'approfondita domanda/risposta sul sito Unix &Linux affronta alcuni dei problemi:Perché no analizza ls (e cosa fare invece)?. Il risultato è che i nomi di file UNIX possono contenere quasi tutti i caratteri, inclusi spazi, tabulazioni, newline, virgolette singole, virgolette doppie, virgolette singole sfuggite, ecc.! Per alcuni rapidi esempi, considera le directory con questi nomi, che sono tutte perfettamente legali:

  • "Nessun file simile" (mkdir "No such file" )
  • "ls:impossibile accedere a 'foo':file o directory non presenti" (mkdir "ls: cannot access 'foo': No such file or directory" )
  • "cartella

    con

    integrato

    newline" (mkdir $'directory\nwith\nembedded\newlines' )

La prima è una directory innocente catturata erroneamente (dallo stdout) dal grep . Anche il secondo viene catturato erroneamente, ma poi ulteriormente mutilato in un percorso completamente diverso -- che può o non può esistere! -- dal sed dichiarazioni. Il terzo è un esempio di ciò che accade quando passi l'output di ls in programmi orientati alla linea; se la directory non esiste, ls lo dirà su più di una riga, che è probabilmente il motivo per cui sei finito con due sed separati affermazioni!

Per distinguere i "percorsi validi" (quelli che esistono e sono leggibili) dai "percorsi sbagliati", suggerirei di eseguire un ciclo sull'array e di creare nuovi array di ciascuno.

for p in "${paths[@]}"
do
  if [ -r "$p" ]
  then
    goodpaths+=("$p")
  else
    badpaths+=("$p")
  fi
done

Puoi quindi fare quello che vuoi con ogni set:

printf 'Good path: -->%s<--\n' "${goodpaths[@]}"
echo
printf 'Bad path: -->%s<--\n' "${badpaths[@]}"

Linux
  1. Quali caratteristiche ci sono in Zsh e mancano da Bash o viceversa?

  2. Il modo migliore per rilevare (da uno script) se il software è installato?

  3. È possibile in Bash iniziare a leggere un file da un offset arbitrario del conteggio dei byte?

  4. a partire da apachectl bash

  5. Come posso ottenere valori univoci da un array in Bash?

Matrici Bash

Matrice associativa in Bash

Esegue lo script bash dall'URL

estrarre il tempo medio da ping -c

Converti una stringa di testo in bash in array

bash - restituisce l'array dalla funzione e visualizza il contenuto