Làm thế nào để giải quyết quyền của từ chối từ chối khi sử dụng sudo với chuyển hướng trong Bash?


138

Khi sử dụng sudo để cho phép chỉnh sửa tệp, tôi thường xuyên nhận được 'quyền bị từ chối'.

Ví dụ, con chuột của tôi rất bồn chồn và chậm chạp, vì vậy tôi muốn tắt bỏ phiếu:

sudo echo "options drm_kms_helper poll=N">/etc/modprobe.d/local.conf

Tôi được nhắc nhập mật khẩu và sau đó nhận:

bash: /etc/modprobe.d/local.conf: Permission denied

Vì vậy, tôi đã cố gắng thực hiện một thay đổi tạm thời để vô hiệu hóa bỏ phiếu bằng cách sử dụng:

sudo echo N> /sys/module/drm_kms_helper/parameters/poll

Một lần nữa hệ thống trả lời:

bash: /sys/module/drm_kms_helper/parameters/poll: Permission denied

Có ý kiến ​​gì không?

Câu trả lời:


157

Chuyển hướng đầu ra (thông qua >toán tử) được thực hiện bằng shell chứ không phải bằng echo . Bạn phải đăng nhập bằng root

sudo -i

Sau đó, bạn có thể sử dụng chuyển hướng

echo N> /sys/module/drm_kms_helper/parameters/poll

Nếu không, bạn có thể chạy chuỗi bash với sudo

sudo bash -c "echo N> /sys/module/drm_kms_helper/parameters/poll"

1
Bạn không thể chạy echo với sudo? những gì về kết quả tôi nhận được:saji@laptop:~$ sudo echo "Hi" [sudo] password for saji: Hi
saji89

bạn có thể viết vào tập tin, lặp lại "cái gì đó"> cách nào đó. Đó là sử dụng đường ống .. Đó là vấn đề.
shantanu

4
Ok, nếu đó là trường hợp, thì xin vui lòng cập nhật câu trả lời của bạn để phản ánh rằng việc chạy echo chỉ là vấn đề trong trường hợp đó.
saji89

Bạn không thể đơn giản chạy shell dựng sẵn echonhư sudo, trừ khi bạn làm một cái gì đó như sudo bash -c 'echo …'; tuy nhiên, các hệ thống POSIX thường cung cấp một echolệnh bên ngoài như /bin/echotrên OS X, sudo có thể thực thi mà không cần Rigamarole. Do đó, echolệnh bạn thường chạy và echolệnh bạn chạy với sudo có thể là hai lệnh khác nhau, nhưng tương tự nhau.
kojiro

Nếu đó là trường hợp, tại sao câu trả lời cho câu hỏi này gợi ý tiếng vang? Askubfox.com/questions/840431/ Mạnh
Harsha

75

Việc chuyển hướng đầu ra được thực hiện bởi trình bao mà lệnh đã được gọi . Vì vậy, chia mọi thứ thành bit, đây là những gì đang xảy ra *:

  • shell invokes sudo echo "options drm_kms_helper poll=N", thực thi sudolệnh với echo "options drm_kms_helper poll=N"dòng lệnh

  • sudo yêu cầu nhập mật khẩu, mở shell superuser và gọi echo "options drm_kms_helper poll=N", chạy echolệnh truyền nó"options drm_kms_helper poll=N"

  • echo, chạy với rootđặc quyền, in chuỗi thành đầu ra tiêu chuẩn của nó.

  • echolệnh chấm dứt, thoát superuser shell, sudochấm dứt

  • shell mà lệnh đã được gọi sẽ thu thập đầu ra và cố gắng chuyển hướng nó tới /etc/modprobe.d/local.conf, chỉ có thể ghi được bằng root. Nó bị lỗi "cho phép từ chối".

Để biết cách khắc phục, hãy xem @shantanu trả lời.


(*) - trong khi trình tự nêu trên giúp chúng ta hiểu tại sao lệnh thất bại, trong thực tế sự việc xảy ra hơi out-of-trật tự: vỏ gốc thông báo chuyển hướng và cố gắng để mở tập tin cho văn bản trước khi viện dẫn sudo ...lệnh. Khi mở tệp không thành công, shell thậm chí không gọi lệnh được cho là ghi vào tệp (cảm ơn @PanosRontogianni vì đã chỉ ra điều này).

