sudo trong kịch bản không tương tác


9

Tôi có một kịch bản thực thi ba chức năng : A && B && C.

Chức năng Bcần phải được chạy như một siêu người dùng, trong khi ACkhông.

Tôi có một số giải pháp nhưng cả hai đều không thỏa mãn:

  1. sudo toàn bộ kịch bản: sudo 'A && B && C'

    Đó có vẻ là một ý tưởng tồi để chạy AClà siêu người dùng nếu không cần thiết

  2. làm cho kịch bản tương tác: A && sudo B && C

    Tôi có thể phải nhập mật khẩu của mình, nhưng tôi muốn tập lệnh của mình không tương tác, vì mỗi chức năng có thể mất một chút thời gian và tôi không muốn tập lệnh chờ tôi. Chà, đó cũng là lý do tại sao nó là một kịch bản ở nơi đầu tiên, vì vậy tôi không phải xem nó chạy.

  3. Giải pháp ngu ngốc: sudo : && A && sudo -n B && C

    Đầu tiên có vẻ ngu ngốc khi chạy no-op sudotrước, và tôi cũng phải vượt qua ngón tay của mình rằng A sẽ không mất nhiều hơn $sudo_timeout.

  4. Giải pháp giả thuyết (tôi muốn bạn nói với tôi rằng nó tồn tại):

    sudo --store-cred 'A && sudo --use-cred-from-parent-sudo B && C'

    Điều đó sẽ nhắc mật khẩu của tôi ngay từ đầu, và sau đó chỉ sử dụng thông tin đăng nhập đó khi cần.

Ý kiến ​​của bạn về tất cả điều này là gì? Tôi rất ngạc nhiên rằng không có giải pháp cho vấn đề đó, vì tôi nghĩ đó là một vấn đề khá phổ biến (còn về make all && sudo make install)


3
Bạn có thể tạo một tập lệnh mà bạn thực thi bằng sudo, nhưng trong tập lệnh thực thi ACcác phần rõ ràng bằng cách sử dụng su -l some_non_priviliged_user. Không có vấn đề thời gian chờ, và không có quyền riêng tư cho A và C. Tôi không nghĩ rằng 4 là có thể, sudodường như là "trạng thái toàn cầu" cho người dùng.
Anthon

Câu trả lời:


7

Tôi nghĩ rằng điều tốt nhất mà bạn có thể làm là khởi chạy tập lệnh sudovà sau đó khởi chạy các quy trình bạn muốn chạy như một người dùng bình thường rõ ràng với su userhoặc sudo -u user:

#!/usr/bin/env bash

## Detect the user who launched the script
usr=$(env | grep SUDO_USER | cut -d= -f 2)

## Exit if the script was not launched by root or through sudo
if [ -z $usr ] && [ $USER = "root" ]
then
    echo "The script needs to run as root" && exit 1
fi

## Run the job(s) that don't need root
sudo -u $usr commandA

## Run the job that needs to be run as root
commandB

9

Thêm tập lệnh của bạn vào /etc/sudoerstệp với NOPASSWDthuộc tính, để nó được phép chạy mà không cần nhắc mật khẩu. Bạn có thể liên kết điều này với một người dùng cụ thể (hoặc nhóm người dùng) hoặc cho phép nó được chạy sudobởi bất kỳ ai trong hệ thống của bạn.

Một dòng mẫu cho một tập lệnh được gọi /usr/local/bin/bossycó thể trông giống như thế này

ALL ALL = (root) NOPASSWD: /usr/local/bin/bossy

Và sau đó bạn sẽ sử dụng một cái gì đó như thế này

A && sudo bossy && C

Ví dụ này tôi giả sử PATHbao gồm /usr/local/bin. Nếu không, thì chỉ cần sử dụng đường dẫn đầy đủ đến tập lệnh, nghĩa làsudo /usr/local/bin/bossy


Upvote cho cách tiếp cận an toàn nhất.
Eyoung100

0

Bạn có thể muốn sử dụng !requirettytùy chọn sudocũng như NOPASSWDtùy chọn. Nhưng hãy nhớ điều này làm giảm an ninh.


1
Khi vấn đề được định nghĩa là không muốn kịch bản có tính tương tác, # 2 với /etc/sudoersmục nhập cho người sử dụng để thực hiện lệnh Bvới NOPASSWDlà câu trả lời đúng.
Andrew

