Bir dizinin veya dosyanın sahibini bulun, ancak yalnızca bunu ve başka bir şey döndürmeyin


62

Bir dizinin sahibini döndürecek bir komut arıyorum ve yalnızca ls -latkomutu - komutu düzenlemek veya regex gibi bir şey mi? Sonucu başka bir betikte kullanmak istiyorum.

Yanıtlar:


102

stat dan GNU coreutils yapabilirsiniz:

stat -c '%U' /path/of/file/or/directory

Ne yazık ki, bazı sürümleri statvardır ve bunların sözdizimlerinde çok fazla tutarlılık yoktur. Örneğin, FreeBSD’de

stat -f '%Su' /path/of/file/or/directory

Taşınabilirliği bir husustur, kullanmakta muhtemelen daha çok işinize Gilles önerisini birleştirerek lsve awk. Biri yerine iki işlemi başlatması gerekir, ancak yalnızca POSIX standardı işlevsellik kullanma avantajına sahiptir:

ls -ld /path/of/file/or/directory | awk '{print $3}'

2
kısalık bir bonus ise stat -c% U / yolu.
tsvallender

1
Bu, eski Linux sistemlerinde olmayan yeni GNU stat'lerini (daha yeni sistemlerde bile dikkatli olacağım , kullanıcının evinde veya statbir yerinde farklı (site çapında bir standart olabilir) olabilir /usr/local/binve nadiren kullanılabilir. diğer birliklerde.
Gilles

1
stat -c %UAyrıca , komut derlenirse BusyBox ile de çalışabilme avantajına sahiptir stat.
Gilles

1
Güzel, son örnek (ls) hem Unix / OSX hem de Linux'ta çalışıyor
kenorb,

1
Not Sahibine uyan yerel bir kullanıcı yoksa, yani kullanıcı ağını (ör. Ağ paylaşımında), ancak stat -c '%U' DIRbu kullanıcılara UNKNOWNnasıl baktığınıza bağlı olarak daha az yardımcı veya daha uygun olanı yazdırır .
Temel6

18

Çıktısının ayrıştırılması lsnadiren iyi bir fikirdir , ancak ilk birkaç alanı elde etmek bir istisnadır, aslında tüm “geleneksel” birimlerde çalışır (kullanıcı adlarında boşluk sağlayan bazı Windows uygulamaları gibi platformlarda çalışmaz).

ls -ld /path/to/directory | awk 'NR==1 {print $3}'

Başka bir seçenek bir statkomut kullanmaktır , ancak statkabuktan kaynaklanan sorun farklı sözdizimine sahip birden fazla komut bulunmasıdır, bu nedenle statbir kabuk komut dosyasında (Linux kurulumlarında bile) desteklenemez.

Belirli bir kullanıcının sahibi olup olmadığının test edilmesinin farklı bir teklif olduğunu unutmayın.

if [ -n "$(find . -user "$username" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by $username."
fi
if [ -n "$(find . -user "$(id -u)" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by the current user."
fi

Burada belirttiğimls | awk gibi, ne yazık ki yaklaşımı ile bazı uyarılar vardır . Son yorumumda bahsettiğim "hedef dosya / dir farklı bir isme sahip bir sembolik bağlantı" sorunu için henüz bir çözüm bulamadım.
beporter

Yerine find . -user "$username" -print -prune -o -prunesadece yapabilirdifind . -maxdepth 0 -user "$username"
Niklas Holm

@Gilles awk 'NR==1 {print $3}'Sadece kullanmak yerine herhangi bir sebep var mı awk '{print $3}'? Neden NR==1burada gerekli olduğundan emin değilim .
Harold Fischer

1
@HaroldFischer Yalnızca yolun yeni bir satır içerdiği kenar durumunda. Nadiren gerekli, fakat asla zararlı değil.
Gilles

@Gilles Bilmek çok iyi! Merak ediyorum, lsbir yoldaki bir yeni çizginin, çizginin ikiye bölünmesine neden olduğu bir uygulamanın farkında mısınız? GNU ls(newish versiyonu), BusyBox lsve FreeBSD lsbir satır olarak döndürülür $'\n', ?ve ?sırasıyla.
Harold Fischer

9

Bir de GNU bulmak ile bunu yapabilirsiniz:

find $directoryname -maxdepth 0 -printf '%u\n'

Bu GNU sisteminin dışında taşınabilir değil, ancak çalışmadığı bir Linux dağıtımı bulduğumda şaşırdım.


1
Bu, tüm gömülü olmayan Linux sistemlerinde ve birkaç diğerinde (örn. Cygwin) çalışır. Gömülü sistemler olması muhtemeldir Busybox olan, findyok -printf.
Gilles,

Dediğim gibi, GNU sistemi.
mattdm

GNU -printf
çekirdeği

@pevik Evet, dediğim gibi, hala. Fakat eğer ihtiyacınız olursa GNU bul programını kurabilirsiniz. :)
mattdm

@mattdm: her zaman değil :-(. En önemlisi, portatif olması gereken scriptler yazdığınızda.
pevik

2

Saf bash'te çıktısını lsbir diziye ve dizine dönüştürebilirsiniz.

# (lrwxr-xr-x, 1, myuser, staff, 36, Oct, 21, 16:36, /path/to/file)    
file_meta=($(ls -ld /path/to/file))
file_owner="${file_meta[2]}" # myuser

Bu kullanmak kadar zarif değil stat, findya awk, ama bir çimdik işe yarayabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.