Làm cách nào để chạy lệnh 'sudo' trong tập lệnh?


84

Để thực hiện một bản vá thủ công, tôi phải gõ lệnh này

sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  

Có một không gian ngay trước ngày 09:

sudo ./playback_delete_data_patch.sh [space] 09_delete_old_data_p.sql

Làm thế nào tôi có thể chạy này trong một kịch bản?

Ngoài ra còn có một số lệnh khác nhưng lệnh này đang gây rắc rối.


2
Chỉ cần đặt nó trong kịch bản, vấn đề là gì?
Lie Ryan

6
@LieRyan - sudo mật khẩu - tập lệnh sẽ không thể chạy hoàn toàn nếu ai đó không ở đó để nhập nó.
Wilf

Hệ thống của tôi chỉ chạy chúng tốt mà không cần nhắc. Ubuntu 16.04 vào tháng 10 năm 2017. Bạn đã làm hỏng sudoersthiết lập của mình . Không vấn đề gì. Nó chỉ cần cố định.
SDsolar

1
@SDsolar Hệ thống của bạn là hệ thống bị rối tung; đó là một lỗ hổng bảo mật nhỏ để không nhắc mật khẩu (khiến người dùng dễ bị tổn thương hơn đối với một số loại tấn công kỹ thuật xã hội).
wizzwizz4

Câu trả lời:


107

Nó hiếm khi là một ý tưởng tốt để có sudotrong các kịch bản. Thay vào đó, hãy xóa đoạn mã sudokhỏi tập lệnh và tự chạy tập lệnh với sudo:

sudo myscript.sh

Bằng cách đó, tất cả các lệnh trong tập lệnh sẽ được chạy với quyền root và bạn chỉ cần cung cấp mật khẩu một lần khi khởi chạy tập lệnh. Nếu bạn cần một lệnh cụ thể trong tập lệnh để chạy mà không có sudođặc quyền, bạn có thể chạy nó như một người dùng thông thường với (cảm ơn Lie Ryan ):

sudo -u username command 

Không gian là không liên quan, nó không ảnh hưởng đến bất cứ điều gì, luôn có một khoảng trống giữa một lệnh và các đối số của nó.


30
có thể có các lệnh trong tập lệnh không cần đặc quyền gốc, bạn có thể tạm thời bỏ đặc quyền gốc cho các lệnh đó bằng cách sử dụng tên người dùng sudo -u
Lie Ryan

48
Rất nhiều tập lệnh tôi viết làm cả đống tương tác người dùng và / hoặc kiểm tra lỗi. Sau đó, một lệnh ở cuối - một cái gì đó như rsync - cần phải được chạy dưới quyền root. Tại sao tôi muốn làm cho toàn bộ hoạt động được nâng lên và để mình mở cho nhiều dòng mã có thể chứa lỗi nghiêm trọng hoặc lỗ hổng với quyền truy cập root - đặc biệt là trong khi gỡ lỗi - khi chỉ một hoặc một vài lệnh yêu cầu quyền truy cập đó?
Joe

2
@Joe đủ công bằng. Thay đổi "không bao giờ là một ý tưởng tốt" thành "hiếm khi".
terdon

10
@Joe có một điểm thực sự tốt ở đây. Ngoài ra, khi người ta nói không làm điều đó , thật tuyệt khi biết chính xác lý do tại sao, hoặc ít nhất, trong bối cảnh nào tôi không nên làm điều đó, và tại sao
arainone

10
@terdon Bạn không nghe. Tôi biết rằng nếu bạn chạy tập lệnh với quyền root thì nó sẽ không bao giờ nhắc bạn về sudo. Tôi đang so sánh rằng không chạy tập lệnh dưới dạng root và thay vào đó là thực hiện sudocác cuộc gọi rõ ràng trong tập lệnh, bởi vì nâng toàn bộ tập lệnh lên root có thể là một ý tưởng tồi tệ nếu chỉ có một số hành động hẹp cần root. Trong bối cảnh đó, tôi đã trả lời cụ thể cho nhận xét của bạn: "Phần lớn là vì điều này có nghĩa là bạn không thể chạy tập lệnh tự động vì bạn sẽ cần nhập mật khẩu mỗi khi bạn được hỏi."
BeeOnRope

41

Bạn có thể sửa đổi sudoerstập tin

Chạy đi sudo visudo.

Thêm một mục nhập cho tên người dùng của bạn và tập lệnh mà bạn muốn chạy mà không được yêu cầu nhập mật khẩu.

username ALL=(ALL) NOPASSWD: /path/to/script

2
Không làm việc cho tôi, nhưng cảm ơn, thật tốt khi biết điều này tồn tại. Có lẽ tôi đã sai cú pháp.
Chris K

5
Không chắc ai đã đề cập đến nó, nhưng bạn phải chấm dứt tất cả các phiên đăng nhập của người dùng đó sau khi bạn đã chỉnh sửa sudoerstệp.
thoát-llc

1
Chỉ cần làm rõ ở đây, đó không phải là tập lệnh chứa dòng "sudo ./playback_delete_data_patch.sh 09_delete_old_data_p.sql" mà nên được chỉ định trong tệp sudoers mà là tập lệnh phát lại của họ hoặc bất kỳ lệnh nào mà bạn muốn tập lệnh để có thể chạy qua sudo mà không cần chỉ định mật khẩu.
MttJocy