Đó là "bạn có thể làm X hoặc Y", đó là "bạn có thể làm X và Y". Chỉ có cả hai sẽ giải quyết vấn đề. Có lẽ tôi nên từ lại câu trả lời của tôi.
Steve Wills

0

Dựa trên câu trả lời của tôi để ủy quyền trước sudo? (Vì vậy, nó có thể được chạy sau) , viết hai tập lệnh:

  • ABC_script:

    #!/bin/sh
    sudo -b ./B_script
    A  &&  > A_is_done
    while [ ! -f B_is_done ]
    do
            sleep 60
    done
    rm -f B_is_done
    C
  • B_script:

    #!/bin/sh
    while [ ! -f A_is_done ]
    do
            sleep 60
    done
    rm -f A_is_done
    B  &&  > B_is_done

Chạy ./ABC_script:

  • Nó sẽ chạy sudo -b ./B_script. Điều này yêu cầu mật khẩu ( ngay sau khi bạn chạy ABC_script). Giả sử rằng mật khẩu chính xác được nhập, nó sẽ sinh ra B_scripttrong ackground b (vì -bđã được chỉ định) là root. Điều này dường như tương đương với sudo sh -c "./B_script &".
  • B_scriptbắt đầu chạy không đồng bộ, song song với ABC_scriptB_scriptkiểm tra sự tồn tại của một tệp được gọi A_is_done và các vòng lặp cho đến khi nó xuất hiện.
  • Song song, ABC_scriptchạy A. Nếu / khi Akết thúc thành công, tập lệnh sẽ tạo một tệp có tên A_is_done.
  • ABC_scriptsau đó kiểm tra sự tồn tại của một tệp được gọi B_is_done và các vòng lặp cho đến khi nó xuất hiện.
  • Song song, B_scriptphát hiện sự tồn tại A_is_donevà thoát ra khỏi vòng lặp. Nó xóa A_is_donetập tin và chạy B. Hãy nhớ rằng, B_scriptđang chạy như root, vì vậy nó chạy Bnhư root. Nếu / khi Bkết thúc thành công, tập lệnh sẽ tạo một tệp được gọi B_is_donevà thoát.
  • Song song, ABC_scriptphát hiện sự tồn tại B_is_donevà thoát ra khỏi vòng lặp. Nó xóa B_is_donetập tin. Hãy nhớ rằng, B_scriptchạy dưới quyền root, do đó B_is_doneđược sở hữu bởi root và bạn muốn sử dụng rm -fđể tránh nhận được yêu cầu xác nhận. ABC_scriptsau đó chạy Cvà thoát.

Ghi chú cho sàng lọc thêm:

  • ABC_scriptCó lẽ nên chạy B_scripttheo một con đường tuyệt đối chứ không phải ./.
  • Thay vì A_is_doneB_is_done, ABC_scriptcó lẽ nên tạo tên tệp ngẫu nhiên, duy nhất.
  • Cần phải có một điều khoản cho kịch bản đang chờ đợi để được thông báo nếu chương trình mà nó đang chờ đã kết thúc nhưng không thành công. (Ngay bây giờ, nếu Athất bại, cả hai tập lệnh chỉ đi vào một vòng chờ vô hạn.) Điều này có thể đơn giản như thay đổi

    A  &&  > A_is_done

    đến

    A; echo $? > A_is_done

    và sau đó sửa đổi spin-waits để đọc các X_is_donetệp và tiến hành nếu nó chứa 0 và thoát khác.


-3

Hãy câm đi. sử dụng nhiều dòng.

if A; then

    if sudo B ; then
        C
    fi
fi

Làm thế nào là giải quyết bất kỳ mối quan tâm của tôi? Vấn đề không liên quan gì&&
Antoine Pelisse

&& dừng thực thi khi lệnh đầu tiên thất bại. Các câu lệnh if làm điều này rõ ràng hơn. Quan điểm của tôi là hoàn thành công việc của bạn, ngay cả khi nó không đẹp.
Robert Jacobs

1
Đây không gì khác hơn là một phiên bản dài hơn của tùy chọn 2 : A && sudo B && C. Giống như Antoine giải thích trong câu hỏi; Điều này không yêu cầu mật khẩu cho đến khi Akết thúc và anh ta không muốn phải chờ điều đó, hoặc có kịch bản chờ anh ta.
Scott
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.