Lệnh su: khác nhau giữa su và su -, sudo su và sudo -i, và cách chuyển tài khoản
Khi muốn chuyển sang tài khoản khác để chạy lệnh trên Linux mà không đăng xuất tài khoản hiện tại, bạn dùng lệnh su. Khi chạy su từ tài khoản root của server AlmaLinux 9 sang daemon, một tài khoản hệ thống không thể đăng nhập, chỉ một dấu gạch ngang đã làm thư mục làm việc và PATH thay đổi, và phải chỉ định shell thì lệnh mới chạy.
Kết quả bên dưới được chạy trên server AlmaLinux 9.8 (tài khoản root) và server Debian 12 (tài khoản thường). Màn hình hỏi mật khẩu và sudo không chạy trên server đang vận hành mà được tóm tắt theo tài liệu hướng dẫn chính thức, và một phần giá trị PATH cùng số phiên bản bản vá util-linux trong trình mô phỏng đã được đổi thành giá trị ví dụ.
1️⃣ Cách dùng lệnh su
Dạng cơ bản là [su tên_tài_khoản], và nếu bỏ tên tài khoản, su sẽ chuyển sang root. Khi bạn gõ exit trong shell mới, shell đó kết thúc và bạn quay lại shell của tài khoản ban đầu đã chạy su.
Khi chạy từ tài khoản thường, bạn nhập mật khẩu của tài khoản đích ở dòng Password: (theo cài đặt mặc định của PAM). Trên server này, /etc/pam.d/su được đặt để bỏ qua xác thực khi người chạy là root, nên khi chuyển từ tài khoản root sang daemon thì không bị hỏi mật khẩu.
su --help
Usage:
su [options] [-] [<user> [<argument>...]]
Change the effective user ID and group ID to that of <user>.
A mere - implies -l. If <user> is not given, root is assumed.
Options:
-m, -p, --preserve-environment do not reset environment variables
-w, --whitelist-environment <list> don't reset specified variables
-g, --group <group> specify the primary group
-G, --supp-group <group> specify a supplemental group
-, -l, --login make the shell a login shell
-c, --command <command> pass a single command to the shell with -c
--session-command <command> pass a single command to the shell with -c
and do not create a new session
-f, --fast pass -f to the shell (for csh or tcsh)
-s, --shell <shell> run <shell> if /etc/shells allows it
-P, --pty create a new pseudo-terminal
-h, --help display this help
-V, --version display version
For more details see su(1).Như phần trợ giúp ghi, dấu gạch ngang [-] là tùy chọn đăng nhập giống [-l], và các đối số viết sau tên tài khoản được chuyển cho shell của tài khoản đích. Trên server AlmaLinux 9, su nằm trong gói util-linux 2.37, còn trên server Debian 12 nằm trong gói 2.38.
su --versionsu from util-linux 2.38.1Muốn biết tài khoản định chuyển sang có mở được shell hay không, hãy xem cột cuối của dòng tài khoản đó trong getent passwd.
getent passwd daemondaemon:x:2:2:daemon:/sbin:/sbin/nologinShell của daemon là /sbin/nologin. Tài khoản có nologin thay cho shell đăng nhập sẽ không mở shell dù đã chuyển sang bằng su.
2️⃣ Khác nhau giữa su và su -
Khi thêm dấu gạch ngang (-), su mở shell giống như khi đăng nhập bằng tài khoản đích. Trong thư mục /tmp, cùng một lệnh được chạy một lần không có dấu gạch ngang và một lần có dấu gạch ngang.
su -s /bin/sh -c pwd daemon/tmpsu - -s /bin/sh -c pwd daemon/usr/sbinKhông có dấu gạch ngang, thư mục làm việc vẫn là /tmp, còn [su -] chuyển sang thư mục home của daemon là /sbin. Trên server này /sbin là liên kết tới /usr/sbin, nên pwd hiện /usr/sbin.
Với biến môi trường, chỉ năm dòng trong kết quả env được chọn để so sánh: HOME, USER, SHELL, PATH và LOGNAME.
su -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binsu - -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbinHOME, USER và LOGNAME đều đổi sang giá trị của daemon trong cả hai trường hợp. Khi không có dấu gạch ngang, PATH vẫn giữ giá trị của root, tài khoản đã chạy su, còn với [su -] thì PATH được đặt lại theo cài đặt đăng nhập.
Theo tài liệu hướng dẫn chính thức, su không có dấu gạch ngang chỉ đổi HOME và SHELL, và chỉ đổi thêm USER và LOGNAME khi tài khoản đích không phải root. Vì vậy, nếu chuyển từ tài khoản thường sang root mà không có dấu gạch ngang, USER vẫn giữ tên tài khoản ban đầu.
[$0], biến in ra tên shell, cũng khác nhau.
su -s /bin/sh -c 'echo $0' daemonshsu - -s /bin/sh -c 'echo $0' daemon-shVới [su -], tên shell có thêm dấu gạch ngang ở đầu và hiện -sh. Shell có tên bắt đầu bằng dấu gạch ngang sẽ chạy như shell đăng nhập và đọc các tệp cấu hình đăng nhập (theo tài liệu hướng dẫn chính thức). Khác biệt của hai dạng như bên dưới.
| So sánh | su | su - |
|---|---|---|
| Thư mục làm việc | Giữ nguyên (/tmp) | Thư mục home của tài khoản đích (/usr/sbin) |
| HOME, USER, LOGNAME | Giá trị của daemon | Giá trị của daemon |
| PATH | Giá trị của root, tài khoản đã chạy su | Đặt lại theo cài đặt đăng nhập |
| Tên shell ($0) | sh | -sh (shell đăng nhập) |
| Các biến môi trường khác | Giữ nguyên | Xóa, chỉ giữ lại vài biến như TERM (theo tài liệu hướng dẫn chính thức) |
Tài liệu hướng dẫn chính thức khuyên luôn thêm tùy chọn đăng nhập để môi trường không bị lẫn, và viết [--login] thay cho dấu gạch ngang. su không có dấu gạch ngang giữ lại thư mục hiện tại và PATH, nên khi muốn kiểm tra lệnh với cài đặt của tài khoản khác, kết quả có thể khác với [su -].
3️⃣ Tùy chọn su -c và su -s
Khi muốn chạy chỉ một lệnh bằng tài khoản khác mà không mở shell, hãy viết lệnh sau -c. Khi chạy id bằng [su -c] trên tài khoản nologin, kết quả hiện ra là thông báo từ chối thay vì kết quả của lệnh.
su -c id daemonThis account is currently not available.Lệnh truyền bằng -c cũng do shell của tài khoản nhận và chạy, nên nếu shell là nologin thì lệnh không bao giờ được chạy tới. Khi đó, hãy chỉ định shell cần chạy bằng -s.
su -s /bin/sh -c id daemonuid=2(daemon) gid=2(daemon) groups=2(daemon)Khi chỉ định /bin/sh, id chạy với UID 2 của daemon. Bạn dùng dạng này khi muốn kiểm tra quyền tệp hoặc kết quả lệnh bằng tài khoản dịch vụ.
Nếu shell của tài khoản đích là shell bị giới hạn không có trong /etc/shells, như nologin, thì chỉ root mới đổi được shell bằng -s. Theo tài liệu hướng dẫn chính thức, khi đó -s và biến SHELL do người dùng không phải root chỉ định sẽ bị bỏ qua.
Nếu lệnh sau -c có khoảng trắng, hãy đặt trong dấu nháy để truyền thành một khối. su trả về nguyên mã thoát của lệnh đã chạy, trả về 126 nếu không chạy được lệnh và 127 nếu không tìm thấy lệnh (theo tài liệu hướng dẫn chính thức).
📌 Tùy chọn chính: kết quả chạy trong bài này
| Tùy chọn | Chức năng | Kết quả trong bài này | |
|---|---|---|---|
| - | Mở shell giống như khi đăng nhập bằng tài khoản đích và chuyển tới thư mục home của tài khoản đó | Từ /tmp, không có dấu gạch ngang thì pwd là /tmp, có thì là /usr/sbin, và echo $0 cho -sh | |
| -c lệnh | Chạy một lệnh bằng shell của tài khoản đích mà không mở shell | Chạy su -c id daemon trên tài khoản nologin daemon thì ra [This account is currently not available.] | |
| -s shell | Chạy bằng shell được chỉ định thay cho shell ghi trong tài khoản; tài khoản có shell bị giới hạn thì chỉ root | su -s /bin/sh -c id daemon cho uid=2(daemon) gid=2(daemon) groups=2(daemon) | |
| --help | In cách dùng và danh sách tùy chọn | Dòng Usage và danh sách tùy chọn -m, -w, -g, -G, -l, -c, -f, -s, -P, -h, -V | |
| --version | In thông tin phiên bản | su from util-linux 2.38.1 trên server Debian 12 |
📎 Tùy chọn khác: theo tài liệu hướng dẫn chính thức
| Tùy chọn | Chức năng | |
|---|---|---|
| -l | Tùy chọn đăng nhập giống dấu gạch ngang (-); tên dài là --login | |
| -m | Giữ nguyên biến môi trường và không đổi HOME, SHELL, USER, LOGNAME; bị bỏ qua khi dùng cùng tùy chọn đăng nhập (giống -p) | |
| -w danh sách | Giữ lại các biến viết cách nhau bằng dấu phẩy khi tùy chọn đăng nhập xóa môi trường; HOME, SHELL, USER, LOGNAME và PATH được đặt lại | |
| -g nhóm | Chỉ định nhóm chính; chỉ root | |
| -G nhóm | Chỉ định nhóm phụ; chỉ root; nếu không có -g thì nhóm phụ đầu tiên thành nhóm chính | |
| -f | Truyền -f cho shell; tùy chọn dùng trong csh và tcsh | |
| -P | Tạo terminal giả mới để không dùng chung terminal với phiên ban đầu | |
| --session-command lệnh | Giống -c nhưng không tạo phiên mới; tài liệu hướng dẫn không khuyên dùng |
🔲 Trình mô phỏng lệnh su
Trình mô phỏng bên dưới bắt đầu từ tài khoản thường user1, và bạn có thể tự gõ su, [su -], sudo rồi quay lại bằng exit. Tài khoản và mật khẩu là giá trị ví dụ.
4️⃣ Khác nhau giữa sudo su và sudo -i
sudo su là cách dùng sudo để chạy su bằng quyền root. Vì root là người chạy su nên không hỏi mật khẩu root, và trước đó sudo hỏi mật khẩu của người chạy lệnh (theo tài liệu chính thức).
Những tài khoản được phép chạy sudo được quy định trong cấu hình /etc/sudoers. Nếu một tài khoản không được phép chạy sudo, tài khoản đó bị từ chối với [user1 is not in the sudoers file.] (theo thông báo trong chương trình).
Mật khẩu được hỏi và thư mục làm việc của từng lệnh mở shell root như bên dưới. Các lệnh trong phần này không chạy trên server đang vận hành mà được tóm tắt theo tài liệu hướng dẫn su(1) và sudo(8).
| Lệnh | Mật khẩu được hỏi | Shell được chạy | Thư mục làm việc |
|---|---|---|---|
| su | root | Shell root | Giữ nguyên |
| su - | root | Shell đăng nhập root | /root |
| sudo su | Tài khoản đã chạy lệnh | Shell root | Giữ nguyên |
| sudo su - | Tài khoản đã chạy lệnh | Shell đăng nhập root | /root |
| sudo -i | Tài khoản đã chạy lệnh | Shell đăng nhập root | /root |
| sudo -s | Tài khoản đã chạy lệnh | Shell trong biến SHELL (quyền root) | Giữ nguyên |
[sudo -i] và [sudo su -] đều kết thúc ở shell đăng nhập root. Với [sudo -i], sudo chạy thẳng shell của root dưới dạng shell đăng nhập, còn [sudo su -] đi qua su thêm một lần ở giữa.
[sudo -s] chạy shell trong biến SHELL bằng quyền root và không chuyển tới thư mục home. Khi đã nhập đúng mật khẩu một lần, sudo mặc định không hỏi lại trong cùng terminal trong 5 phút (theo tài liệu hướng dẫn sudoers).
Khác biệt giữa su và sudo giống như khác biệt giữa mượn chìa khóa nhà và ghi tên ở phòng bảo vệ để ra vào.
5️⃣ Lỗi lệnh su
Nếu chuyển sang tài khoản không thể đăng nhập, nologin sẽ chạy thay cho shell và hiện [This account is currently not available.]. Khi chạy [su daemon] từ root, chỉ hiện một dòng này và mã thoát là 1.
su daemonThis account is currently not available.Thông báo này do chương trình nologin ghi ở cột cuối của dòng tài khoản in ra, và cùng nội dung đó đã được tìm thấy trong /usr/sbin/nologin trên server. Nếu là root, bạn có thể chỉ định shell bằng -s và chạy lệnh bằng tài khoản đó.
Nếu mật khẩu sai, sẽ hiện [su: Authentication failure]. Dòng chữ này là thông báo mà thư viện PAM trả về khi xác thực thất bại. Theo tài liệu hướng dẫn chính thức, nếu su thất bại trước khi chạy lệnh thì mã thoát là 1.
Nếu đã nhập đúng mật khẩu tài khoản của mình mà su vẫn từ chối, trước hết hãy kiểm tra xem chỗ đó có phải cần nhập mật khẩu của tài khoản đích hay không. sudo hỏi mật khẩu của người chạy lệnh, còn su hỏi mật khẩu của tài khoản sẽ chuyển sang.
Nếu viết tên tài khoản không tồn tại, sẽ hiện [su: user user9 does not exist or the user entry does not contain all the required fields] (theo thông báo trong chương trình). Nguyên nhân và điều cần kiểm tra cho từng lỗi như bên dưới.
| Đầu ra | Nguyên nhân | Điều cần kiểm tra |
|---|---|---|
| This account is currently not available. | Shell của tài khoản đích là nologin | Cột cuối của dòng tài khoản trong getent passwd; nếu là root, chỉ định shell bằng -s |
| su: Authentication failure | Mật khẩu không đúng | Có phải mật khẩu của tài khoản đích không (sudo hỏi mật khẩu của bạn) |
| su: user user9 does not exist … | Không có tài khoản tên đó | getent passwd tên_tài_khoản |
| user1 is not in the sudoers file. | Tài khoản không được phép dùng sudo | Cấu hình sudoers và nhóm wheel |
🔢 FAQ & nội dung đề xuất
Phân quyền · sở hữu
Quyền Linux (4,2,1) và quyền sở hữu | lệnh chmod, chown, umask
Bài viết về cách xem và thay đổi quyền đọc, ghi, thực thi và chủ sở hữu của tệp và thư mục.
Người dùng và truy cập
Lệnh Linux who, w & lệnh user
Các lệnh xem người dùng đang đăng nhập vào server lúc này và công việc họ đang chạy.
Mạng và truy cập
Lệnh SSH: tùy chọn và cách dùng
Bài viết về dạng cơ bản và tùy chọn của lệnh ssh, lệnh kết nối tới server từ xa bằng tài khoản người dùng.
ℹ️ Thông báo tiếp thị liên kết
Nội dung trên trang này có chứa liên kết affiliate (tiếp thị liên kết). Khi khách truy cập mua sản phẩm hoặc dịch vụ qua các liên kết này, trang sẽ nhận hoa hồng từ bên bán. Trong quá trình đó, số tiền người mua phải trả (sẽ giảm khi có chương trình khuyến mãi ↓) không hề tăng lên. Giá, khuyến mãi và tình trạng hàng được đăng theo thời điểm viết bài và có thể khác với thực tế, vì vậy hãy kiểm tra lại lần cuối với bên bán trước khi mua. Việc chọn và đánh giá sản phẩm dựa trên tiêu chí riêng của trang; việc có nhận hoa hồng hay không không ảnh hưởng đến thứ tự giới thiệu hay nội dung đánh giá.