Chỉ chạy các phần của tập lệnh dưới dạng sudo, chỉ nhập mật khẩu một lần


14

Tôi đang viết một tập lệnh (thực ra là sự kết hợp giữa tập lệnh và tập tin thực hiện) để cài đặt các phụ thuộc bên ngoài: một số apt-getlệnh, một số gitnhân bản, xây dựng, cài đặt, thêm người dùng vào nhóm, ...

Một số thao tác trong các tập lệnh này yêu cầu quyền siêu người dùng, một số thì không.

Cho đến bây giờ tôi đã chạy toàn bộ quá trình tạo với sudo, nhưng nó có một số nhược điểm:

  • gitrepos tôi nhân bản rootlà chủ sở hữu, có nghĩa là tôi không thể sửa đổi chúng sau đó mà không có sudohoặcchown
  • các tập lệnh thêm người dùng vào các nhóm không biết nên thêm người dùng nào kể từ khi whoamitrả vềroot

Cách tốt nhất để chạy như siêu người dùng chỉ các lệnh yêu cầu nó là gì? Lý tưởng nhất là quá trình vẫn sẽ yêu cầu tôi nhập sudomật khẩu của mình , nhưng chỉ một lần khi bắt đầu quá trình cài đặt. Sau đó, nó sẽ quên nó vào cuối, nhưng giữ nó mọi lúc cho đến khi đó (có thể mất vài giờ).

Các giải pháp tôi đã tìm thấy trực tuyến bao gồm:

  • sudo -vtại nhận thức của kịch bản, nhưng nếu tôi hiểu chính xác thì lần này ra. Kịch bản của tôi có thể chạy trong một vài giờ
  • chạy tập lệnh với sudo, nhưng các lệnh không cần siêu người dùng sudo -u $(logname) <command>. Đây là những gì tôi làm bây giờ, nhưng cảm giác như nó phải là cách khác.

Lý tưởng nhất, tôi muốn kịch bản của tôi:

  1. yêu cầu thông tin đăng nhập
  2. chạy các lệnh bình thường khi người dùng đăng nhập
  3. chạy các lệnh sudo với thông tin đăng nhập ở bước 1
  4. sudo -k để đóng phiên siêu người dùng

2
Bạn vẫn có thể chạy mọi thứ dưới dạng sudo và tập lệnh của bạn có thể kiểm tra SUDO_USERbiến môi trường. Nếu có, nó sẽ chứa tên người dùng của người dùng gọi sudo. Vì vậy, bạn có thể (với quyền root) chown $ SUDO_USER: $ SUDO_GID $ your_files. Tương tự, bạn có thể kiểm tra các biến này để các lệnh adduser của bạn biết người dùng nào cần thêm.
roadmr

... Hoặc chạy mọi thứ như root và sử dụng su $SUDO_USER -c commandcho các lệnh chạy như người dùng bình thường.
Rmano

Câu trả lời:


7

Vì bạn có quyền truy cập sudo, hãy tạo một tệp sudoers cho chính mình, sau đó xóa nó khi tập lệnh được hoàn thành:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k

2

Một cách nào, rằng tôi sẽ không thường khuyên, là để đọc mật khẩu cho mình, và sử dụng sudo's -Stùy chọn để vượt qua mật khẩu và khi cần thiết:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

Từ man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.

1
Có an toàn không? echo "$password"??
αғsнιη

@KasiyA echo "$password"sẽ không như vậy, nhưng heredocs và herestrings an toàn hơn một chút. Chúng không hiển thị trên dòng lệnh được hiển thị bởi các công cụ thông thường.
muru

1
Tôi nghĩ, nói đúng ra, echo "$password"ở phía bên trái của một đường ống an toàn trong một kịch bản bash. echolà một vỏ dựng sẵn; /bin/echokhông chạy khi nó được gọi là đơn giản echo .... Một số shell khác có echodựng sẵn ( dashví dụ), nhưng shell theo kiểu Bourne không bắt buộc phải có. Vì vậy, tôi nghĩ echo "$password" |là có thể chấp nhận được trong bash nhưng tốt nhất có thể tránh trong trường hợp ai đó chuyển tập lệnh sang shell khác mà không nhận thấy vấn đề. Tôi sử dụng một thiết bị không di động [[thay vì [trong tập lệnh đó để tránh vấn đề tương tự. @KasiyA
Eliah Kagan
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.