“Tidak ada file atau direktori” ketika mencoba menghapus file, tetapi file itu ada?

21

Saya mencoba menghapus gambar png yang diunggah ke server saya melalui skrip PHP. Setiap kali saya mencoba menghapusnya baik melalui ftp dan terminal, saya mendapatkan kesalahan

No such file or directory

Namun, ketika saya lsdi dir, file tersebut terdaftar dan juga terdaftar di klien ftp saya. Saya telah mencoba membuat file dengan nama yang sama dan akhirnya saya mendapatkan dua file dengan nama yang sama.

Saya dapat membuka file yang seharusnya tidak ada, tetapi saya masih tidak bisa menghapusnya. Saya juga mencoba me-reboot server saya. Ada ide apa masalahnya? Saya menjalankan versi 64 bit dari Ubuntu, tapi saya rasa itu bukan masalah 32/64. Saya juga harus mencatat bahwa saya telah menghapus banyak file png lainnya yang diunggah oleh skrip PHP yang sama.

Output untuk ls -l

total 224 
-rw-r--r-- 1 www-data www-data 222838 May 13 04:14 qyxdshyikfr_fishing_timeout.png 
-rw-r--r-- 1 root root 272 May 14 06:54 upload.php

Keluaran saat mencoba rm

rm: cannot remove ‘qyxdshyikfr_fishing_timeout.png’: No such file or directory

upload.php: http://pastebin.com/z87eypTY

DevinFrench
sumber
Salin tempel keluaran dari ls -ldirektori, juga rmperintah lengkap dan hasilnya ..
heemayl
@heemayl total 224 -rw-r - r-- 1 www-data www-data 222838 13 Mei 04 04 qyxdshyikfr_fishing_timeout.png -rw-r - r-- 1 root root 272 Mei 14 06:54 upload.php rm: tidak dapat menghapus 'qyxdshyikfr_fishing_timeout.png': Tidak ada file atau direktori seperti itu
DevinFrench
1
@DevinFrench, harap edit pertanyaan Anda untuk menambahkan informasi.
muru
Dari direktori mana Anda menjalankan rmperintah?
heemayl
1
@Samuel Mengapa ini menyarankan masalah sistem file? The unlinkpanggilan akan selalu gagal untuk menemukan file yang tidak ada. Ketika saya menjalankan straceperintah itu di sistem saya , di mana saya tahu saya tidak punya file seperti itu, itu menghasilkan output yang sama; Saya tidak berpikir itu menunjukkan saya memiliki masalah sistem file! Tampaknya jauh lebih mungkin bahwa nama file sedikit berbeda qyxdshyikfr_fishing_timeout.pngdan hanya muncul sama karena keterbatasan dalam cara lsmenampilkan nama file, seperti yang disarankan dalam jawaban lain.
Eliah Kagan

Jawaban:

21

Saya telah mencoba membuat file dengan nama yang sama dan akhirnya saya mendapatkan dua file dengan nama yang sama.

Yang mengatakan, tidak ada korupsi filesystem, bahwa Anda memiliki dua file dengan dua nama berbeda yang muncul sama karena karakter yang tidak dicetak atau karakter yang terlihat sama di set karakter Anda / font. The --escapepilihan untuk lsadalah teman Anda dalam kasus tersebut, seperti alat seperti cat -v.

Begitu juga rm -i -- *

Bacaan lebih lanjut

JdeBP
sumber
Saya adalah pencipta file dan nama file yang diunggah. Tidak ada yang mencoba menyabotase server saya karena saya satu-satunya orang yang tahu jalur lengkap untuk mengunggah.php Namun, rm -i -- *lakukan triknya.
DevinFrench
3
@DevinFrench Jika jawaban ini menyelesaikan masalah Anda, harap tandai sebagai jawaban yang diterima dengan mengklik tanda di bawah jumlah upvotes, sehingga pengguna di masa mendatang mungkin menyadari fakta bahwa solusi ini bekerja untuk Anda.
kos
1
Bisakah seseorang menjelaskan rm -i -- *perintah?
user3731622
Dari apa yang saya mengerti: Passing -i akan meminta Anda sebelum menghapus setiap file. --sebelum *memilih semua file terlepas dari apakah namanya termasuk karakter khusus. Referensi: https://explainshell.com/explain?cmd=rm+-i+--+*
MoltenMuffins
16

TL; DR: Jalankan ls -1b, cari nama file, salin baris yang muncul, dan berikan itu rm.

