Ciao a tutti, sto prendendo confidenza con lo scripting in BASH :) Praticamente il mio script fa qualcosa di molto banale:

  • prende le cartelle personali di THunderbird e ne crea un archivio compresso
  • l'archivio compresso viene trasferito su un NAS collegato all'interno della mia rete domestica.
  • [questa è la parte che vorrei risolvere] dovrebbe entrare nella cartella del NAS dove vengono salvati i backup delle email e cancellare tutti i file tranne il meno recente.


Per quest'ultimo punto, come potrei fare? Esiste qualche comando o combinazione di comandi da scrivere in bash?

Grazie mille a tutti, per l'aiuto.

Francesco

chiesto 09 Jul '14, 18:59

FrancescoSupercar's gravatar image

FrancescoSup...
249131423

modificato 09 Jul '14, 23:12

enzotib's gravatar image

enzotib ♦♦
14.1k113187


Ecco un comando che, dai miei test, dovrebbe fare quello che chiedi

rm !("$(ls -t | head -n1)")

ma ti raccomando, prima di eseguirlo, di provarlo con un "echo" davanti, tipo

echo rm !("$(ls -t | head -n1)")

in modo da verificare cosa vorrebbe cancellare.
La spiegazione:

ls -t

fa un elenco dei file nella directory corrente in ordine di "modification time", dal più recente al più vecchio.
L'aggiunta

head -n1

prende solo il primo file di questa lista, ovvero il più recente.
Infine il comando

rm !(file)

cancella tutto tranne "file", dove file è ottenuto con i comandi precedenti.

coll. permanente

ha risposto 09 Jul '14, 23:11

enzotib's gravatar image

enzotib ♦♦
14.1k113187

grazie @enzotib! Un ultima cosa mi sapresti spiegare l'utilità del "!" dopo il comando rm ? Non l'ho trovata come opzione nel pagina del manuale. Grazie

(10 Jul '14, 19:42) FrancescoSup... FrancescoSupercar's gravatar image

per il resto funziona alla perfezione :)

