Ai đặt biến môi trường $ USER và $ USERNAME?


34

Ngoài ra, các biến này có luôn khớp với tên người dùng hiện đang đăng nhập không (chúng có trên hệ thống Debian của tôi) không? Tôi có thể giả sử tính khả dụng của chúng trong các hệ thống Unix (giống như) khác không?

Tôi cũng tò mò tại sao người ta sẽ sử dụng whoamithay vì chỉ đọc bất kỳ biến nào trong số này.


2
Nhìn vào mantrang, whoamibáo cáo tên được liên kết với ID người dùng hiệu quả của bạn. Điều đó có nghĩa là nó sẽ trả về một cái gì đó khác nếu bạn đang sử dụng sudohoặc chạy một tập tin thực thi setuid. Nếu bạn đã sudothiết lập, hãy thử sudo whoamiví dụ.
Joseph R.

4
USERUSERNAMElà các biến môi trường thông thường, có nghĩa là, nếu bạn muốn, bạn có thể đặt chúng thành các giá trị tùy ý. Chỉ cần gõ USER=xyz. Nói cách khác, ngay cả khi các biến đó tồn tại, không có gì đảm bảo rằng giá trị của chúng khớp với tên người dùng hiện đang đăng nhập.
Uwe

@Uwe Bởi guarantee, ý tôi là theo mặc định (nghĩa là người dùng không thay đổi chúng).
tshepang

2
@Tshepang Theo dõi nhận xét đầu tiên của tôi: so sánh kết quả của sudo whoamisudo echo $USER
Joseph R.

2
@JosephR. Đối với sudo echo $USER, vỏ mở rộng $USER, sau đó gọi sudo. Vì vậy, tất nhiên nó không tạo ra cùng một đầu ra như whoami. Giống như sudo whoami, sudo sh -c 'echo $USER'đầu ra (thường) root. Về nhận xét của bạn về việc whoamisử dụng EUID , lưu ý rằng sudo whoamisẽ xuất rootngay cả khi đã whoamisử dụng UID. sudođặt cả EUID và UID cho lệnh mà nó chạy (ngoại trừ trong trường hợp rất bất thường mà bạn định cấu hình rõ ràng để hành xử theo cách khác). So sánh sudo id -uvới sudo id -ru.
Eliah Kagan

Câu trả lời:


29

Đó là đăng nhập .

Trang người dùng đăng nhập Linux (1) cho biết:

Giá trị cho $ HOME , $ USER , $ SHELL , $ PATH , $ LOGNAME$ MAIL được đặt theo các trường thích hợp trong mục nhập mật khẩu.

Trang người dùng đăng nhập FreeBSD (1) cho biết:

Các đăng nhập tiện ích nhập thông tin vào môi trường (xem environ (7) ) xác định thư mục của người dùng gia đình (HOME), lệnh thông dịch viên (SHELL), đường dẫn tìm kiếm (PATH), loại thiết bị đầu cuối (HẠN) và tên người dùng (cả LOGNAME và USER) .

Các trang man NetBSD , OpenBSDOS X nói điều tương tự.

Đây là mã nguồn từ thông tin đăng nhập linux-linux:

setenv("HOME", pwd->pw_dir, 0); /* legal to override */
setenv("USER", pwd->pw_name, 1);
setenv("SHELL", pwd->pw_shell, 1);
/* ... */
setenv("LOGNAME", pwd->pw_name, 1);

Đây là mã nguồn từ thông tin đăng nhập FreeBSD:

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);

2
Trên hộp Fedora 16 của tôi, tôi có cả hai USERUSERNAMEthiết lập và lệnh của bạn chỉ trả về LOGNAME.
Joseph R.

1
@JosephR., Thật không may, tôi không có Fedora trên tay nhưng tôi cũng đã xem các nguồn của FreeBSD, xem
CẬP NHẬT

Nhưng điều này rõ ràng không phải là trường hợp trên Fedora. Tất cả những gì tôi nói là, logindường như không phải là điều duy nhất thiết lập các biến này.
Joseph R.

