2009-02-19 61 views
33

Vì vậy, tôi đang cố gắng để có được một quy trình được chạy như một người dùng siêu từ bên trong một tập lệnh python bằng cách sử dụng tiến trình con. Trong một cái gì đó ipython vỏ nhưchạy lệnh với tư cách người dùng siêu từ tập lệnh python

proc = subprocess.Popen('sudo apach2ctl restart', 
         shell=True, stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 

hoạt động tốt, nhưng ngay sau khi tôi dính nó vào một kịch bản tôi bắt đầu nhận được: sudo: apach2ctl: command not found.

Tôi đoán điều này là do cách sudo xử lý môi trường trên ubuntu. (Tôi cũng đã thử sudo -E apche2ctl restartsudo env path=$PATH apache2ctl restart không có kết quả)

Vì vậy, câu hỏi của tôi về cơ bản là nếu tôi muốn chạy apache2ctl restart làm người dùng siêu nhắc người dùng nhập mật khẩu người dùng khi cần thiết, tôi nên làm như thế nào điều này? Tôi không có ý định lưu trữ mật khẩu trong tập lệnh.

Chỉnh sửa:

Tôi đã thử chuyển các lệnh dưới dạng cả chuỗi và được mã hóa vào danh sách. Trong trình thông dịch python, với một chuỗi tôi sẽ nhận được lời nhắc mật khẩu đúng (vẫn không hoạt động trong một kịch bản python như trong vấn đề ban đầu của tôi), một danh sách chỉ cung cấp cho màn hình trợ giúp cho sudo.

Chỉnh sửa 2:

Vì vậy, những gì tôi thu thập là trong khi Popen sẽ làm việc với một số lệnh giống như chuỗi khi shell = Đúng, phải mất

proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart']) 

không có 'shell = True' để có được sudo làm việc.

Cảm ơn!

+2

Cách định cấu hình sudo để người dùng này chỉ có thể chạy lệnh này mà không yêu cầu mật khẩu? –

+0

Bạn có thể muốn sử dụng ['proc.wait()'] (https://docs.python.org/2/library/subprocess.html#subprocess.Popen.wait) tùy thuộc vào những gì bạn đang làm; 'wait' không tiến hành cho đến khi tiến trình con chạy xong. – craymichael

Trả lời

14

Thử cung cấp đường dẫn đầy đủ tới apache2ctl.

+0

Tôi nghĩ bạn đã đánh vào nó. Chạy một tập lệnh từ trình thông dịch kế thừa $ PATH từ trình bao tương tác đang chạy nó. Tuy nhiên, khi chạy dưới dạng tập lệnh, $ PATH được kế thừa từ một trình vỏ không tương tác và có thể không giống nhau. Tốt nhất là luôn luôn chỉ định đường dẫn đầy đủ khi sử dụng popen(). –

+0

Vâng - bất cứ khi nào bạn tham khảo các tập tin nhị phân từ tập lệnh, bạn không thể dựa vào $ PATH ở đó cho bạn. Nhân tiện, "apch2ctl" bị viết sai chính tả. ;) – ojrac

3

Bạn phải sử dụng Popen như thế này:

cmd = ['sudo', 'apache2ctl', 'restart'] 
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

Nó hy vọng một danh sách.

+7

Đọc http://docs.python.org/library/subprocess.html Có một sự khác biệt giữa một chuỗi và trình tự args khi shell = True. – jfs

+0

Tôi hiểu rồi, tôi chưa bao giờ sử dụng nó như thế trước đây. –

+1

Không đặt shell = True khi bạn đang chuyển danh sách vào đó. –

21

Hãy thử:

subprocess.call(['sudo', 'apach2ctl', 'restart'])

Các tiến trình con cần phải truy cập vào stdin thực ra/vào/err cho nó để có thể nhắc bạn, và đọc bằng mật khẩu của bạn. Nếu bạn đặt chúng thành đường ống, bạn cần phải tự nhập mật khẩu vào ống đó.

Nếu bạn không xác định chúng, sau đó nó lấy sys.stdout, vv ...

7

Một cách khác là làm cho người dùng của bạn một mật khẩu ít sudo user.

Loại sau đây trên dòng lệnh:

sudo visudo 

Sau đó, thêm dòng sau và thay thế <username> với bạn:

<username> ALL=(ALL) NOPASSWD: ALL 

Điều này sẽ cho phép người dùng thực hiện sudo lệnh mà không cần phải yêu cầu mật khẩu (bao gồm cả ứng dụng được đưa ra bởi người dùng đã nói.Đây có thể là rủi ro bảo mật mặc dù

Các vấn đề liên quan