sudo echo Số thứ gì đó >> >> etc / đặc quyềnFile không hoạt động


586

Đây là một câu hỏi khá đơn giản, ít nhất có vẻ như nó phải như vậy, về các quyền sudo trong Linux.

Có rất nhiều lần tôi chỉ muốn thêm một cái gì đó vào /etc/hostshoặc một tệp tương tự nhưng cuối cùng không thể vì cả hai >>>không được phép, ngay cả với root.

Có cách nào đó để thực hiện công việc này mà không cần phải suhoặc sudo suroot?

Câu trả lời:


855

Sử dụng tee --appendhoặc tee -a.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list

Hãy chắc chắn để tránh dấu ngoặc kép bên trong dấu ngoặc kép.

Để tránh in dữ liệu trở lại bàn điều khiển, hãy chuyển hướng đầu ra thành / dev / null.

echo 'deb blah ... blah' | sudo tee -a /etc/apt/sources.list > /dev/null

Hãy nhớ về cờ ( -a/ --append)! Chỉ cần teehoạt động như thế >và sẽ ghi đè lên tập tin của bạn. tee -ahoạt động như >>và sẽ viết ở cuối tập tin.


3
Tôi hoàn toàn thích cái này Nó chỉ đơn giản nhất (và nó đã cho tôi biết về tee, cũng có ích trong các tình huống khác).
Joachim Sauer

5
Tôi đồng ý. Có vẻ gọn gàng hơn là bắt đầu một sh ​​mới, đặc biệt là có khả năng làm mọi việc với môi trường, v.v.
Sam Brightman

39
Một điều quan trọng cần lưu ý: KHÔNG BAO GIỜ quên -a! Chỉ cần tưởng tượng những gì echo 'tmpfs /tmp tmpfs defaults 0 0' | sudo tee /etc/fstabsẽ làm
mic_e

21
Trong OS X, điều này nên tee -athay vì tee --append.
knite 17/2/2015

26
Đối với những người không hiểu những gì @mic_e đã nói: không có-a--append cờ ( ) , lệnh sẽ ghi đè lên toàn bộ tệp bằng chuỗi đã cho thay vì nối thêm vào cuối.
totymedli

314

Vấn đề là shell không chuyển hướng đầu ra, không phải sudo hoặc echo, vì vậy điều này đang được thực hiện như người dùng thông thường của bạn.

Hãy thử đoạn mã sau:

sudo sh -c "echo 'something' >> /etc/privilegedfile"

"Ranh giới cho phép sudo" là gì? Nó chỉ là cái vỏ phân tích toán tử chuyển hướng với độ ưu tiên cao hơn một lệnh vì những lý do rõ ràng
Vinko Vrsalovic

1
Tùy thuộc vào bạn sh, echo có thể diễn giải các chuỗi thoát như \tbên trong các trích dẫn đơn. Bạn có thể sử dụng printf %s 'something'thay thế.
Lri

Sử dụng tee là phổ biến hơn và tương thích hơn với các bản phát hành mới hơn.
Eduardo B.

1
Đây là cái duy nhất hoạt động tương tự như một lệnh SSH có thể được thực thi trên một nút từ xa.
Khóa Duncan

Tôi đồng ý với các bài viết khác ở đây. Cái này sử dụng shell và shell duy nhất nên một chương trình khác như tee không bắt buộc ở đây. Có, tôi biết tee đã được cài đặt, nhưng có thể không phụ thuộc vào phân phối vi mô nào bạn đang sử dụng như xương trần. Tôi thích rằng bạn cũng có một tùy chọn shell: sudo /bin/bash -c "echo 'fs.inotify.max_user_watches = 524288' > /etc/sysctl.d/60-golang-inotify.conf"ví dụ.
Ligemer

35

Vấn đề là vỏ của bạn xử lý chuyển hướng; nó đang cố mở tệp bằng các quyền của bạn chứ không phải các quy trình bạn đang chạy theo sudo.

Sử dụng một cái gì đó như thế này, có lẽ:

sudo sh -c "echo 'something' >> /etc/privilegedFile"

@GordonSun điều này là do sudo(vì lý do bảo mật) không truyền bá môi trường đến quy trình con. Bạn có thể sử dụng sudo -Eđể bỏ qua hạn chế này.
arielf

1
@GordonSun đúng vậy, tôi không hiểu tại sao bạn cứ lặp đi lặp lại câu nói này! Nếu bạn làm như vậy sudo sh -c "echo 'something' >> $FILENAME", với dấu ngoặc kép, điều này sẽ hoạt động - việc thay thế biến được thực hiện bởi lớp vỏ bên ngoài, chứ không phải lớp vỏ sudoed.
Nadav Har'El


13

Đang làm

sudo sh -c "echo >> somefile"

nên làm việc. Vấn đề là> và >> được xử lý bởi trình bao của bạn chứ không phải bởi lệnh "sudoed", vì vậy các quyền là của bạn chứ không phải của người dùng mà bạn đang "sudoing".


9

Tôi xin lưu ý, đối với những người tò mò, bạn cũng có thể trích dẫn một di sản (cho các khối lớn):