19

Bạn có thể thử một cái gì đó như:

echo "PASSWORD" | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Đây không phải là điều an toàn nhất để làm vì bạn đang viết mật khẩu sudoer bằng văn bản thuần túy. Để làm cho nó an toàn hơn một chút, bạn có thể tạo một biến và đọc mật khẩu sudo vào biến đó và sau đó bạn có thể thực thi lệnh như:

echo $PASSWORD | sudo -S ./playback_delete_data_patch.sh 09_delete_old_data_p.sql

Ngoài ra, nếu bạn không bận tâm tất cả các lệnh của bạn đang được thực thi với quyền root, bạn có thể đơn giản thực thi tập lệnh của mình bằng cách sử dụng sudo, như đã đề xuất trước đó.

sudo ./myscript

Đọc mật khẩu vào biến an toàn:read -s PASSWORD
Tobias Uhmann

10

Câu trả lời này tương tự như câu trả lời của terdon . Tôi cũng đề nghị chạy tập lệnh chính sudođể tập lệnh có thể chạy mà không phải hỏi mật khẩu người dùng trong quá trình thực thi.

Tuy nhiên, trong trường hợp bạn muốn thả đặc quyền gốc vào một số lệnh và chạy chúng với tư cách là người dùng thực tế đã gọi lệnh với sudo, bạn có thể kiểm tra $SUDO_USERbiến để tìm ra người dùng ban đầu.

Đây là một kịch bản ví dụ về cách bạn có thể đạt được điều đó:

#!/bin/bash

# ref: https://askubuntu.com/a/30157/8698
if ! [ $(id -u) = 0 ]; then
   echo "The script need to be run as root." >&2
   exit 1
fi

if [ $SUDO_USER ]; then
    real_user=$SUDO_USER
else
    real_user=$(whoami)
fi

# Commands that you don't want running as root would be invoked
# with: sudo -u $real_user
# So they will be run as the user who invoked the sudo command
# Keep in mind if the user is using a root shell (they're logged in as root),
# then $real_user is actually root
# sudo -u $real_user non-root-command

# Commands that need to be ran with root would be invoked without sudo
# root-command

4

Thực sự có một cách đơn giản hơn nhiều để làm điều này. Đối với tính di động, đây là triển khai của tôi nhưng hãy thoải mái thao tác nó cho phù hợp với nhu cầu của bạn.

Nhập mật khẩu sudo của bạn làm tham số khi bắt đầu tập lệnh, ghi lại và lặp lại với mỗi lệnh sẽ nhắc mật khẩu sudo.

#!/bin/bash

PW=$1
echo $PW | ./playback_delete_data_patch.sh 09_delete_old_data_p.sql  
./command_wo_sudo.sh <param>
echo $PW | ./other_command_requires_sudo.sh <param>

Bạn có thể thêm một dấu nhắc và chụp sau khi tập lệnh được khởi động như vậy:

echo "enter the sudo password, please"
read PW

Nhưng nếu ai đó theo dõi những gì chạy trên nút; có quyền truy cập vào các bản ghi được tạo bởi nó; hoặc chỉ nhìn qua một cách ngẫu nhiên khi bạn chạy thử nghiệm, điều đó có thể ảnh hưởng đến bảo mật.

Điều này cũng hoạt động với các lệnh / tập lệnh đang chạy yêu cầu có để tiếp tục:

echo $PW | yes | ./install.sh

Tiếng vang là để đáp lại lời nhắc, vì vậy bạn có thể sử dụng bất cứ thứ gì bạn cần, ở đó, nếu bạn đang chạy các tập lệnh khác có lời nhắc tiến trình, theo thứ tự liên tục. Hãy chắc chắn rằng bạn biết rằng thứ tự, mặc dù, hoặc những điều xấu có thể xảy ra.


Điều đó thanh lịch và đơn giản hơn nhiều, tôi rất vui vì tôi đã cuộn xuống! EDIT: chờ đã, điều này sẽ thêm mật khẩu vào lịch sử thiết bị đầu cuối của tôi
Công việc

1
Cách hỏi tên người dùng / mật khẩu với read: ryanstutorials.net/bash-scripting-tutorial/bash-input.php Điều đó nên tránh vấn đề này
Công việc

3
#!/bin/bash
# this declares that current user is a sudoer
sudo tee /etc/sudoers.d/$USER <<END
END

# write the content of your script here
sudo npm install hexo-cli -g
mkdir Untitled
sudo apt-get install python

# then to remove the sudo access from the current user
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k

0

Bạn có thể thử thêm người dùng chạy tập lệnh vào tệp sudoers:

#give permissions to the file
sudo chmod 700 /etc/sudoers.d/useradm

sudo visudo /etc/sudoers.d/useradm

#add the following text, changing "user" but your desired user
user ALL=(ALL)NOPASSWD:ALL

#return the right permissions to the file
sudo chmod 440 /etc/sudoers.d/useradm

Nói chung đây là một phương pháp kém. Nếu bạn định thêm quy tắc sudo NOPASSWD, đặc biệt là đối với các tài khoản chạy tự động hóa, tối thiểu bạn nên hạn chế chúng theo lệnh chính xác được chạy (chứ không phải TẤT CẢ)
Christopher Hunter
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.