Bagaimana saya bisa menentukan proses apa yang memiliki file terbuka di Linux?

124

Saya ingin menentukan proses apa yang memiliki kepemilikan file kunci. File-file kunci hanyalah sebuah file dengan nama spesifik yang telah dibuat.

Jadi, bagaimana saya bisa menentukan proses apa yang memiliki file tertentu terbuka di Linux? Lebih disukai tipe satu-liner atau solusi alat Linux tertentu akan optimal.

Danny
sumber

Jawaban:

55

Anda juga dapat menggunakan fuserini:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc:              28135
~> ps 28135
  PID TTY      STAT   TIME COMMAND
28135 pts/36   T      0:00 less .vimrc
Nathan Fellman
sumber
ini hebat, tetapi untuk menggunakannya dalam skrip saya harus memeriksa panjang output.
chovy
apa maksudmu panjang output?
Nathan Fellman
if [ fuser "$ file" `]; lalu keluar`
chovy
1
fuser memiliki perilaku aneh dengan kode keluar. mengembalikan 1 kode akses dengan dua status: A / beberapa kesalahan internal, file yang diperiksa tidak ditemukan dll, B / tidak ada proses membuka file yang ditentukan. Dalam situasi A / beberapa pesan kesalahan dicetak ke outputnya. Sayangnya ketika file tersedia dan dibuka oleh sesuatu, output dihasilkan tetapi dengan kode keluar 0. Akan lebih baik jika fuser akan keluar dengan tiga kode, bukan dua seperti saat ini. lsoft adalah tekad yang sedikit lebih buruk karena ini bekerja lebih lambat.
Znik
Ini pada dasarnya adalah pola yang sama dengan yang lsberikut - ia mengembalikan kode keluar 2 jika ada kesalahan (misalnya, opsi tidak valid ditentukan) atau file tidak ditemukan (dan 0 jika berhasil melaporkan informasi).
Scott
144

Pada sebagian besar sistem Linux lsof NAMEmelakukan pekerjaan:

fin@r2d2:~$ lsof /home/fin
COMMAND   PID USER   FD   TYPE DEVICE SIZE    NODE NAME
bash    21310  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21320  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21321  fin  cwd    DIR    8,1 4096 5054467 /home/fin
fin@r2d2:~$
sirip
sumber
4
Dan bagaimana jika Anda tidak memiliki lsof?
JoseLSegura
3
@ JoseLSegura: Saya berasumsi Anda cukup akal untuk jawaban 'lalu instal lsof' menjadi tidak berguna untuk Anda. Bisakah Anda menguraikan masalah Anda? Jika Anda tidak memiliki root, Anda kemungkinan tidak memiliki privs untuk mengetahui apakah pengguna lain membuka file tersebut.
Michael Scheper
ini tampaknya tidak berfungsi untuk file, hanya untuk dirs
Jason
@Jason: ini berfungsi untuk file, tetapi cwdbaris (yang laporannya digunakan sebagai direktori kerja suatu proses saat ini) hanya melaporkan direktori.
reinierpost
9

Memiliki file yang terbuka bukanlah kunci karena, jika setiap proses harus memeriksa apakah file tersebut dibuka terlebih dahulu dan tidak melanjutkan jika itu adalah file atau membuat / membukanya jika tidak, maka dua proses dapat memeriksa dengan baik secara bersamaan, keduanya menemukan bahwa itu tidak terbuka, maka keduanya membuat atau membukanya.

Untuk menggunakan file sebagai kunci, operasi pemeriksaan dan penguncian harus merupakan operasi tunggal yang tidak terputus. Anda dapat mencapai ini dalam sistem file Unix dengan membuat file dengan mode hanya baca dan menghapusnya untuk membuka kunci. Jika file itu ada (dan hanya baca) pembuatan file akan gagal, sehingga Anda mendapatkan check-and-lock dalam satu operasi atom.

Jika proses penguncian Anda adalah skrip shell yang akan berjalan sebagai daemon, Anda bisa mendapatkan efek ini dengan menggunakan umask, pengaturan per-proses yang menetapkan izin yang membuat file baru dengan:

oldumask = $ (umask)
umask 222 # buat file juga tidak bisa ditulis oleh pemilik
jika echo $$> / var / lock / foo
kemudian
    : penguncian berhasil
lain
    : penguncian gagal
fi
umask $ oldumask
Ini juga menulis proses kepemilikan 'PID ke dalam file, yang memecahkan masalah Anda yang lain: cat /var/lock/foo
Mengenai pertanyaan spesifik "Proses mana yang membuka file ini?", Ini bisa berguna ketika Anda ingin meng-unmount sistem file tetapi tidak bisa karena beberapa proses memiliki file yang terbuka di dalamnya. Jika Anda tidak memiliki perintah-perintah itu, Anda dapat bertanya /procsebagai root:

ls -l /proc/*/cwd | grep '/var/lock/foo$'

atau, sebagai pengguna manusia:

ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'

martinwguy
sumber
metode `ls-l 'bekerja untuk Linux tetapi tampaknya tidak berfungsi untuk CygWin: tidak ada info tentang penguncian file di sana. Tidakkah Anda tahu bagaimana menyelesaikannya? Terima kasih.
Sopalajo de Arrierez
Tidak, Anda tidak membuat file read-only untuk kunci, karena ketika aplikasi Anda akan crash, file tersebut akan tetap ada. Memaksa pengguna untuk menghapus omong kosong setelah aplikasi Anda mogok mental.
polkovnikov.ph
6

Jika Anda ingin tahu deskriptor file proses mana yang ditautkan ke file Anda tanpa lsofatau fuser- cari melalui /proc:

$ find /proc -regex '\/proc\/[0-9]+\/fd\/.*' -type l -lname "*$1*" -printf "%p -> %l\n" 2> /dev/null

Ganti $1dengan nama file terbuka yang Anda cari. Anda dapat mengubah -printfuntuk apa pun yang ingin Anda lihat, atau pipa egrep -o '[0-9]+' | head -1untuk digunakan dengan untuk info proses itu.ps -Fp <pid>

The jawaban dengan @fin adalah jawaban terbaik, jelas, tapi untuk menjawab @ komentar JoseLSegura ini , jika ini tidak tersedia, solusi di atas adalah tanggapan saya.$ lsof <filename>

Scott
sumber
2

Saya menemukan bahwa menggunakan jawaban yang diterima tidak mencantumkan proses yang menggunakan direktori saya (ubuntu 14.04).

Pada akhirnya, saya menggunakan lsof (daftar file yang terbuka) dan menerima hasilnya untuk menemukan proses yang menyinggung:

lsof | egrep "<regexp-for-your-file>"
Eosis
sumber
Cara yang lebih bersih dan lebih cepat untuk penggunaan ini lsofadalah pilihannya -R. misal: lsof -R [filename]
tron5