, 2018-06-01 tarihinde yayınlanmıştır olarak cevaplardan hiçbiri hariç tarafından gönderildi tek komut satırının foxidrive , gerçekten tüm dosya ve tüm klasörleri / dizinleri silinmiş %PathToFolder%
. Bu, bir klasörün tüm dosyalarını ve alt klasörlerini silmek için çok basit bir tek komut satırı ile bir yanıt daha göndermenin nedeni ve 2018-06-01'de DEL kullanılarak gönderilen diğer tüm yanıtların neden açıklandığını daha karmaşık bir çözüm içeren bir toplu iş dosyası ve RD ile FOR bir klasörü tamamen temizleyemedi.
Elbette bir toplu iş dosyasında kullanılabilen basit tek komut satırı çözümü:
pushd "%PathToFolder%" 2>nul && ( rd /Q /S "%PathToFolder%" 2>nul & popd )
Bu komut satırı, birbiri ardına yürütülen üç komut içerir.
İlk komut PUSHD, geçerli dizin yolunu yığına iter ve daha %PathToFolder%
sonra geçerli dizini komut işlemini çalıştırmak için yapar .
Bu , komut uzantıları varsayılan olarak etkinleştirildiğinden varsayılan olarak UNC yolları için de çalışır ve bu durumda PUSHD , belirtilen ağ kaynağına işaret eden geçici bir sürücü harfi oluşturur ve ardından yeni tanımlanmış sürücü harfini kullanarak geçerli sürücüyü ve dizini değiştirir.
PUSHD , belirtilen dizin hiç yoksa STDERR'yi işlemek için aşağıdaki hata iletisini verir :
Sistem belirtilen yolu bulamıyor.
Bu hata iletisi, NUL2>nul
aygıtına yeniden yönlendirilerek bastırılır .
Bir sonraki komut RD , yalnızca geçerli komut işlemi için geçerli dizini belirtilen dizine değiştirmek başarılı olduğunda, yani belirtilen dizinin var olması durumunda yürütülür.
Komut RD seçenekleri ile /Q
ve /S
bir dizini kaldırır sessizce tüm alt dizinleri belirtilen dizin gizli özellik ya da salt okunur özellik seti ile dosya veya klasörleri içerse bile. System özniteliği hiçbir zaman bir dosya veya klasörün silinmesini engellemez.
Silinmemiş olanlar:
Çalışan herhangi bir işlem için geçerli dizin olarak kullanılan klasörler. Herhangi bir çalışan işlem için geçerli dizin olarak bir klasör kullanılırsa, böyle bir klasöre ait klasör ağacının tamamı silinemez.
Çalışan uygulama / işlem tarafından açılırken dosyanın silinmesini önlemek için, dosya üzerinde izin verilen dosya erişim izinleri açık olarak çalışan herhangi bir işlem tarafından o anda açılmış olan dosyalar. Bu şekilde açılan bir dosya, klasör ağacının tamamının açılan dosyaya silinmesini de önler.
Geçerli kullanıcının, dosya / klasörü silmek için gerekli (NTFS) izinlerine sahip olmadığı dosyalar / klasörler, klasör ağacının bu dosyaya / klasöre de silinmesini önler.
Bir klasörü silmemenin ilk nedeni, bu komut satırı tarafından belirtilen klasörün tüm dosyalarını ve alt klasörlerini silmek için kullanılır, ancak klasörün kendisini değil. Klasör geçici olarak geçerli dizinin kendisi için silinmesini önleyen komut işlemi çalıştırmak için yapılır. Tabii ki bu RD komutu tarafından bir hata mesajı çıktısı ile sonuçlanır :
Başka bir işlem tarafından kullanıldığından işlem dosyaya erişemiyor.
Burada dosya yanlış terimdir, çünkü gerçekte klasör başka bir işlem tarafından kullanılıyor, RD komutunu uygulayan geçerli komut işlemi . Aslında, bir klasör dosya sistemi için bu hata mesajını açıklayan dosya özniteliği dizinine sahip özel bir dosyadır . Ancak dosya sistemi yönetimine çok fazla girmek istemiyorum.
Bu hata mesajı, yukarıda yazılan üç nedenden ötürü oluşabilecek diğer tüm hata mesajları gibi, STDERR2>nul
tutamacından NUL cihazına yönlendirilerek bastırılır .
Üçüncü komut olan POPD , RD komutunun çıkış değerinden bağımsız olarak yürütülür .
POPD , PUSHD tarafından yığından itilen dizin yolunu açar ve komut işlemini bu dizine çalıştırmak için geçerli dizini değiştirir, yani ilk geçerli dizini geri yükler. POPD , UNC klasör yolu durumunda PUSHD tarafından oluşturulan geçici sürücü harfini siler .
Not: İlk geçerli dizinin temizlenecek dizinin artık bulunmayan bir alt dizini olması durumunda POPD sessizce ilk geçerli dizini geri yükleyemez. Bu özel durumda %PathToFolder%
geçerli dizin kalır. Bu nedenle, yukarıdaki komut satırını bir alt dizininden değil çalıştırmanız önerilir %PathToFolder%
.
Daha ilginç bir gerçek:
Komut satırını aynı zamanda UNC yolunu kullanarak C:\Temp
paylaşım adı ile yerel dizini paylaşarak Temp
ve Windows 7'de \\%COMPUTERNAME%\Temp\CleanTest
ortam değişkenine atanmış UNC yolunu kullanarak da denedim. PathToFolder
UNC yolu kullanılarak erişilen klasör C:\Temp\CleanTest\Subfolder1
, RDSubfolder1
tarafından silinir ve bir sonraki POPD , geçerli dizini yeniden oluşturmada sessizce başarısız olur ve yerel bir dizinin gerçekten var olmasına neden olur . Maalesef POPDC:\Temp\CleanTest\Subfolder1
Z:\CleanTest
çalıştıran komut işlemi için geçerli dizin olarak kalan. Bu çok, çok özel bir durumda, geçici sürücü harfi geçerli dizin değiştirilinceye kadar aynı kalır.cd /D %SystemRoot%
ilk geçerli dizini geri yükleyemezse 0'dan büyük bir değerle çıkmaz, bu da yalnızca POPD'nin çıkış kodunu kullanarak bu çok özel hata koşulunu algılamayı imkansız hale getirir . Bununla birlikte, UNC yolları genellikle yerel dosyalara ve klasörlere erişmek için kullanılmadığından kimsenin bu çok özel hata durumuna hiç girmediği varsayılabilir.
Kullanılan komutları daha iyi anlamak için, bir komut istemi penceresi açın, orada aşağıdaki komutları yürütün ve her komut için görüntülenen yardımı çok dikkatli bir şekilde okuyun.
Windows toplu iş dosyası kullanan birden fazla komut içeren tek satır , operatörleri açıklar &&
ve &
burada kullanılır.
Sonraki bize komut kullanarak toplu iş dosyası çözüm üzerinde bakalım DEL dosyaları silmek %PathToFolder%
ve FOR ve RD de alt klasörleri silmek için %PathToFolder%
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Clean the folder for temporary files if environment variable
rem PathToFolder is not defined already outside this batch file.
if not defined PathToFolder set "PathToFolder=%TEMP%"
rem Remove all double quotes from folder path.
set "PathToFolder=%PathToFolder:"=%"
rem Consisted the folder path only of double quotes?
if not defined PathToFolder goto EndCleanFolder
rem Remove a backslash at end of folder path.
if "%PathToFolder:~-1%" == "\" set "PathToFolder=%PathToFolder:~0,-1%"
rem Consisted folder path only of a backslash (with one or more double quotes)?
if not defined PathToFolder goto EndCleanFolder
rem Delete all files in specified folder including files with hidden
rem or read-only attribute set, except the files currently opened by
rem a running process which prevents deletion of the file while being
rem opened by the application, or on which the current user has not
rem the required permissions to delete the file.
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
rem Delete all subfolders in specified folder including those with hidden
rem attribute set recursive with all files and subfolders, except folders
rem being the current directory of any running process which prevents the
rem deletion of the folder and all folders above, folders containing a file
rem opened by the application which prevents deletion of the file and the
rem entire folder structure to this file, or on which the current user has
rem not the required permissions to delete a folder or file in folder tree
rem to delete.
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
:EndCleanFolder
endlocal
Toplu iş dosyası önce ortam değişkeninin PathToFolder
çift tırnaksız ve sonunda ters eğik çizgi olmadan bir klasör yolu ile gerçekten tanımlandığından emin olur . Sondaki ters eğik çizgi sorun olmaz, ancak bir klasör yolundaki çift tırnak işaretleri, PathToFolder
toplu iş dosyası yürütme sırasında değeri diğer dizelerle birleştirildiği için sorunlu olabilir .
İki satır önemlidir:
del /A /F /Q "%PathToFolder%\*" >nul 2>nul
for /F "eol=| delims=" %%I in ('dir "%PathToFolder%\*" /AD /B 2^>nul') do rd /Q /S "%PathToFolder%\%%I" 2>nul
DEL komutu belirtilen dizindeki tüm dosyaları silmek için kullanılır.
- Bu seçenek
/A
, DEL'in seçeneği kullanmadan yok sayacağı gizli özellikli dosyalar da dahil olmak üzere tüm dosyaları işlemek için gereklidir /A
.
- Bu seçenek
/F
, salt okunur öznitelik ayarlı dosyaların silinmesini zorlamak için gereklidir.
- Bu seçenek
/Q
, kullanıcıya birden fazla dosyanın gerçekten silinip silinmeyeceğini sormadan birden fazla dosyanın sessiz bir şekilde silinmesini çalıştırmak için gereklidir.
>nul
STDOUT'u işlemek için yazılan dosya adlarının çıktısını , şu anda bir dosya açıldığı veya kullanıcının dosyayı silme iznine sahip olmadığı için silinemeyen NUL aygıtına yeniden yönlendirmek için gereklidir .
2>nul
STDERR tanıtıcısından silinemeyen her dosya için hata iletisi çıktısını NUL aygıtına yeniden yönlendirmek gerekir .
FOR ve RD komutları , belirtilen dizindeki tüm alt dizinleri kaldırmak için kullanılır. Ama for /D
yüzünden kullanılmaz İÇİN gizli özellik seti ile bu durum altdizinlere görmezden geliyor. Bu nedenle for /F
, aşağıdaki komut satırını arka planda başlatılan ayrı bir komut işleminde çalıştırmak için kullanılır %ComSpec% /c
:
dir "%PathToFolder%\*" /AD /B 2>nul
DIR/B
, özniteliğe sahip dizin girişleri nedeniyle D
bir yolla gizli öznitelik gibi diğer özniteliklerden bağımsız olarak belirtilen dizindeki tüm alt dizinlerin adları nedeniyle çıplak biçimde çıkar . STDERR tanıtıcısından NUL aygıtına hiçbir dizin bulunamadığı için DIR2>nul
tarafından hata iletisi çıktısını yeniden yönlendirmek için kullanılır .
Yeniden yönlendirme işlecinin , FOR komut satırında, Windows komut yorumlayıcısı gömülü komut satırını ayrı bir komut işleminde yürüten FOR komutunu çalıştırmadan önce, bu komut satırını işlediğinde değişmez bir karakter olarak yorumlanacak >
caret karakteriyle kaçılmalıdır. arka planda.^
dir
FOR , yol olmadan alt dizinlerin adları olan ve hiçbir zaman çift tırnak içine alınmayan bir komut komutunun STDOUT'u işlemek için yazılan çıktıyı işler .
FOR seçeneği ile /F
burada gerçekleşmeyen boş satırları yoksayar çünkü seçeneği ile DIR/B
boş satırlar vermez.
FOR ayrıca, varsayılan satır sonu karakteri olan noktalı virgülle başlayan satırları yoksayar. Bir dizin adı noktalı virgülle başlayabilir. Bu nedenle eol=|
, dikey çubuk karakterini, adında hiçbir dizin veya dosyanın bulunamayacağı satır sonu karakteri olarak tanımlamak için kullanılır.
FOR , boşluk ve yatay sekmeyi ayırıcılar olarak kullanarak satırı alt dizelere böler ve belirtilen döngü değişkenine yalnızca ilk boşluk / sekmeyle ayrılmış dizeyi atar I
. Bir dizin adı bir veya daha fazla boşluk içerebileceğinden, bu bölme davranışı burada istenmiyor. Bu nedenle delims=
, satır bölme davranışını devre dışı bırakmak ve döngü değişkenine I
, her zaman tam dizin adı olarak atanmak için boş bir sınırlayıcı listesi tanımlamak için kullanılır .
Komut İÇİN komutu çalıştırır RD üzerinde neden olan bir yol içermeyen her dizin adı için RD alt klasör adı ile birleştirilmiş komut satırından klasör yolu bir kez daha belirtilmelidir.
Kullanılan komutları ve nasıl çalıştıklarını anlamak için bir komut istemi penceresi açın, orada aşağıdaki komutları yürütün ve her komut için görüntülenen tüm yardım sayfalarını çok dikkatli bir şekilde okuyun.
del /?
dir /?
echo /?
endlocal /?
for /?
goto /?
if /?
rd /?
rem /?
set /?
setlocal /?