Seperti yang disarankan orang lain, kemungkinan besar ini karena keterbatasan dalam cara ls- dan beberapa program lain, termasuk klien dan perangkat lunak server - menangani nama file aneh, seperti yang berisi karakter kontrol, secara default. Keberhasilan Anda dengan jawaban JdeBP sangat menyarankan ini adalah masalahnya, meskipun itu akan menjadi taruhan yang baik bahkan sebelum itu.

  • Sebab ls, ketika output standar adalah terminal, ?karakter dicetak di tempatnya. Jadi, jika Anda tidak memipipkan lskeluaran ke perintah lain (atau mengarahkannya ke log untuk dilihat), mungkin nama file Anda tidak mengandung karakter kontrol. Tetapi ada karakter bermasalah lainnya - mungkin nama file mengandung spasi spasi, misalnya.

    Perilaku ini lsdapat membingungkan tetapi bukan bug, dapat ditimpa secara eksplisit oleh pengguna (lihat di bawah).

  • Ketika mencoba mengakses atau menghapus file dari jarak jauh, bug di perangkat lunak klien atau server dapat menghasilkan masalah seperti itu.

    Saya telah mengalami hal semacam ini melalui ftpdiri saya sendiri beberapa kali , termasuk untuk file yang namanya berisi spasi tambahan. (Bahwa itu tidak berhasil adalah karena bug di klien ftp saya.) Bahkan ketika Anda secara manual membuat file sendiri, tergantung pada bagaimana Anda membuatnya, kadang-kadang cukup mudah untuk secara tidak sengaja memasukkan spasi tambahan, atau spasi putih lain yang mungkin terlihat seperti spasi meskipun tidak.

Ini adalah situasi di mana ls -1b(atau dir -1) berguna:

  • -1memberitahu lsuntuk menunjukkan satu entri per baris. Dengan begitu tidak ada kebingungan tentang di mana satu nama file berakhir dan yang lain dimulai. Ini berguna untuk file dengan nama yang aneh.
  • -bmemberitahu lsuntuk mencetak urutan pelarian untuk setiap karakter khusus. Keluaran dari ls -bdapat disalin dan ditempelkan secara harfiah ke dalam perintah, tanpa mengutip tambahan : semua karakter bermasalah sudah dikutip dengan cara yang menyebabkan shell mengenali mereka sebagai apa adanya.

Hanya ada satu peringatan: jika karakter terakhir pada sebuah baris muncul \, salin satu karakter setelah itu, karena ini berarti \mengutip spasi.

Anda bisa menjalankannya ls -1bbegitu saja, atau Anda bisa meneruskan pola gumpalan shell ke sana (mis., ls -1b qyx*). Globbing mungkin atau mungkin tidak menemukan file, tergantung pada apakah karakter kontrol (atau karakter aneh lainnya) ada di bagian nama yang muncul dalam pola glob.

Setelah menyalin \versi -quote dari nama file yang diberikan kepada Anda oleh ls, Anda dapat menempelkannya ke dalam perintah. Anda tidak perlu memodifikasinya secara manual dengan cara apa pun. Dalam kasus Anda, saat Anda ingin menghapus file, ketik rm, ketik spasi, tempel baris, dan tekan Enter.

Bacaan lebih lanjut:

Eliah Kagan
sumber
1
Sangat keren -bthx =) dan +1
AB
Sesuatu yang saya tinggalkan dari OP adalah ketika saya membuat file dengan nama yang sama, di klien ftp saya ketika saya mencoba untuk menghapus file pertama yang saya mengalami masalah, itu malah akan menghapus file baru yang saya buat. Itu sebabnya saya tidak berpikir ada karakter khusus yang terlibat, dan saya masih tidak tahu apa karakter khusus itu sejak saya gunakan rm -i -- *.
DevinFrench
@DevinFrench Karakter ekstra adalah spasi di akhir nama file. Itu masih dalam lsoutput dalam pertanyaan, tetapi hanya dapat dilihat dalam mode teks ketika Anda mengklik "edit".
Izkata
@Izkata Panggilan bagus! Aku seharusnya berpikir untuk memeriksanya. Itu juga muncul ketika saya memperluas revisi 3 di histori edit (nama file lengkap, termasuk ruang trailing, disorot dalam warna hijau dan karenanya dapat dilihat). Apa yang Anda katakan adalah penjelasan yang paling pasti dan paling benar sejauh ini - jika Anda memposting jawaban yang menjelaskan bahwa itu berasal dari ruang tambahan, dan bagaimana Anda tahu, dan perintah apa yang akan menghapus file (jika OP masih memilikinya) , Saya tahu saya akan membatalkannya.
Eliah Kagan
@EliahKagan Selesai, dengan gambar
Izkata
3
  1. Gunakan finddan periksa hasilnya:

    Jika file tidak ditemukan, maka persingkat istilah pencarian *qyxdshyikfr*sedikit, misalnya: *qyxds*atau *fishing*.

    sudo find . -maxdepth 1 -type f -name "*qyxdshyikfr*"
    
  2. Jika ok, daripada gunakan finddengan istilah pencarian di langkah 1 danrm

    find . -maxdepth 1 -type f -name "*qyxdshyikfr*" -print0 | xargs -0  rm
    
