Pertanyaan Periksa apakah ada direktori dalam skrip shell


Perintah apa yang dapat digunakan untuk memeriksa apakah direktori ada atau tidak, dalam skrip shell?


2988
2017-09-12 20:06


asal


Jawaban:


Untuk memeriksa apakah direktori ada dalam skrip shell Anda dapat menggunakan yang berikut ini:

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

Atau untuk memeriksa apakah suatu direktori tidak ada:

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

Namun, seperti Jon Ericson menunjukkan, perintah berikutnya mungkin tidak berfungsi sebagaimana yang dimaksudkan jika Anda tidak memperhitungkan bahwa tautan simbolis ke direktori juga akan melewati pemeriksaan ini. Misalnya. menjalankan ini:

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

Akan menghasilkan pesan kesalahan:

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

Jadi tautan simbolis mungkin harus diperlakukan berbeda, jika perintah berikutnya mengharapkan direktori:

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

Perhatikan catatan ganda yang digunakan untuk membungkus variabel, alasannya dijelaskan oleh 8jean di jawaban lain.

Jika variabel mengandung spasi atau karakter lain yang tidak biasa itu mungkin akan menyebabkan skrip gagal.


4132
2017-09-12 20:07



Ingat untuk selalu membungkus variabel dalam tanda kutip ganda saat mereferensikannya skrip bash. Anak-anak dewasa ini tumbuh dengan ide bahwa mereka dapat memiliki ruang dan banyak karakter lucu lainnya dalam nama direktori mereka. (Spaces! Kembali di hari-hari saya, kami tidak memiliki ruang mewah!;))

Suatu hari, salah satu dari anak-anak itu akan menjalankan skrip Anda $DIRECTORY mulai "My M0viez" dan naskahmu akan meledak. Anda tidak menginginkan itu. Jadi gunakan ini.

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

454
2017-09-15 22:00



Perhatikan -d tes dapat menghasilkan beberapa hasil yang mengejutkan:

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

File di bawah: "Kapan direktori bukan direktori?" Jawabannya: "Ketika itu symlink ke direktori." Tes yang sedikit lebih teliti:

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

Anda dapat menemukan informasi lebih lanjut di manual Bash Ekspresi kondisional Bash dan [ perintah bawaan dan [[ komando gabungan.


203
2017-09-12 20:26



Saya menemukan itu braket-ganda versi dari test membuat penulisan tes logika lebih alami:

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

198
2017-09-12 21:33



Bentuk lebih pendek:

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

125
2017-09-12 21:08



Untuk memeriksa apakah ada direktori, Anda dapat menggunakan struktur sederhana jika seperti ini:

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

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

Anda bisa melakukannya juga negatif

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

Catatan: Hati-hati, kosongkan ruang di kedua sisi pembuka dan tutup braces.

Dengan sintaks yang sama yang dapat Anda gunakan:

-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 

118
2018-04-08 02:50



if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi

94
2018-04-15 08:07



Kamu dapat memakai test -d (Lihat man test).

-d file       Benar jika file ada dan merupakan direktori.

Sebagai contoh:

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

Catatan: The test perintah sama dengan ekspresi kondisional [ (Lihat: man [), jadi portabel di seluruh skrip shell.

[ - Ini adalah sinonim untuk test builtin, tetapi argumen terakhir harus, menjadi literal ], untuk mencocokkan pembukaan [.

Untuk opsi yang memungkinkan atau bantuan lebih lanjut, periksa:

  • help [
  • help test
  • man test atau man [

73
2017-09-12 21:25



Atau untuk sesuatu yang sama sekali tidak berguna:

[ -d . ] || echo "No"

55
2017-08-17 14:02



Inilah ungkapan yang sangat pragmatis:

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

Saya biasanya membungkusnya dalam suatu fungsi:

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

Atau:

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

Yang menyenangkan dari pendekatan ini adalah saya tidak perlu memikirkan pesan kesalahan yang baik.

cd akan memberi saya pesan satu baris standar ke stderr sudah. Ini juga akan memberikan lebih banyak informasi daripada yang bisa saya berikan. Dengan melakukan cd di dalam subkulit ( ... ), perintah tidak mempengaruhi direktori saat ini dari pemanggil. Jika direktori ada, subkulit ini dan fungsinya hanya tidak-op.

Selanjutnya adalah argumen yang kami sampaikan cd: ${1:?pathname expected}. Ini adalah bentuk substitusi parameter yang lebih rumit yang dijelaskan secara lebih rinci di bawah ini.

Tl; dr: Jika string yang dilewatkan ke fungsi ini kosong, kita keluar lagi dari subkulit ( ... ) dan kembali dari fungsi dengan pesan kesalahan yang diberikan.


Mengutip dari ksh93 halaman manual:

${parameter:?word}

Jika parameter  diatur dan tidak nol lalu gantikan nilainya;   jika tidak, cetak word dan keluar dari shell (jika tidak interaktif).   Jika word dihilangkan kemudian pesan standar dicetak.

dan

Jika usus besar : dihilangkan dari ekspresi di atas, lalu   shell hanya memeriksa apakah parameter sudah diatur atau belum.

Ungkapan di sini khas untuk dokumentasi shell, seperti word dapat merujuk ke string yang masuk akal, termasuk spasi kosong.

Dalam kasus ini, saya tahu bahwa pesan kesalahan standar 1: parameter not set tidak cukup, jadi saya memperbesar jenis nilai yang kami harapkan di sini - pathname dari sebuah direktori.

Catatan filosofis: Shell bukanlah bahasa yang berorientasi objek, jadi pesannya mengatakan pathnametidak directory. Pada tingkat ini, saya lebih suka tetap sederhana - argumen untuk fungsi hanya string.


46
2017-08-09 21:43



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

Kode di atas memeriksa apakah direktori ada dan jika itu bisa ditulis.


34
2018-04-21 06:06