Domanda

Quale comando può essere utilizzato per verificare se una directory esiste o meno, all'interno di uno script di shell?

È stato utile?

Soluzione

Per verificare se esiste una directory in uno script di shell è possibile utilizzare quanto segue:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

Oppure per verificare se una directory non esiste:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

Tuttavia, come Jon Ericson sottolinea, i comandi successivi potrebbero non funzionare come previsto se non si tiene conto del fatto che anche un collegamento simbolico a una directory supera questo controllo.Per esempio.eseguendo questo:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

Produrrà il messaggio di errore:

rmdir: failed to remove `symlink': Not a directory

Quindi i collegamenti simbolici potrebbero dover essere trattati diversamente, se i comandi successivi prevedono directory:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

Presta particolare attenzione alle virgolette doppie utilizzate per racchiudere le variabili, la ragione di ciò è spiegata da 8jean in un'altra risposta.

Se le variabili contengono spazi o altri caratteri insoliti, probabilmente lo script fallirà.

Altri suggerimenti

Ricorda di avvolgere sempre le variabili in doppie citazioni quando le fa riferimento in uno script bash.I ragazzi di oggi crescono con l'idea di poter avere spazi e tanti altri personaggi divertenti nei nomi delle loro directory.(Spazi!Ai miei tempi non avevamo spazi fantasiosi!;))

Un giorno, uno di quei ragazzi eseguirà la tua sceneggiatura $DIRECTORY impostato "My M0viez" e la tua sceneggiatura esploderà.Non lo vuoi.Quindi usa questo.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

Notare la -D il test può produrre alcuni risultati sorprendenti:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

File sotto:"Quando una directory non è una directory?" La risposta:"Quando è un collegamento simbolico per una directory." Un test leggermente più completo:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Puoi trovare maggiori informazioni nel manuale di Bash su Espressioni condizionali Bash e il [ comando integrato e il [[ comando composto.

Trovo il doppia parentesi versione di test rende la scrittura dei test logici più naturale:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

Forma più breve:

[ -d "$DIR" ] && echo "Yes"

Per verificare se esiste una directory puoi usare una semplice struttura if come questa:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

Puoi farlo anche in negativo

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

Nota:Fai attenzione, lascia degli spazi vuoti su entrambi i lati dell'apparecchio sia di apertura che di chiusura.

Con la stessa sintassi puoi usare:

-e: any kind of archive 

-f: file 

-h: symbolic link 

-r: readable file 

-w: writable file 

-x: executable file 

-s: file size greater than zero 
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

Puoi usare test -d (Vedere man test).

-d file Vero se il file esiste ed è una directory.

Per esempio:

test -d "/etc" && echo Exists || echo Does not exist

Nota:IL test il comando è uguale all'espressione condizionale [ (Vedere: man [), quindi è portabile tra gli script di shell.

[ - Questo è un sinonimo di test builtin, ma l'ultimo argomento deve essere letterale ], per abbinare l'apertura [.

Per possibili opzioni o ulteriore aiuto, controlla:

  • help [
  • help test
  • man test O man [
  1. Un semplice script per verificare se dir o file è presente o meno:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. Un semplice script per verificare se la directory è presente o meno:

    mkdir tempdir   # if you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
    

    Gli script sopra controlleranno che la directory sia presente o meno

    $? se l'ultimo comando ha successo restituisce "0" altrimenti un valore diverso da zero.supponiamo tempdir è già presente allora mkdir tempdir darà un errore come di seguito:

    mkdir:impossibile creare la directory "tempdir":il file esiste

O per qualcosa di completamente inutile:

[ -d . ] || echo "No"

Ecco un linguaggio molto pragmatico:

(cd $dir) || return # is this a directory,
                    # and do we have access?

Di solito lo avvolgo in una funzione:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

O:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

La cosa bella di questo approccio è che non devo pensare a un buon messaggio di errore.

cd mi darà già un messaggio standard di una riga a stderr.Fornirà anche più informazioni di quelle che sarò in grado di fornire.Eseguendo il cd all'interno di una sottoshell ( ... ), il comando non influisce sulla directory corrente del chiamante.Se la directory esiste, questa subshell e la funzione sono semplicemente un'operazione non operativa.

Il prossimo è l'argomento a cui passiamo cd: ${1:?pathname expected}.Questa è una forma più elaborata di sostituzione dei parametri che viene spiegata più dettagliatamente di seguito.

Tl;dr:Se la stringa passata a questa funzione è vuota, usciamo nuovamente dalla subshell ( ... ) e ritorna dalla funzione con il messaggio di errore indicato.


Citando dal ksh93 pagina man:

${parameter:?word}

Se parameter è impostato ed è diverso da null, quindi sostituisci il suo valore;altrimenti stampa word ed esci dalla shell (se non interattiva).Se word viene omesso, viene stampato un messaggio standard.

E

Se il colon : viene omesso dalle espressioni di cui sopra, quindi la shell controlla se il parametro è impostato o meno.

La frase qui è peculiare della documentazione della shell, come word Può fare riferimento a qualsiasi stringa ragionevole, incluso lo spazio bianco.

In questo caso particolare, so che il messaggio di errore standard 1: parameter not set non è sufficiente, quindi ingrandisco il tipo di valore che ci aspettiamo qui: the pathname di una directory.

Una nota filosofica:La shell non è un linguaggio orientato agli oggetti, così dice il messaggio pathname, non directory.A questo livello preferirei mantenerlo semplice: gli argomenti di una funzione sono solo stringhe.

if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Il codice precedente controlla se la directory esiste e se è scrivibile.

Digita questo codice nel prompt di bash

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

Altre funzionalità utilizzando find

  • Verifica l'esistenza della cartella all'interno delle sottodirectory:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
    
  • Verifica l'esistenza di una o più cartelle in base a uno schema all'interno della directory corrente:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
    
  • Entrambe le combinazioni.Nell'esempio seguente viene verificata l'esistenza della cartella nella directory corrente:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    

In realtà, dovresti utilizzare diversi strumenti per ottenere un approccio a prova di proiettile:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
    echo "It's a dir";
fi

Non devi preoccuparti di spazi e caratteri speciali finché li usi "${}".

Notare che [[]] non è portatile come [], ma poiché la maggior parte delle persone lavora con le versioni moderne di Bash (poiché, dopo tutto, la maggior parte delle persone non lavora nemmeno con la riga di comando :-p), il vantaggio è maggiore del problema.

Per controllare più di una directory utilizzare questo codice:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

Hai considerato di fare semplicemente quello che vuoi fare nel if piuttosto che guardare prima di saltare?

IE, se vuoi verificare l'esistenza di una directory prima di accedervi, prova semplicemente a fare questo:

if pushd /path/you/want/to/enter; then
    # commands you want to run in this directory
    popd
fi

Se il percorso a cui dai pushd esiste, lo inserirai e uscirà con 0, il che significa che then parte dell'istruzione verrà eseguita.Se non esiste, non accadrà nulla (a parte qualche output che dice che la directory non esiste, che probabilmente è comunque un effetto collaterale utile per il debug).

Sembra meglio di così, che richiede la ripetizione:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # commands you want to run in this directory
    popd
fi

La stessa cosa funziona con cd, mv, rm, eccetera...se li provi su file che non esistono, usciranno con un errore e stamperanno un messaggio dicendo che non esiste, e il tuo then il blocco verrà saltato.Se li provi su file che esistono, il comando verrà eseguito e uscirà con lo stato di 0, consentendo al tuo then blocco da eseguire.

Controlla se la directory esiste, altrimenti creane una

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

NB:Citare le variabili è una buona pratica.

[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

Questa risposta racchiuso come uno script di shell

Esempi

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";

Usando il -e check controllerà la presenza di file e questo include le directory.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

Come da Jonathan commento:

Se vuoi creare la directory e questa non esiste ancora, la tecnica più semplice è usare mkdir -p che crea la directory - e tutte le directory mancanti nel percorso - e non fallisce se la directory esiste già, quindi puoi farlo tutto in una volta con:

mkdir -p /some/directory/you/want/to/exist || exit 1
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Questo non è del tutto vero...Se vuoi andare in quella directory, devi anche avere i diritti di esecuzione sulla directory.Forse devi avere anche i diritti di scrittura.

Pertanto:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi

IL ls comando insieme a -l (elenco lungo) l'opzione restituisce informazioni sugli attributi su file e directory.
In particolare il primo carattere di ls -l l'output è solitamente a d o a - (trattino).Nel caso di a d quella elencata è sicuramente una directory.

Il seguente comando in una sola riga ti dirà se il dato ISDIR la variabile contiene o meno il percorso di una directory:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

Utilizzo pratico:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;

Se vuoi verificare se esiste una directory, indipendentemente dal fatto che sia una directory reale o un collegamento simbolico, usa questo:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Spiegazione:Il comando "ls" restituisce l'errore "ls:/X:No such file or directory" se la directory o il collegamento simbolico non esiste e imposta anche il codice di ritorno, che puoi recuperare tramite "$?", su un valore diverso da zero (normalmente "1").Assicurati di controllare il codice di ritorno subito dopo aver chiamato "ls".

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

Se viene riscontrato un problema con uno degli approcci sopra indicati.

Con ls comando;nei casi in cui la directory non esiste: viene visualizzato un messaggio di errore

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1]] && echo esiste || non esiste -ksh:non:non trovato [Nessun file o directory di questo tipo]

Ottime soluzioni disponibili, ma alla fine ogni script fallirà se non ti trovi nella directory giusta.Quindi codice come questo:

if [ -d "$LINK_OR_DIR" ]; then 
if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here
    rm "$LINK_OR_DIR"
else
    # It's a directory!
    # Directory command goes here
    rmdir "$LINK_OR_DIR"
fi
fi

verrà eseguito con successo solo se al momento dell'esecuzione ti trovi in ​​una directory che ha una sottodirectory che ti capita di controllare.

Capisco la domanda iniziale in questo modo:per verificare se una directory esiste indipendentemente dalla posizione dell'utente nel file system.Quindi usare il comando "trova" potrebbe risolvere il problema:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

Questa soluzione è buona perché consente l'uso dei caratteri jolly, una funzionalità utile durante la ricerca di file/directory.L'unico problema è che, se la directory cercata non esiste, il comando 'find' non stamperà nulla sullo stdout (non è una soluzione elegante per i miei gusti) e avrà comunque un'uscita zero.Forse qualcuno potrebbe migliorare in questo.

Di seguito è possibile utilizzare la ricerca,

find . -type d -name dirname -prune -print
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top