Tìm chủ sở hữu của một thư mục hoặc tệp, nhưng chỉ trả lại và không có gì khác


62

Tôi đang tìm kiếm một lệnh sẽ trả về chủ sở hữu của một thư mục và chỉ có điều đó - chẳng hạn như một regex phân tích cú pháp ls -latlệnh hoặc một cái gì đó tương tự? Tôi muốn sử dụng kết quả trong một kịch bản khác.

Câu trả lời:


102

stat từ lõi core GNU có thể làm điều này:

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

Thật không may, có một số phiên bản statvà không có nhiều tính nhất quán trong cú pháp của chúng. Ví dụ, trên FreeBSD, nó sẽ là

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

Nếu tính di động là một mối quan tâm, có lẽ bạn nên sử dụng đề xuất kết hợp lsawk. Nó phải bắt đầu hai quy trình thay vì một, nhưng nó có lợi thế là chỉ sử dụng chức năng tiêu chuẩn POSIX:

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

2
stat -c% U / path, nếu ngắn gọn là phần thưởng.
tsvallender

1
Giả sử GNU stat, không phải là trường hợp trên các hệ thống Linux cũ hơn (ngay cả trên các hệ thống mới hơn tôi sẽ cảnh giác, có thể có một stattiêu chuẩn khác (trên toàn trang web) trong /usr/local/binhoặc ở đâu đó trong nhà của người dùng) và hiếm khi có sẵn trên các đơn vị khác.
Gilles 'SO- ngừng trở nên xấu xa'

1
stat -c %Ucũng có lợi thế khi làm việc với BusyBox , nếu statlệnh được biên dịch.
Gilles 'SO- ngừng trở nên xấu xa'

1
Thật tuyệt, ví dụ cuối cùng (ls) hoạt động cả trên Unix / OSX và Linux
kenorb

1
Lưu ý rằng ls sẽ in uid nếu không có người dùng cục bộ phù hợp với chủ sở hữu (nghĩa là trên chia sẻ mạng), nhưng stat -c '%U' DIRsẽ in UNKNOWN, điều này ít hữu ích hơn hoặc phù hợp hơn, tùy thuộc vào cách bạn nhìn vào nó.
bản6

18

Phân tích cú pháp đầu ra lshiếm khi là một ý tưởng hay , nhưng có được một vài trường đầu tiên là một ngoại lệ, nó thực sự hoạt động trên tất cả các thông báo truyền thống của truyền thống (nó không hoạt động trên các nền tảng như một số triển khai Windows cho phép khoảng trắng trong tên người dùng).

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

Một tùy chọn khác là sử dụng một statlệnh, nhưng vấn đề stattừ shell là có nhiều lệnh với cú pháp khác nhau, do đó, stattrong một kịch bản shell là không thể truy cập được (thậm chí trên các cài đặt Linux).

Lưu ý rằng kiểm tra xem một người dùng nhất định có phải là chủ sở hữu hay không là một đề xuất khác nhau.

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

Có một số cảnh báo với ls | awkcách tiếp cận quá tiếc, như tôi đã lưu ý ở đây . Tôi chưa đưa ra giải pháp cho "tệp mục tiêu / thư mục đích là một liên kết tượng trưng với một tên khác", vấn đề tôi đã đề cập trong bình luận gần đây.
beporter

Thay vì find . -user "$username" -print -prune -o -prunebạn chỉ có thể làmfind . -maxdepth 0 -user "$username"
Niklas Holm

@Gilles Có bất kỳ lý do bạn sử dụng awk 'NR==1 {print $3}'thay vì chỉ awk '{print $3}'? Tôi không chắc tại sao lại NR==1cần thiết ở đây.
Harold Fischer

1
@HaroldFischer Chỉ trong trường hợp cạnh có đường dẫn chứa dòng mới. Nó hiếm khi cần thiết, nhưng không bao giờ có hại.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Rất tốt để biết !! Chỉ tò mò, bạn có biết về việc triển khai lsmột dòng mới trong một đường dẫn làm cho dòng bị chia làm hai (mà tôi tin là trường hợp cạnh bạn đang cố gắng che)? Trên GNU ls(phiên bản mới), BusyBox lsvà FreeBSD, lsmột dòng mới được trả lại lần lượt là $'\n', ??, tương ứng.
Harold Fischer

9

Người ta cũng có thể làm điều này với GNU find:

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

Đây không phải là di động bên ngoài hệ thống GNU, nhưng tôi rất ngạc nhiên khi tìm thấy một bản phân phối Linux nơi nó không hoạt động.


1
Điều này hoạt động trên mọi hệ thống Linux không nhúng và một vài hệ thống khác (ví dụ Cygwin). Các hệ thống nhúng có thể có Busybox , findkhông có -printf.
Gilles 'SO- ngừng trở nên xấu xa'

Như tôi đã nói, hệ thống GNU.
mattdm

Các hệ thống không có -printf
lõi core

@pevik Vâng, như tôi đã nói, vẫn còn. Nhưng bạn có thể cài đặt GNU find nếu bạn cần. :)
mattdm

. @mattdm:. không phải lúc nào :-( quan trọng nhất khi bạn viết kịch bản đó nên cầm tay
pevik

2

Trong bash thuần, bạn có thể chuyển đổi đầu ra của lsmột mảng và lập chỉ mục vào nó.

# (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

Nó không phải là thanh lịch như sử dụng stat, findhoặc awk, nhưng có thể làm việc trong một pinch.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.