(10 Jul '14, 19:43) FrancescoSup... FrancescoSupercar's gravatar image
1

@francescosupercar: nella pagina di manuale di bash cerca nel paragrafo "Pattern Matching":

!(pattern-list)
                 Matches anything except one of the given patterns
(10 Jul '14, 20:11) enzotib ♦♦ enzotib's gravatar image

utilizzando il tuo comando: rm !("$(ls -t | head -n1)")

ricevo il seguente messaggio di errore:

./prova.sh: riga 3: errore di sintassi vicino al token non atteso "(" ./prova.sh: riga 3: `rm !("$(ls -t | head -n1)")'

A che serve quel "1" ???

(10 Jul '14, 21:02) FrancescoSup... FrancescoSupercar's gravatar image
1

@francescosupercar: hai ragione, da riga di comando funziona, dato che di default sono attivati gli extglob. Invece in uno script bisogna attivarli esplicitamente, con la riga

shopt -s extglob

da inserire da qualche parte prima dell'altro comando, magari all'inizio dello script una volta e per tutte.

(10 Jul '14, 21:09) enzotib ♦♦ enzotib's gravatar image

fantastico adesso va :) Grazie mille!

(10 Jul '14, 23:07) FrancescoSup... FrancescoSupercar's gravatar image

ciao @enzotib scusa se ritorno sull'argomento ma non ho mai risolto completamente. Importando gli "extglob" ho visto che al momento in cui lo script esegue echo rm !("$(ls -t | head -n1)") lo stesso si blocca. Hai idee su quale possa essere la causa? Grazie!

(10 Oct '14, 21:45) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: quindi il commento precedente del 10 luglio, dove hai scritto "adesso va" non era vero?

(10 Oct '14, 21:50) enzotib ♦♦ enzotib's gravatar image

@enzotib quel commento si riferiva al fatto che importando gli extglob con il comando da te suggerito (shopt) il comando echo rm !("$(ls -t | head -n1)") stampava correttamente i risultati. Però si è sempre bloccato. In sostanza lo script non terminava la sua esecuzione.

(11 Oct '14, 10:29) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: mi chiedo come mai non hai detto a suo tempo che il problema non era risolto. In ogni caso, ho fatto qualche prova ed il problema a me non si presenta.
Inoltre, eseguendolo all'interno di uno script, il motivo per il quale non termina non potrebbe dipendere da qualche altra parte dello script?

(11 Oct '14, 15:32) enzotib ♦♦ enzotib's gravatar image

lo so hai ragione @enzotib, forse per mancanza di tempo, all'epoca non ho insistito. Perdonami. Se mi aiuti ancora te ne sarei grato. Ti riporto per esteso un semplicissimo script che comunque si blocca, quindi come hai detto tu probabilmente sbaglio qualcosa nello script:

#!/bin/bash

shopt -s extglob variabile= ls /home/francesco/Downloads -t | head -n2 rm !("$variabile")

exit

(13 Oct '14, 18:56) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: prova così, ho corretto un paio di cose:

#!/bin/bash

shopt -s extglob
variabile="$(ls /home/francesco/Downloads -t | head -n1)" 
rm !("$variabile")
(13 Oct '14, 21:02) enzotib ♦♦ enzotib's gravatar image

@enzotib: fatto un semplice copia incolla del tuo script. Adesso funziona e non si blocca ma..... elimina tutti i file dalla cartella :( Non vorrei mettermi a fare uno script Python per una cosa del genere...

(14 Oct '14, 19:00) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: hai mica anche delle sottodirectory nella cartella interessata? e lo script dove lo metti, nella stessa cartella? immagino di no.
Inutile dire che a me funziona perfettamente, ma supponendo che non ci siano subdirectory, dato che si era parlato solo di files.

(14 Oct '14, 19:13) enzotib ♦♦ enzotib's gravatar image

no non ci sono sottodirectory, solo file .tar. Lo script che eseguo si trova nella cartella "Desktop" e deve cancellare i file in cartella "Downloads" lo script come l'ho copiato dal tuo commento cancella tutti i file della cartella in cui risiede lo script (quindi Desktop) allora ho provato a premette prima della definizione della variabile un " cd /home/francesco/Downloads" così invece mi elimina tutti i file della cartella Downloads. Unica piccola modifica apportata: dopo il simbolo di "|" ho scritto "head -n2" credo che non si a questa modifica a dare problemi. Grazie ancora

(14 Oct '14, 19:26) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: invece è proprio questa modifica a dare problemi, e l'avevo già corretta dal tuo script in un tuo precedente commento, quando ti avevo proposto l'ultimo script.
Perché metti -n2? cosa vuoi ottenere?

(14 Oct '14, 19:35) enzotib ♦♦ enzotib's gravatar image

@enzotib vorrei mantenere i due file più recenti. Comunque ho provato anche a mettere -n1 ma comunque cancella tutti i file, non ne conserva nessuno. Ma perché? Sembra che non interpreti correttamente quel "!"

(14 Oct '14, 20:52) FrancescoSup... FrancescoSupercar's gravatar image

@francescosupercar: se anche con -n1 funziona, allora non so proprio cosa fare, dato che non sono in grado di riprodurre il problema. Rinuncio e ti prego di togliere il segno di spunta all'accettazione della risposta.
Magari provo a scriverne un'altra con un approccio completamente diverso.

(14 Oct '14, 21:06) enzotib ♦♦ enzotib's gravatar image

Ecco un'altra possibilità, senza l'uso degli extended glob di bash, ma con un ciclo, e quindi più lento, anche se probabilmente non ci si dovrebbe accorgere della differenza. Lo script cancella tutti i file tranne i due più nuovi, senza tener conto delle eventuali directory presenti

#!/bin/bash

i=1
ls -t /path |
  while read f; do
    if [[ -f "$f" ]]; then
      if ((i > 2)); then
        echo rm "$f"
      fi
      ((i++))
    fi
  done
coll. permanente

ha risposto 14 Oct '14, 21:36

enzotib's gravatar image

enzotib ♦♦
14.1k113187

Grazie @enzotib. Sono finalmente riuscito a far funzionare lo script grazie a tuoi consigli.Il problema era che inserivo $ls -t | head -n1 senza anteporre le virgolette. O almeno credo che quello fosse il motivo per cui si bloccava lo script adesso funziona splendidamente. Ottima alternativa anche quella riportata nel tuo ultimo commento. Forse con il ciclo (per chi non è esperto di extglob) è molte più semplice da comprendere. Grazie ancora per la tua disponibilità e pazienza

(19 Oct '14, 10:28) FrancescoSup... FrancescoSupercar's gravatar image
La tua risposta
abilita/disabilita anteprima

Segui questa domanda

Via email:

Una volta eseguito l'accesso potrai iscriverti a tutti gli aggiornamenti qui

Via RSS:

Risposte

Risposte e commenti

Basi di markdown

  • *corsivo* o __corsivo__
  • **grassetto** o __grassetto__
  • collegamento:[testo](http://url.com/ "titolo")
  • immagine?![alt testo](/path/img.jpg "titolo")
  • elenco numerato: 1. Foo 2. Bar
  • per aggiungere un'interruzione di riga, aggiungi due spazi a fine riga e premi «Invio»
  • è supportato anche semplice HTML

Tag:

×105
×52

domanda posta: 09 Jul '14, 18:59

domanda visualizzata: 6,777 volte

ultimo aggiornamento: 19 Oct '14, 10:28

Chiedi è un servizio di supporto gestito da Ubuntu-it. Contattaci!

powered by OSQAPostgreSQL database
Ubuntu e Canonical sono marchi registrati da Canonical Ltd.