1
Lưu ý rằng Linux chỉ là một kernel, nó không có loginlệnh. Các hệ điều hành sử dụng Linux làm nhân của họ được tự do sử dụng bất kỳ triển khai nào họ muốn. Chẳng hạn, các hệ thống dựa trên Debian có xu hướng sử dụng một hệ thống từ bóng tối, không sử dụng linux.
Stéphane Chazelas

1
Lưu ý rằng loginthường không được gọi khi đăng nhập qua sshhoặc bởi hầu hết các trình quản lý đăng nhập đồ họa.
Stéphane Chazelas

11

Không có quy tắc. Một số vỏ thích tcshhoặc zshđặt $LOGNAME. zshbộ $USER.

Nó có thể được thiết lập bởi một số điều mà bạn đăng nhập vào như login(như gọi bởi gettykhi đăng nhập trên một thiết bị đầu cuối và đôi khi bởi những thứ khác như in.rlogind), cron, su, sudo, sshd, rshd, cán bộ quản lý đăng nhập đồ họa hoặc có thể không.

Tuy nhiên, nếu có đăng nhập, theo kinh nghiệm của tôi, $USERthường được đặt (nhưng nó có thể không được cập nhật sau khi thay đổi id người dùng (thông qua các lệnh setuid) trong phiên đăng nhập đó. POSIX yêu cầu phải $LOGNAMEđược đặt khi đăng nhập (và cron).

Để có được tên đăng nhập một cách hợp lý, tốt nhất là sử dụng lognamelệnh (nếu không có bất kỳ thông tin đăng nhập nào, nó có thể không trả về gì). Để lấy id người dùng, hãy sử dụng id -u. Để có một tên người dùng tương ứng với id người dùng hiệu quả hiện tại : id -un. Để có được tất cả chúng (hầu hết thời gian, chỉ có một tên người dùng cho mỗi id người dùng, nhưng điều đó không được đảm bảo):

perl -le 'while ($n = getpwent()) {print $n if getpwnam($n) == $>}'

Mặc dù điều đó có thể không hoạt động trên các hệ thống mà cơ sở dữ liệu người dùng không thể được liệt kê (đôi khi xảy ra với cơ sở dữ liệu người dùng được nối mạng).


3

Bạn có thể muốn dựa vào tiêu chuẩn POSIX ở đây, vì đôi khi bạn có thể sẽ quan tâm đến không chỉ người dùng đăng nhập (được quản lý bởi loginchương trình) mà còn cả croncông việc và những thứ tương tự.

Do đó, bạn nên biết rằng POSIX yêu cầu $LOGNAMEnhưng không $USER. Ví dụ, $USERcó thể không được đặt bởi cron, như được chỉ ra trong câu trả lời của Keith Thompson , người cũng tham khảo một số lịch sử về việc điều này liên quan đến lịch sử của System-V vs BSD:

... ít nhất là trên hệ thống của tôi (Ubuntu 14.04), biến môi trường $ USER không được đặt cho các công việc định kỳ. Thay vào đó, bạn có thể sử dụng $ LOGNAME, một phần của môi trường cho các công việc định kỳ.

Theo trang man của môi trường (7) (loại man môi trường để đọc), $ USER được sử dụng bởi các chương trình có nguồn gốc BSD và $ LOGNAME được sử dụng bởi các chương trình có nguồn gốc System-V.


1

Nếu bạn muốn sử dụng các biến môi trường (thay vì whoamihoặc getpwentgetpwnam) và bạn không chắc chắn liệu chúng có luôn được đặt theo cùng một cách trên tất cả các hệ thống * NIX không, thì hãy thử điều này trong bash:

THIS_USER=${USER:-${USERNAME:-${LOGNAME}}}
echo ${THIS_USER}

Nếu nó vẫn trống sau tất cả những điều đó, thì bạn đang ở trên một hệ thống khá bí truyền. ;)

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.