Saya ingin menguji apakah direktori tidak mengandung file apa pun. Jika demikian, saya akan melewati beberapa pemrosesan.
Saya mencoba yang berikut ini:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Itu memberikan kesalahan berikut:
line 1: [: too many arguments
Apakah ada solusi / alternatif?
Jawaban:
Juga, akan lebih baik untuk memeriksa apakah direktori sudah ada sebelumnya
sumber
&&
dan||
secara bersamaan! Jikaecho "Not Empty"
gagal,echo "Empty"
akan berjalan! Cobaecho "test" && false || echo "fail"
! Ya, saya tahuecho
tidak akan gagal tetapi jika Anda mengubah perintah lain, Anda akan terkejut![ "$(ls -A /)" ] && touch /non-empty || echo "Empty"
- jika Anda ingin "menandai" direktori yang tidak kosong dengan file yang dibuat dengan namanon-empty
, akan gagal dan mencetak "Kosong".touch /empty
di baris saya?if [ -n "$(ls -A /path/to/dir)" ]; then
... Harap perbarui jawabannya sebelum seseorang menempelkan kode ini ke server mereka di suatu tempat dan seorang hacker mencari cara untuk mengeksploitasinya. Jika/path/to/dir
tidak kosong, maka nama file yang ada dapat diteruskan sebagai argumen/bin/test
yang jelas tidak dimaksudkan. Cukup tambahkan-n
argumen, masalah terpecahkan. Terima kasih!Tidak perlu menghitung apa pun atau gumpalan shell. Anda juga dapat menggunakan
read
dalam kombinasi denganfind
. Jikafind
output kosong, Anda akan kembalifalse
:Ini harus portabel.
sumber
echo
panggilan Anda mencerminkan hasil yang salah: dalam pengujian saya (di bawah Cygwin)find . -mindepth 1 | read
memiliki 141 kode kesalahan dalam direktori yang tidak kosong, dan 0 di direktori kosongread
mengembalikan 0, dan untuk yang kosong, 1.set -o pipefail
sumber
-n
benar dan aman (uji dengan direktori dengan spasi di namanya, uji dengan direktori tidak kosong dengan nama '0 = 1').... [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; ...
grep
. serverfault.com/questions/225798/...find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty | grep .
, dan bergantung pada status keluar dari grep. Apa pun cara Anda melakukannya, ini adalah jawaban yang tepat untuk pertanyaan ini.sumber
Ini akan melakukan pekerjaan di direktori kerja saat ini (.):
atau perintah yang sama terpecah pada tiga baris hanya agar lebih mudah dibaca:
Ganti saja
ls -1A . | wc -l
denganls -1A <target-directory> | wc -l
jika Anda perlu menjalankannya di folder target yang berbeda.Sunting : Saya diganti
-1a
dengan-1A
(lihat komentar @aniel)sumber
ls -A
saja. Beberapa sistem file tidak memiliki.
dan..
tautan simbolik menurut dokumen.-1
pasti berlebihan. Bahkan jikals
tidak akan mencetak satu item per baris ketika akan disalurkan maka itu tidak mempengaruhi gagasan untuk memeriksa apakah itu menghasilkan nol atau lebih baris.Gunakan yang berikut ini:
Dengan cara ini, Anda terlepas dari format output
ls
.-mindepth
melompati direktori itu sendiri,-maxdepth
mencegah secara rekursif mempertahankan ke dalam subdirektori untuk mempercepat.sumber
wc -l
danfind
format output (yang cukup sederhana sekalipun).Menggunakan array:
sumber
shopt -s nullglob
${#files[@]} == 2
asumsi tidak berdiri untuk dir root (Anda mungkin tidak akan menguji apakah itu kosong tapi beberapa kode yang tidak tahu tentang batasan yang mungkin).Cara PID bebas hack, tapi khusus, hanya:
Ini mengambil keuntungan dari fakta bahwa
test
builtin keluar dengan 2 jika diberikan lebih dari satu argumen setelah-e
: Pertama,"$1"/*
bola diperluas oleh bash. Ini menghasilkan satu argumen per file. BegituJika tidak ada file, tanda bintang di
test -e "$1"*
tidak berkembang, jadi Shell kembali ke mencoba file bernama*
, yang mengembalikan 1.... kecuali jika sebenarnya ada satu file yang dinamai persis
*
, maka asterisk mengembang dengan baik, asterisk, yang berakhir dengan panggilan yang sama seperti di atas, yaitu.test -e "dir/*"
, kali ini mengembalikan 0. (Terima kasih @ TrueY telah menunjukkan ini.)Jika ada satu file,
test -e "dir/file"
jalankan, yang mengembalikan 0.Tetapi jika ada lebih banyak file dari 1,
test -e "dir/file1" "dir/file2"
dijalankan, yang bash melaporkannya sebagai kesalahan penggunaan, yaitu 2.case
membungkus seluruh logika sekitar sehingga hanya kasus pertama, dengan 1 status keluar dilaporkan berhasil.Kemungkinan masalah yang belum saya periksa:
Ada lebih banyak file daripada jumlah argumen yang diperbolehkan - Saya kira ini bisa berperilaku mirip dengan kasus dengan 2+ file.
Atau sebenarnya ada file dengan nama kosong - Saya tidak yakin itu mungkin pada OS waras / FS.
sumber
test -e dir/*
dipanggil. Jika satu-satunya file adalah '*' dalam dir maka tes akan mengembalikan 0. Jika ada lebih banyak file, maka itu mengembalikan 2. Jadi itu berfungsi seperti yang dijelaskan.Dengan FIND (1) (di Linux dan FreeBSD) Anda dapat melihat entri direktori secara non-rekursif melalui "-maxdepth 0" dan menguji apakah itu kosong dengan "-empty". Diterapkan pada pertanyaan ini memberikan:
sumber
Saya pikir solusi terbaik adalah:
terima kasih kepada https://stackoverflow.com/a/91558/520567
Ini adalah pengeditan anonim dari jawaban saya yang mungkin atau mungkin tidak bermanfaat bagi seseorang: Sedikit perubahan memberikan jumlah file:
Ini akan berfungsi dengan benar bahkan jika nama file mengandung spasi.
sumber
EDIT: Saya pikir solusi ini berfungsi baik dengan gnu find, setelah sekilas melihat implementasinya . Tetapi ini mungkin tidak bekerja dengan, misalnya, temuan netbsd . Memang, yang satu menggunakan bidang st_size stat (2). Manual menggambarkannya sebagai:
Solusi yang lebih baik, juga lebih sederhana, adalah:
Juga, -prune dalam solusi pertama tidak berguna.
EDIT: no -exit for gnu find .. solusi di atas bagus untuk temuan NetBSD. Untuk menemukan GNU, ini harus bekerja:
sumber
-exit
predikat .Ini semua adalah hal yang luar biasa - cukup buat menjadi skrip sehingga saya dapat memeriksa direktori kosong di bawah ini. Di bawah ini harus dimasukkan ke dalam file yang disebut 'findempty', ditempatkan di jalan di suatu tempat sehingga bash dapat menemukannya dan kemudian chmod 755 untuk dijalankan. Dapat dengan mudah diubah untuk kebutuhan spesifik Anda, saya kira.
sumber
Ini berfungsi untuk saya, untuk memeriksa & memproses file dalam direktori
../IN
, mengingat skrip ada di../Script
direktori:sumber
Bagaimana dengan pengujian jika direktori ada dan tidak kosong dalam pernyataan if
sumber
Untuk direktori apa pun selain yang sekarang, Anda dapat memeriksa apakah itu kosong dengan mencobanya
rmdir
, karenarmdir
dijamin gagal untuk direktori yang tidak kosong. Jikarmdir
berhasil, dan Anda benar-benar ingin direktori kosong untuk bertahan dalam ujian, cukup lakukanmkdir
lagi.Jangan gunakan peretasan ini jika ada proses lain yang mungkin menjadi disobobobulasi oleh direktori yang mereka ketahui tentang penghentian sebentar.
Jika
rmdir
tidak bekerja untuk Anda, dan Anda mungkin sedang menguji direktori yang berpotensi mengandung banyak file, solusi apa pun yang mengandalkan shell globbing bisa menjadi lambat dan / atau mengalami batas panjang baris perintah. Mungkin lebih baik digunakanfind
dalam kasus itu.find
Solusi tercepat yang bisa saya pikirkan berjalan sepertiIni berfungsi untuk versi GNU dan BSD
find
tetapi tidak untuk Solaris, yang tidak memiliki semuafind
operator tersebut. Cintai pekerjaanmu, Oracle.sumber
Anda dapat mencoba menghapus direktori dan menunggu kesalahan; rmdir tidak akan menghapus direktori jika tidak kosong.
sumber
rmdir
akan gagal jika saya tidak memiliki izin untuk menghapus direktori; atau jika itu adalah subvolume Btrfs; atau jika itu milik sistem file read-only. Dan jikarmdir
tidak gagal danmkdir
berjalan: bagaimana jika direktori yang sudah dihapus milik pengguna lain? bagaimana dengan izinnya (mungkin non-standar)? ACL? atribut yang diperluas? Semua hilang.