Đây là một bài kiểm tra nhanh:

$ touch ./onlyroot.txt
$ sudo chown root:root ./onlyroot.txt
$ sudo bash -c "whoami | tee who.txt" > onlyroot.txt
bash: onlyroot.txt: Permission denied

Trong thử nghiệm ở trên, chúng whoami | tee who.txtta sẽ tạo một tệp có tên who.txtchứa từ "root". Tuy nhiên, khi chuyển hướng đầu ra không thành công trong vỏ gọi, tệp "who.txt" cũng bị thiếu do lệnh không được gọi.


Nhiều khả năng shell 'forks' và cố gắng mở /etc/modprobe.d/local.conf trước khi thử 'exec' sudo, có nghĩa là 4 bước đầu tiên mà mô tả của bạn không bao giờ thực sự xảy ra vì tệp không thể mở được.
Panos Rontogianni

1
@PanosRontogianni: cảm ơn, tôi đã cập nhật câu trả lời
Sergey

60

Thêm vào câu trả lời của Chaianu:

... Hoặc bạn có thể sử dụng một teelệnh như thế này:

sudo tee /sys/module/drm_kms_helper/parameters/poll <<<10

hoặc nếu đầu ra của lệnh:

echo 10 | sudo tee /sys/module/drm_kms_helper/parameters/poll

3
Đăng nhập +1 với quyền root là một ý tưởng tồi cho công việc thủ công và một ý tưởng thực sự tồi cho các tác vụ theo kịch bản.
l0b0

2
Ngoài ra, sudo tee /sys/module/drm_kms_helper/parameters/poll > /dev/nullnếu bạn không muốn nó cũng in stdout.
Fabian Tamp

16

Một cách tiếp cận tôi chưa từng thấy được đề cập ở đây là chỉ cần thực hiện toàn bộ dòng lệnh trong lớp vỏ của chính nó. Bản sudothân trang này đưa ra một ví dụ về phương pháp này:

Để tạo một danh sách sử dụng các thư mục trong phân vùng / home. Lưu ý rằng điều này chạy các lệnh trong một vỏ con để làm cho chuyển hướng cd và tập tin hoạt động.

$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE"

Ồ cảm ơn nhé. một giải pháp đơn giản
Khả năng phục hồi

4

Một lựa chọn khác là sử dụng một tập tin tạm thời. Điều này rất hữu ích trong một tập lệnh bash.

temp=$(mktemp)
echo "Hello, world!" > $temp
sudo cp $temp /etc/wherever

3

sudo dd of=

Để thêm như bạn muốn:

echo inbytes | sudo dd of=outfile oflag=append conv=notrunc

hoặc để tạo lại tập tin từ đầu:

echo inbytes | sudo dd of=outfile

Ưu điểm:

  • đẹp hơn teetừ khi không /dev/nullchuyển hướng
  • đẹp hơn shvì không có subshell rõ ràng (nhưng một ẩn cho chuyển hướng)
  • ddcó nhiều tùy chọn mạnh mẽ, ví dụ status=progressđể xem tiến trình chuyển

Hoạt động vì sudo chuyển stdin cho lệnh.


1
Điều này là tốt Chúng tôi nghĩ về ddcách chúng tôi ghi đè lên các hệ thống tệp tuyệt vời của chúng tôi và không nhận ra rằng đó cũng là các nhiệm vụ trần tục - và các lệnh khác với quyền root cũng gây ra tác hại lớn nếu sử dụng trên các tệp / thiết bị sai. Giống nhưsudo tee , sudo ddtất nhiên cũng sẽ làm việc với các chuỗi ở đây , ví dụ , sudo dd of=outfile <<<'hello world'. [Cảm ơn đã chỉnh sửa. NB với sh -c 'cmd', shlà một quy trình con là một lớp vỏ, nhưng không thực sự là một lớp con ngoại trừ theo nghĩa tất cả các lệnh bên ngoài bắt đầu là một.]
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.