72

Tôi đang cố gắng tự động hóa việc bổ sung nguồn lưu trữ trong tệp pacman.conf của vòm nhưng sử dụng echolệnh trong tập lệnh shell của tôi. Tuy nhiên, nó thất bại như thế này: -

sudo echo "[archlinuxfr]" >> /etc/pacman.conf
sudo echo "Server = http://repo.archlinux.fr/\$arch" >> /etc/pacman.conf
sudo echo " " >> /etc/pacman.conf

-bash: /etc/pacman.conf: Permission denied

Nếu tôi thực hiện thay đổi đối với /etc/pacman.conf bằng cách sử dụng vim, bằng cách thực hiện

sudo vim /etc/pacman.conf

và thoát vim với :wq, mọi thứ đều hoạt động tốt và pacman.conf của tôi đã được cập nhật thủ công mà không có khiếu nại "Quyền bị từ chối".

Tại sao cái này rất? Và làm thế nào để tôi đi sudo echolàm? (btw, tôi cũng đã thử sử dụng sudo catnhưng điều đó cũng thất bại với Quyền bị từ chối)

|
42

Vấn đề là chuyển hướng đang được xử lý bởi vỏ ban đầu của bạn chứ không phải bởi sudo. Vỏ sò không có khả năng đọc được suy nghĩ và không biết rằng cụ thể đó >>là dành cho sudovà không dành cho nó.

Bạn cần phải:

  1. trích dẫn chuyển hướng (vì vậy nó được chuyển qua sudo)
  2. sử dụng sudo -s(để sudosử dụng trình bao để xử lý chuyển hướng được trích dẫn.)
|
  • 1

    Vì vậy, thực hiện theo hai bước như thế này (1) sudo -s(2) echo "# test" >> /etc/pacman.conf hoạt động. Nhưng nó có thể thực hiện điều này trong một dòng duy nhất không?

    – Tạ Thiên Kim 04:10:11 13/04/2012
  • 1

    sudo -s 'echo "# test" >>/etc/pacman.conf'là những gì tôi đã cố gắng truyền đạt cho bạn.

    – Tạ Vũ Uy 04:13:57 13/04/2012
  • 1

    Trên thực tế, tôi đã thử điều đó sau khi đọc câu trả lời của bạn ở trên nhưng gặp một lỗi kỳ lạ như thế này: - sudo -s 'echo "# test" >> /etc/pacman.conf' /bin/bash: echo "# test" >> /etc/pacman.conf: No such file or directoryđó là lý do tại sao sau đó tôi đã thử quy trình thủ công 2 bước.

    – Tạ Ngọc Hạnh 04:18:19 13/04/2012
  • 1

    À ..... một nỗ lực cuối cùng theo cách này đã có hiệu quả -echo 'echo "# test" >> /etc/pacman.conf' | sudo -s

    – Ngô Huy Thông 04:20:25 13/04/2012
  • 1

    Làm thế nào / nơi tôi tìm hiểu về sudoviệc vô hiệu hóa cấu hình -s? thị giác?

    – Trịnh Bảo Quốc 04:35:57 13/04/2012
110

Như @geekizard đã giải thích, shell thực hiện chuyển hướng trước khi chạy lệnh. Khi bạn gõ này:

sudo foo >/some/file

Quá trình shell hiện tại của bạn tạo một bản sao của chính nó trước tiên cố mở /some/fileđể ghi, sau đó làm cho mô tả tệp đó thành đầu ra tiêu chuẩn của nó, và chỉ sau đó thực thi sudo.

Nếu bạn được phép (cấu hình sudoer thường loại trừ các shell đang chạy), bạn có thể làm một cái gì đó như thế này:

sudo bash -c 'foo >/some/file'

Nhưng tôi tìm thấy một giải pháp tốt nói chung là sử dụng | sudo teethay vì >| sudo tee -athay vì >>. Điều đó đặc biệt hữu ích nếu chuyển hướng là lý do duy nhất tôi cần sudoở nơi đầu tiên; Rốt cuộc, không cần thiết phải chạy các tiến trình như root chính xác là những gì sudođã được tạo để tránh. Và chạy echonhư root chỉ là ngớ ngẩn.

echo '[archlinuxfr]' | sudo tee -a /etc/pacman.conf >/dev/null
echo 'Server = http://repo.archlinux.fr/$arch' | sudo tee -a /etc/pacman.conf >/dev/null
echo ' ' | sudo tee -a /etc/pacman.conf >/dev/null

Tôi đã thêm > /dev/nullvào cuối bởi vì teegửi đầu ra của nó cho cả tệp được đặt tên đầu ra tiêu chuẩn của chính nó và tôi không cần phải xem nó trên thiết bị đầu cuối của mình. ( teeLệnh này hoạt động như một đầu nối "T" trong một đường ống vật lý, là nơi nó có tên của nó.) Và tôi đã chuyển sang các dấu ngoặc đơn ( '... ') thay vì nhân đôi ( "... ") để mọi thứ đều theo nghĩa đen và tôi không cần phải đặt một dấu chéo ngược ở phía trước của $trong $arch.

