tutorial - Ottieni la nuova directory in bash su una variabile




bin bash (4)

Bene, penso che questa soluzione sia la più efficiente:

path="/my/dir/structure/*"
backupdir=$(find $path -type d -prune | tail -n 1)

Spiegazione perché questo è un po 'meglio:

Non abbiamo bisogno di sub-shell (a parte quello per ottenere il risultato nella variabile bash). Non abbiamo bisogno di un inutile -exec ls -d alla fine del comando find , stampa già l'elenco delle directory. Possiamo facilmente modificarlo, ad esempio per escludere determinati modelli. Ad esempio, se si desidera la seconda directory più recente, poiché i file di backup vengono prima scritti in una directory tmp nello stesso percorso:

backupdir=$(find $path -type -d -prune -not -name "*temp_dir" | tail -n 1)

Mi piacerebbe trovare la sottodirectory più recente in una directory e salvare il risultato in variabile in bash.

Qualcosa come questo:

ls -t /backups | head -1 > $BACKUPDIR

Qualcuno può aiutare?


C'è una soluzione semplice a questo usando solo ls :

BACKUPDIR=$(ls -td /backups/*/ | head -1)
  • -t ordini in base al tempo (prima l'ultimo)
  • -d elenca solo gli elementi da questa cartella
  • */ elenca soltanto le directory
  • head -1 restituisce il primo oggetto

Non sapevo di */ fino a quando ho trovato solo le directory che usavano ls in bash: un esame .


Per ottenere la cartella più recente usando ls -t potresti dover differenziare i file dalle cartelle se la tua directory non ha solo le directory. Usando un ciclo semplice avrai un risultato sicuro e veloce e potrai anche implementare facilmente diversi filtri in futuro:

while read i ; do if [ -d "${i}" ] ; then newestFolder="${i}" ; break ; fi ; done < <(ls -t)

Blocco elaborato:

while read currentItemOnLoop # While reading each line of the file
do 
  if [ -d "${currentItemOnLoop}" ] # If the item is a folder
  then 
    newestFolder="${currentItemOnLoop}" # Then save it into the "newestFolder" variable
    break # and stop the loop
  else
    continue # Look for the next newest item
  fi 
done < <(ls -t) # Sending the result of "ls -t" as a "file" to the "while read" loop

Attenti alla continue logica sul mio blocco elaborato:

else
  continue # Look for the next newest item

Non lo userai. L'ho messo lì solo per la tua visibilità, perché in questo caso non influirebbe sui risultati.


Questa è una pura soluzione Bash:

topdir=/backups
BACKUPDIR=

# Handle subdirectories beginning with '.', and empty $topdir
shopt -s dotglob nullglob

for file in "$topdir"/* ; do
    [[ -L $file || ! -d $file ]] && continue
    [[ -z $BACKUPDIR || $file -nt $BACKUPDIR ]] && BACKUPDIR=$file
done

printf 'BACKUPDIR=%q\n' "$BACKUPDIR"

Salta i collegamenti simbolici, inclusi i collegamenti simbolici alle directory, che possono o meno essere la cosa giusta da fare. Salta altre non-directory. Gestisce le directory i cui nomi contengono caratteri, incluse le nuove linee e i punti principali.







bash