Perintah apa yang dapat digunakan untuk memeriksa apakah ada direktori atau tidak, dalam skrip Bash shell?
Untuk memeriksa apakah direktori ada dalam skrip shell, Anda dapat menggunakan yang berikut:
if [ -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY exists.
fi
Atau untuk memeriksa apakah direktori tidak ada:
if [ ! -d "$DIRECTORY" ]; then
# Control will enter here if $DIRECTORY doesn't exist.
fi
Namun, seperti yang ditunjukkan oleh Jon Ericson , perintah selanjutnya mungkin tidak berfungsi sebagaimana dimaksud 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 simbolik mungkin harus diperlakukan secara berbeda, jika perintah selanjutnya 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 tanda kutip ganda yang digunakan untuk membungkus variabel. Alasan untuk ini dijelaskan oleh 8jean di jawaban lain .
Jika variabel berisi spasi atau karakter tidak biasa lainnya, mungkin akan menyebabkan skrip gagal.
--
sangat dianjurkan (penanda opsi akhir). Jika tidak, jika variabel Anda berisi sesuatu yang terlihat seperti opsi, skrip akan gagal seperti halnya spasi.[ ! -d "$DIRECTORY" ]
akan benar jika$DIRECTORY
tidak ada, atau jika memang ada tetapi bukan direktori. Pertimbangkan sesuatu sepertiif [ ! -d "$DIRECTORY" ] ; then mkdir "$DIRECTORY" ; fi
; ini akan gagal jika"$DIRECTORY"
merupakan file. (Tentu saja Anda harus memeriksa apakahmkdir
berhasil juga; ada sejumlah alasan mengapa hal itu dapat gagal.)-d
) dan symlink (-L
), lebih mudah hanya menambahkan garis miring ke variabel, sepertiif [ -d "${THING:+$THING/}" ]
. Direktori tidak akan keberatan dengan slash tambahan. File akan dinilai false. Kosong akan tetap kosong, jadi salah. Dan symlink akan diselesaikan ke tujuannya. Tentu saja, itu tergantung pada tujuan Anda. Jika Anda ingin pergi ke sana, ini tidak masalah. Jika Anda ingin menghapusnya , maka kode dalam jawaban ini lebih baik.Ingatlah untuk selalu membungkus variabel dalam tanda kutip ganda ketika merujuk mereka dalam skrip Bash. Anak-anak dewasa ini tumbuh dengan gagasan bahwa mereka dapat memiliki ruang dan banyak karakter lucu lainnya dalam nama direktori mereka. (Spaces! Kembali ke masa saya, kami tidak memiliki ruang mewah!;))
Suatu hari, salah satu dari anak-anak itu akan menjalankan skrip Anda dengan
$DIRECTORY
diatur ke"My M0viez"
dan skrip Anda akan meledak. Anda tidak menginginkan itu. Jadi gunakan ini.sumber
Perhatikan tes -d dapat menghasilkan beberapa hasil yang mengejutkan:
File di bawah: "Kapan sebuah direktori bukan sebuah direktori?" Jawabannya: "Ketika symlink ke direktori." Tes yang sedikit lebih teliti:
Anda dapat menemukan informasi lebih lanjut di manual Bash tentang ekspresi kondisional Bash dan
[
perintah builtin dan[[
komandemen majemuk .sumber
if [ -d tmpdir -a ! -L tmpdir ]; then echo "is directory"; rmdir tmpdir; fi
... atau, untuk satu perintah yang bekerja pada kedua tautan & direktori:rm -r tmpdir
Saya menemukan versi braket ganda dari
test
membuat tes logika menulis lebih alami:sumber
if [[ -d "$TARFILE" ]]
saya mendapatkan [[: tidak ditemukan[[ ]]
didukung, tetapi sebenarnya tidak memberikan fungsionalitas yang berbeda[ ]
. Jika portabilitas menjadi perhatian, patuhi[ ]
dan gunakan solusi yang diperlukan.Bentuk lebih pendek:
sumber
if $dir is a dir, then echo "yes"
:? Sedikit penjelasan akan membantu :)cmd && other
adalah singkatan umum untukif cmd; then other; fi
- ini bekerja dengan sebagian besar bahasa pemrograman yang mendukung logika Boolean, dan dikenal sebagai evaluasi hubung singkat .set -e
(yang merupakan praktik terbaik pemrograman shell ).[ -d "$DIR" ]
dicentang (diikuti oleh&& echo Yes
), jadi saya percayaset -e
tidak ada bedanya dengan perilaku skrip (yaitu jika tes gagal, skrip berlanjut secara normal).Untuk memeriksa apakah ada direktori, Anda dapat menggunakan
if
struktur sederhana seperti ini:Anda juga dapat melakukannya dengan negatif:
Catatan : Hati-hati. Sisakan ruang kosong di kedua sisi kurung buka dan tutup.
Dengan sintaks yang sama Anda dapat menggunakan:
sumber
Skrip sederhana untuk menguji apakah direktori atau file ada atau tidak:
Script sederhana untuk memeriksa apakah direktori ada atau tidak:
Script di atas akan memeriksa apakah direktori ada atau tidak
$?
jika perintah terakhir adalah sukses ia mengembalikan "0", jika tidak nilai nol. Misalkantempdir
sudah ada. Makamkdir tempdir
akan memberikan kesalahan seperti di bawah ini:sumber
Anda dapat menggunakan
test -d
(lihatman test
).Sebagai contoh:
Catatan:
test
Perintah ini sama dengan ekspresi kondisional[
(lihatman [
:), jadi ini portabel di skrip shell.Untuk opsi yang mungkin atau bantuan lebih lanjut, periksa:
help [
help test
man test
atauman [
sumber
Atau untuk sesuatu yang sama sekali tidak berguna:
sumber
Inilah ungkapan yang sangat pragmatis:
Saya biasanya membungkusnya dalam suatu fungsi:
Atau:
Yang menyenangkan tentang pendekatan ini adalah saya tidak perlu memikirkan pesan kesalahan yang baik.
cd
akan memberi saya pesan satu baris standar untuk kesalahan standar . Itu juga akan memberi lebih banyak informasi daripada yang bisa saya berikan. Dengan melakukan bagiancd
dalam subkulit( ... )
, perintah tidak mempengaruhi direktori pemanggil saat ini. Jika direktori ada, subkulit ini dan fungsinya hanyalah larangan.Berikutnya adalah argumen bahwa kita lolos ke
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 melewati fungsi ini kosong, kami kembali keluar dari subkulit
( ... )
dan kembali dari fungsi dengan pesan kesalahan yang diberikan.Mengutip dari
ksh93
halaman manual:dan
Ungkapan di sini adalah khusus untuk dokumentasi shell, seperti
word
dapat merujuk pada string yang masuk akal, termasuk spasi.Dalam kasus khusus ini, saya tahu bahwa pesan kesalahan standar
1: parameter not set
tidak cukup, jadi saya memperbesar jenis nilai yang kita harapkan di sini -pathname
direktori.Catatan filosofis:
Shell bukan bahasa yang berorientasi objek, jadi pesannya mengatakan
pathname
, bukandirectory
. Pada level ini, saya lebih suka membuatnya tetap sederhana - argumen untuk suatu fungsi hanyalah string.sumber
test -d
seperti yang dijelaskan oleh @Grundlefleck.test -d /unreadable/exists
akan gagal, bahkan jika ada argumen.Kode di atas memeriksa apakah direktori tersebut ada dan apakah dapat ditulis.
sumber
Coba online
sumber
space
setelah[
-> [`` -d . saya mendapat kesalahan karena ruang yang hilangKetikkan kode ini pada prompt Bash:
sumber
Lebih banyak fitur menggunakan
find
Periksa keberadaan folder dalam sub-direktori:
Periksa keberadaan satu atau beberapa folder berdasarkan pola dalam direktori saat ini:
Keduanya kombinasi. Dalam contoh berikut, ia memeriksa keberadaan folder di direktori saat ini:
sumber
find -maxdepth 1 -type d -name 'pattern'
. Apakah Anda keberatan jika saya menambahkan dalam jawaban Anda trik ini? Cheers;)Sebenarnya, Anda harus menggunakan beberapa alat untuk mendapatkan pendekatan antipeluru:
Tidak perlu khawatir tentang spasi dan karakter khusus selama Anda menggunakannya
"${}"
.Catatan yang
[[]]
tidak semudah portabel[]
, tetapi karena kebanyakan orang bekerja dengan versi modern Bash (karena bagaimanapun, kebanyakan orang bahkan tidak bekerja dengan baris perintah :-p), manfaatnya lebih besar daripada masalah.sumber
Sudahkah Anda mempertimbangkan untuk melakukan apa saja yang ingin Anda lakukan di dalam
if
daripada melihat sebelum melompat?Yaitu, jika Anda ingin memeriksa keberadaan direktori sebelum Anda memasukkannya, coba lakukan ini:
Jika jalur yang Anda berikan
pushd
ada, Anda akan memasukkannya dan itu akan keluar dengan0
, yang berartithen
bagian dari pernyataan akan dieksekusi. Jika tidak ada, tidak ada yang terjadi (selain beberapa output yang mengatakan direktori tidak ada, yang mungkin merupakan efek samping yang bermanfaat untuk debugging).Tampaknya lebih baik dari ini, yang mengharuskan Anda mengulangi sendiri:
Hal yang sama bekerja dengan
cd
,mv
,rm
, dll ... jika Anda mencoba mereka pada file yang tidak ada, mereka akan keluar dengan kesalahan dan mencetak pesan yang mengatakan itu tidak ada, dan Andathen
blok akan dilewati. Jika Anda mencobanya pada file yang ada, perintah akan menjalankan dan keluar dengan status0
, yang memungkinkanthen
blok Anda untuk dieksekusi.sumber
Penjelasan:
-d
: periksa apakah itu direktori-L
: periksa apakah itu tautan simbolissumber
Untuk memeriksa lebih dari satu direktori gunakan kode ini:
sumber
Periksa apakah direktori ada, buat yang lain:
sumber
mkdir -p "$DIRECTORY"
untuk efek yang sama.sumber
Jawaban ini dibungkus sebagai skrip shell
Contohnya
is_dir
sumber
Menggunakan
-e
cek akan memeriksa file dan ini termasuk direktori.sumber
Sesuai komentar Jonathan :
Jika Anda ingin membuat direktori dan belum ada, maka teknik paling sederhana adalah menggunakan
mkdir -p
yang membuat direktori - dan direktori yang hilang di jalur - dan tidak gagal jika direktori sudah ada, sehingga Anda bisa melakukan semuanya sekaligus dengan:sumber
Ini tidak sepenuhnya benar ...
Jika Anda ingin pergi ke direktori itu, Anda juga perlu memiliki hak eksekusi pada direktori. Mungkin Anda perlu memiliki hak tulis juga.
Karena itu:
sumber
Gunakan
file
programnya. Mempertimbangkan semua direktori juga file di Linux, mengeluarkan perintah berikut akan cukup:file $directory_name
Memeriksa file yang tidak ada:
file blah
Keluaran:
cannot open 'blah' (No such file or directory)
Memeriksa direktori yang ada:
file bluh
Keluaran:
bluh: directory
sumber
The
ls
perintah dalam hubungannya dengan-l
(panjang daftar) kembali option atribut informasi tentang file dan direktori.Khususnya karakter pertama dari
ls -l
output biasanya ad
atau a-
(dash). Dalam kasusd
yang terdaftar adalah direktori pasti.Perintah berikut hanya dalam satu baris akan memberi tahu Anda jika
ISDIR
variabel yang diberikan berisi lintasan ke direktori atau tidak:Penggunaan praktis:
sumber
sumber
Jika Anda ingin memeriksa apakah ada direktori, terlepas dari apakah itu direktori asli atau symlink, gunakan ini:
Penjelasan: Perintah "ls" memberikan kesalahan "ls: / x: Tidak ada file atau direktori" jika direktori atau symlink tidak ada, dan juga menetapkan kode kembali, yang dapat Anda ambil melalui "$?", Ke non -null (biasanya "1"). Pastikan Anda memeriksa kode kembali secara langsung setelah memanggil "ls".
sumber
if ! ls $DIR 2>/dev/null; then echo "$DIR does not exist!"; fi
(1)
(2)
(3)
Jika masalah ditemukan dengan salah satu pendekatan yang diberikan di atas:
Dengan
ls
perintah; kasus-kasus ketika direktori tidak ada - pesan kesalahan ditampilkansumber
Ada solusi hebat di luar sana, tetapi pada akhirnya setiap skrip akan gagal jika Anda tidak berada di direktori yang benar. Jadi kode seperti ini:
akan mengeksekusi dengan sukses hanya jika pada saat eksekusi Anda berada di direktori yang memiliki subdirektori yang kebetulan Anda periksa.
Saya memahami pertanyaan awal seperti ini: untuk memverifikasi apakah ada direktori terlepas dari posisi pengguna dalam sistem file. Jadi menggunakan perintah 'find' mungkin melakukan trik:
Solusi ini bagus karena memungkinkan penggunaan wildcard, fitur yang berguna saat mencari file / direktori. Satu-satunya masalah adalah bahwa, jika direktori yang dicari tidak ada, perintah 'temukan' tidak akan mencetak apa pun ke output standar (bukan solusi elegan untuk seleraku) dan akan tetap memiliki jalan keluar nol. Mungkin seseorang bisa memperbaiki ini.
sumber
locate
tetapi tidak bagus untuk hal lain ...