sudo bash -c "cat <<EOIPFW >> /etc/ipfw.conf
<?xml version=\"1.0\" encoding=\"UTF-8\"?>

<plist version=\"1.0\">
  <dict>
    <key>Label</key>
    <string>com.company.ipfw</string>
    <key>Program</key>
    <string>/sbin/ipfw</string>
    <key>ProgramArguments</key>
    <array>
      <string>/sbin/ipfw</string>
      <string>-q</string>
      <string>/etc/ipfw.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true></true>
  </dict>
</plist>
EOIPFW"

1
Điều này hoạt động rất tốt, ngoại trừ các trích dẫn được nhúng có thể cần phải được thoát bằng \
N Jones

Hoàn toàn đúng @NJones! Tôi sẽ chỉnh sửa câu trả lời của tôi. (Tuy nhiên, lưu ý rằng việc không thực hiện việc này sẽ loại bỏ nội bộ "nhưng không khiến lệnh bị lỗi.)
msanford

8

Trong bash, bạn có thể sử dụng teekết hợp với > /dev/nullđể giữ cho thiết bị xuất chuẩn.

 echo "# comment" |  sudo tee -a /etc/hosts > /dev/null

4

Sử dụng câu trả lời của Yoo , đặt câu hỏi này vào ~/.bashrc:

sudoe() {
    [[ "$#" -ne 2 ]] && echo "Usage: sudoe <text> <file>" && return 1
    echo "$1" | sudo tee --append "$2" > /dev/null
}

Bây giờ bạn có thể chạy sudoe 'deb blah # blah' /etc/apt/sources.list


Biên tập:

Một phiên bản hoàn chỉnh hơn cho phép bạn chuyển đầu vào hoặc chuyển hướng từ một tệp và bao gồm một -acông tắc để tắt phụ lục (được bật theo mặc định):

sudoe() {
  if ([[ "$1" == "-a" ]] || [[ "$1" == "--no-append" ]]); then
    shift &>/dev/null || local failed=1
  else
    local append="--append"
  fi

  while [[ $failed -ne 1 ]]; do
    if [[ -t 0 ]]; then
      text="$1"; shift &>/dev/null || break
    else
      text="$(cat <&0)"
    fi

    [[ -z "$1" ]] && break
    echo "$text" | sudo tee $append "$1" >/dev/null; return $?
  done

  echo "Usage: $0 [-a|--no-append] [text] <file>"; return 1
}

2

Bạn cũng có thể sử dụng spongetừ moreutilsgói và không cần chuyển hướng đầu ra (nghĩa là không có teetiếng ồn để ẩn):

echo 'Add this line' | sudo sponge -a privfile

0

Bằng cách sử dụng sed -i với $ a , bạn có thể nối thêm văn bản, chứa cả biến và ký tự đặc biệt, sau dòng cuối cùng.

Ví dụ: thêm $ NEW_HOST với $ NEW_IP vào / etc / hosts:

sudo sed -i "\$ a $NEW_IP\t\t$NEW_HOST.domain.local\t$NEW_HOST" /etc/hosts

tùy chọn sed giải thích:

  • -i cho tại chỗ
  • $ cho dòng cuối cùng
  • một để chắp thêm


0

Làm thế nào về:
văn bản echo | sudo dd status = none of = đặc quyền
tôi muốn thay đổi / Proc / sys / net / ipv4 / tcp_rmem.
Tôi đã làm:
sudo dd status = none of = / Proc / sys / net / ipv4 / tcp_rmem <<< "4096 131072 1024000"
loại bỏ tiếng vang với một tài liệu dòng đơn


1
Xin vui lòng dành một chút thời gian để đọc qua trợ giúp chỉnh sửa trong trung tâm trợ giúp . Định dạng trên Stack Overflow khác với các trang web khác.
Dharman

-1

Điều này làm việc cho tôi: lệnh ban đầu

echo "export CATALINA_HOME="/opt/tomcat9"" >> /etc/environment

Lệnh làm việc

echo "export CATALINA_HOME="/opt/tomcat9"" |sudo tee /etc/environment

1
Nên tee -a. Chỉ cần teeghi đè lên tập tin!
codeforester

-6

Bạn có thể thay đổi quyền sở hữu của tập tin sau đó thay đổi lại sau khi sử dụng cat >>để chắp thêm không?

sudo chown youruser /etc/hosts  
sudo cat /downloaded/hostsadditions >> /etc/hosts  
sudo chown root /etc/hosts  

Một cái gì đó như thế này làm việc cho bạn?


4
Chown là một lệnh phá hoại để sử dụng. Nếu trình quản lý cấu hình đã sử dụng để cập nhật / etc / hosts, đột nhiên / etc / hosts thuộc về người dùng cấu hình và không phải root. có khả năng dẫn đến các quá trình khác không có quyền truy cập vào / etc / hosts. Toàn bộ quan điểm của sudo là để tránh có một cái gì đó được đăng nhập vào root và thông qua sudoers, nhiều hạn chế cũng có thể được chồng chất.
David
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.