Vì vậy, nó quan tâm đến việc ghi vào các tập tin như root bằng cách sử dụng sudo. Bây giờ cho một bản phân tích dài về các cách để xuất văn bản chứa dòng mới trong tập lệnh shell. :)

Đầu tiên, bạn chỉ có thể nhóm tất cả các nhóm echolại với nhau trong một khung con, vì vậy bạn chỉ phải thực hiện chuyển hướng một lần:

(echo '[archlinuxfr]
 echo 'Server = http://repo.archlinux.fr/$arch'
 echo ' ') | sudo tee -a /etc/pacman.conf >/dev/null

Hoặc sử dụng printfthay vì echo, vì vậy bạn có thể nhúng dòng mới trực tiếp vào chuỗi bằng cách sử dụng \n:

printf '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

Trong bash, bạn có thể nhận được kết quả tương tự với echo -e:

# BASH ONLY - NOT RECOMMENDED
echo -e '[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

Nhưng hầu hết các shell sẽ chỉ xuất ra -ekhi bạn thử điều đó, vì vậy nó không được khuyến khích.

Với cả hai printfecho -e, những gì lệnh nhận được dưới dạng chuỗi đối số chứa dấu gạch chéo ngược theo sau bằng chữ N ở bất cứ nơi nào bạn nhập \nvà tùy thuộc vào chương trình lệnh (mã bên trong printfhoặc echo) để dịch nó thành dòng mới. Trong nhiều shell hiện đại, bạn có tùy chọn sử dụng dấu ngoặc kép ANSI $'... ', nó sẽ dịch các chuỗi như \nthành dòng mới bằng chữ trước khi chương trình lệnh bao giờ nhìn thấy chuỗi, có nghĩa là các chuỗi như vậy hoạt động với bất kỳ lệnh nào:

echo $'[archlinuxfr]\nServer = http://repo.archlinux.fr/$arch\n ' | 
  sudo tee -a /etc/pacman.conf >/dev/null

Nhưng, trong khi có tính di động cao hơn echo -e, các trích dẫn ANSI vẫn là một phần mở rộng không phải POSIX.

Cách ưa thích của tôi để làm điều này sẽ là sử dụng tài liệu ở đây và tránh sự cần thiết echohoặc printfhoàn toàn:

sudo tee -a /etc/pacman.conf >/dev/null <<'EOF'
[archlinuxfr]
Server = http://repo.archlinux.fr/$arch

EOF
|
16

http://www.innovationsts.com/blog/?p=2758

Vì hướng dẫn không rõ ràng ở trên nên tôi đang sử dụng các hướng dẫn từ bài đăng trên blog đó. Với các ví dụ để dễ dàng hơn để xem những gì bạn cần làm.

$ sudo mèo /root/example.txt | gzip> /root/example.gz
-bash: /root/example.gz: Quyền bị từ chối

Lưu ý rằng đó là lệnh thứ hai (lệnh gzip) trong đường ống gây ra lỗi. Đó là nơi kỹ thuật sử dụng bash của chúng tôi với tùy chọn -c xuất hiện.

$ sudo bash -c 'cat /root/example.txt | gzip> /root/example.gz '
$ sudo ls /root/example.gz
/root/example.gz

Chúng ta có thể thấy mẫu đầu ra của lệnh ls mà việc tạo tệp nén đã thành công.

Phương thức thứ hai tương tự như phương pháp thứ nhất là chúng ta chuyển một chuỗi lệnh để bash, nhưng chúng ta đang thực hiện nó trong một đường ống thông qua sudo.

$ sudo rm /root/example.gz
$ echo "cat /root/example.txt | gzip> /root/example.gz" | sudo bash
$ sudo ls /root/example.gz
/root/example.gz

|
  • 1

    Cảm ơn! Ví dụ của bạn đã giúp!

    – Tạ Thiên Kim 05:20:59 02/07/2012
  • 1

    Đối với một lệnh đơn giản như vậy, có thể tốt hơn một chút để sử dụng sh thay vì bash. Ví dụ: sudo sh -c 'cat /root/example.txt | gzip> /root/example.gz '. Nhưng nếu không, giải thích tốt, +1.

    – Tạ Vũ Uy 20:24:59 03/08/2012
5
sudo bash -c 'echo "[archlinuxfr]" >> /etc/pacman.conf'
|
1

BƯỚC 1 tạo một hàm trong tệp bash ( write_pacman.sh)

#!/bin/bash

function write_pacman {
 tee -a /etc/pacman.conf > /dev/null << 'EOF'
  [archlinuxfr]
  Server = http://repo.archlinux.fr/\$arch
EOF
}

'EOF'sẽ không giải thích $archbiến.

Tập tin bash nguồn STE2

$ source write_pacman.sh

BƯỚC 3 thực hiện chức năng

$ write_pacman
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.