Tôi thường muốn có được tên đăng nhập được liên kết với ID người dùng và vì nó được chứng minh là trường hợp sử dụng phổ biến, tôi đã quyết định viết một hàm shell để làm điều này. Mặc dù tôi chủ yếu sử dụng các bản phân phối GNU / Linux, tôi cố gắng viết các tập lệnh của mình sao cho dễ mang theo nhất có thể và để kiểm tra xem những gì tôi đang làm có tương thích với POSIX không.
Phân tích /etc/passwd
Cách tiếp cận đầu tiên tôi đã thử là phân tích /etc/passwd
(sử dụng awk
).
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
Tuy nhiên, vấn đề với cách tiếp cận này là thông tin đăng nhập có thể không cục bộ, ví dụ: xác thực người dùng có thể thông qua NIS hoặc LDAP.
Sử dụng getent
lệnh
Sử dụng getent passwd
dễ mang theo hơn phân tích cú pháp /etc/passwd
vì điều này cũng truy vấn cơ sở dữ liệu NIS hoặc LDAP không cục bộ.
getent passwd "$uid" | cut -d: -f1
Thật không may, getent
tiện ích dường như không được chỉ định bởi POSIX.
Sử dụng id
lệnh
id
là tiện ích được chuẩn hóa POSIX để nhận dữ liệu về danh tính của người dùng.
Việc triển khai BSD và GNU chấp nhận ID người dùng dưới dạng toán hạng:
Điều này có nghĩa là nó có thể được sử dụng để in tên đăng nhập được liên kết với ID người dùng:
id -nu "$uid"
Tuy nhiên, việc cung cấp ID người dùng làm toán hạng không được chỉ định trong POSIX; nó chỉ mô tả việc sử dụng tên đăng nhập làm toán hạng.
Kết hợp tất cả những điều trên
Tôi đã cân nhắc việc kết hợp ba cách tiếp cận trên vào một cái gì đó như sau:
get_username(){
uid="$1"
# First try using getent
getent passwd "$uid" | cut -d: -f1 ||
# Next try using the UID as an operand to id.
id -nu "$uid" ||
# As a last resort, parse `/etc/passwd`.
awk -v uid="$uid" -F: '$3 == uid {print $1}' /etc/passwd
}
Tuy nhiên, điều này là vụng về, không phù hợp và - quan trọng hơn - không mạnh mẽ; nó thoát với trạng thái khác không nếu ID người dùng không hợp lệ hoặc không tồn tại. Trước khi tôi viết một tập lệnh shell dài hơn và phân tích và phân tích trạng thái thoát của mỗi lệnh gọi, tôi nghĩ tôi sẽ hỏi ở đây:
Có cách nào thanh lịch và di động hơn (tương thích POSIX) để lấy tên đăng nhập được liên kết với ID người dùng không?
getent
hoặc id
sẽ không trả lại bất cứ điều gì qua trận đấu đầu tiên; cách duy nhất để tìm thấy tất cả là liệt kê tất cả người dùng, nếu cơ sở dữ liệu người dùng cho phép điều đó. ( /etc/passwd
Rõ ràng là tìm kiếm các tác phẩm cho người dùng được xác định ở đó.)
/etc/passwd
và /etc/shadow
để kiểm tra kịch bản này và xác minh rằng cả hai id
và getent passwd
hành xử như bạn mô tả. Nếu, ở một giai đoạn nào đó, tôi kết thúc việc sử dụng một hệ thống mà người dùng có nhiều tên, tôi sẽ làm giống như các tiện ích hệ thống này và chỉ đơn giản coi sự xuất hiện đầu tiên là tên chính tắc cho người dùng đó.
setuid(some_id)
và không có yêu cầu nào some_id
có thể là một phần của bất kỳ cơ sở dữ liệu người dùng nào. Với những thứ như không gian tên người dùng trên Linux, điều này có thể trở thành một giả định làm tê liệt cho các tập lệnh của bạn.
getpwuid()
chức năng đắt tiền ls
dùng để dịch UID sang tên đăng nhập. Câu trả lời của Gilles là một cách trực tiếp và hiệu quả hơn để thực hiện điều này.