AB
sumber
1
Daripada menelepon rmdengan nama melalui pipa dari findke xargs, saya sarankan hanya menggunakan find's -deletetindakan. Juga sudotidak diperlukan. Kurang signifikan, saya sarankan menghilangkan -type fkecuali itu jelas membantu. Agaknya jika entri yang ingin dihapus OP ternyata adalah tautan simbolis, misalnya, mereka masih ingin menemukannya dan masih ingin menghapusnya. The -deletetindakan tidak akan rekursif mengkritik direktori; tidak akan rmperintah Anda karena Anda tidak punya -r. Jadi, Anda tidak akan secara tidak sengaja memukul folder utuh (tidak kosong) di sini dengan tidak menggunakan -type.
Eliah Kagan
OK, beri saya waktu sebentar.
AB
Dalam kasus saya, bahkan find ... -deletemengatakan "tidak dapat menghapus ... Tidak ada file atau direktori"
Stop Harming Monica
1

Reposting secara detail, diperluas dari komentar saya pada jawaban Eliah

Masalahnya tidak terlihat, tetapi dapat dilihat jika Anda tahu apa yang harus dicari: Nama file termasuk spasi di bagian akhir. Karena Anda menyalin / menempelkan seluruh lsoutput, itu dapat dilihat dalam pertanyaan jika Anda menyorot output, atau mengedit posting dan memindahkan kursor ke akhir, atau (seperti yang ditunjukkan Eliah) melihat perbedaan dalam histori edit. Saya menyoroti lsoutput dalam pos di tangkapan layar ini:

Ruang ekstra

Sesi terminal kecil cepat untuk menduplikasi masalah, dengan komentar:

$ touch 'foo '        # Create file with a space at the end
$ ls -l               # Space is not visible in ls output
total 0
-rw-rw-r-- 1 izkata izkata 0 May 14 21:59 foo 

$ rm foo              # Cannot remove it when not specifying the space
rm: cannot remove ‘foo’: No such file or directory

$ rm 'foo '           # Can remove it if we quote the file name and include the space
$ rm foo\             # Or can escape the space to tell bash to include it as part of the filename

Menggunakan penyelesaian tab juga akan sepenuhnya menghindari masalah di sini, karena bash cukup pintar untuk keluar dari ruang dengan benar (Ini juga merupakan kebiasaan yang baik pada umumnya, mempercepat jalur pengetikan begitu banyak) .

Sebagai contoh, seandainya saya mengetik rm f<tab>, maka akan selesai secara otomatis rm foo\<space><space>, seperti pada contoh terakhir di blok kode di atas.

Izkata
sumber
Saya secara khusus menyebutkan copy / paste lsoutput karena sesuatu yang serupa terjadi pada StackOverflow sekali (dan seluruh alasan saya berpikir untuk mencari ini): seseorang mendapat karakter yang tidak dapat dicetak dalam kode mereka, dan satu-satunya alasan ada yang tahu karena pengguna itu juga menyalin / menempel alih-alih mengetik ulang kode mereka saat memposting pertanyaan
Izkata
0

sekali, saya telah membuat file untuk membuka Nautilus sebagai root, tetapi nama file ketika melihat dari nautilus adalah "File Browser (root)", lalu ketika saya mencoba menghapus sebagai

$ rm "File Browser (Root)"
$ sudo rm "File Browser (Root)"
$ sudo rm "File Browser (Root).desktop"

satu-satunya server yang saya dapatkan adalah: "rm: tidak dapat menghapus 'File Browser (Root) .desktop': Tidak ada file atau direktori"

maka ketika saya menjalankan:

$ ls -l

saya melihat / mengingat bahwa nama file itu, sebenarnya, adalah "Nautilus-root.desktop"

jadi saya jalankan:

$ sudo rm "Nautilus-root.desktop"

bekerja untuk saya, semoga membantu!

Wagner Arcieri
sumber
0

Jadi saya punya masalah ini dan tidak ada yang berhasil untuk saya. Apa yang berhasil adalah membuat file dengan nama yang sama persis. Itu adalah folder bernama Example.1.2.3 jadi saya membuat folder baru dan menamakannya sama persis dengan yang tidak akan dihapus. Folder lama menghilang dan saya menghapus yang baru.

Jamison Lifsey
sumber
0

Saya memiliki situasi yang sama, setelah menggunakan rsyncuntuk membackup direktori Pictures saya di Mac dan membacanya di Ubuntu. Ada dua file (sebenarnya direktori) dengan nama yang berbeda, tetapi memiliki konten yang sama. Saya menghapus satu ke Sampah (menggunakan Nautilus), tetapi tidak bisa menghapus yang lain, bahkan dari baris perintah. Itu akan mengatakan:

$ rmdir Pictures
rmdir: failed to remove 'Pictures': No such file or directory
$ rm Pictures
rm: cannot remove 'Pictures': Is a directory

Setelah memeriksa nomor inode dengan ls -i-l ternyata kedua direktori memiliki nomor inode yang sama. Tampak seperti tautan keras ...

Solusinya sangat sederhana - mengosongkan Sampah dengan mengklik kanan ikon. Setelah itu kedua direktori hilang.

elomage
sumber