it-swarm-vi.tech

Làm cách nào để sử dụng Sudo để chuyển hướng đầu ra đến một vị trí mà tôi không được phép ghi vào?

Tôi đã được cấp quyền truy cập Sudo trên một trong các hộp linux RedHat phát triển của chúng tôi và dường như tôi thấy mình thường xuyên cần chuyển hướng đầu ra đến một vị trí mà tôi thường không có quyền truy cập ghi.

Vấn đề là, ví dụ giả định này không hoạt động:

Sudo ls -hal /root/ > /root/test.out

Tôi chỉ nhận được phản hồi:

-bash: /root/test.out: Permission denied

Làm thế nào tôi có thể làm điều này để làm việc?

760
Jonathan

Lệnh của bạn không hoạt động vì chuyển hướng được thực hiện bởi Shell của bạn không có quyền ghi vào /root/test.out. Chuyển hướng của đầu ra không phải là được thực hiện bởi Sudo.

Có nhiều giải pháp:

  • Chạy Shell với Sudo và ra lệnh cho nó bằng cách sử dụng tùy chọn -c:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Tạo tập lệnh với các lệnh của bạn và chạy tập lệnh đó bằng Sudo:

    #!/bin/sh
    ls -hal /root/ > /root/test.out
    

    Chạy Sudo ls.sh. Xem câu trả lời của Steve Bennett nếu bạn không muốn tạo một tệp tạm thời.

  • Khởi chạy Shell với Sudo -s sau đó chạy các lệnh của bạn:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Sử dụng Sudo tee (nếu bạn phải thoát rất nhiều khi sử dụng tùy chọn -c):

    Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null
    

    Cần chuyển hướng đến /dev/null để dừng tee từ đầu ra màn hình. Để chắp thêm thay vì ghi đè tệp đầu ra (>>), sử dụng tee -a hoặc tee --append (tệp cuối cùng dành riêng cho GNU coreutils ).

Cảm ơn đi đến Jd , Adam J. ForsterJohnathan cho các giải pháp thứ hai, thứ ba và thứ tư.

1068
Cristian Ciupitu

Ai đó ở đây vừa đề nghị sudoing tee:

Sudo ls -hal /root/ | Sudo tee /root/test.out > /dev/null

Điều này cũng có thể được sử dụng để chuyển hướng bất kỳ lệnh nào, đến một thư mục mà bạn không có quyền truy cập. Nó hoạt động vì chương trình tee thực sự là một chương trình "echo to a file" và việc chuyển hướng đến/dev/null là dừng nó cũng xuất ra màn hình để giữ cho nó giống như ví dụ ban đầu ở trên.

89
Jonathan

Một mẹo tôi tự tìm ra là

Sudo ls -hal /root/ | Sudo dd of=/root/test.out
70
rhlee

Vấn đề là lệnh được chạy trong Sudo, nhưng chuyển hướng được chạy dưới người dùng của bạn. Điều này được thực hiện bởi Shell và có rất ít bạn có thể làm về nó.

Sudo command > /some/file.log
`-----v-----'`-------v-------'
   command       redirection

Những cách thông thường để bỏ qua điều này là:

  • Gói các lệnh trong một tập lệnh mà bạn gọi trong Sudo.

    Nếu các lệnh và/hoặc tệp nhật ký thay đổi, bạn có thể tạo tập lệnh Lấy chúng làm đối số. Ví dụ:

    Sudo log_script command /log/file.txt
    
  • Gọi Shell và truyền dòng lệnh dưới dạng tham số với -c

    Điều này đặc biệt hữu ích cho một lệnh ghép . Ví dụ:

    Sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    
41
dsm

Một biến thể khác về chủ đề:

Sudo bash <<EOF
ls -hal /root/ > /root/test.out
EOF

Hoặc tất nhiên:

echo 'ls -hal /root/ > /root/test.out' | Sudo bash

Chúng có lợi thế (nhỏ) mà bạn không cần phải nhớ bất kỳ đối số nào đối với Sudo hoặc sh/bash

19
Steve Bennett

Làm rõ một chút về lý do tại sao tùy chọn tee thích hợp hơn

Giả sử bạn có quyền thích hợp để thực thi lệnh tạo đầu ra, nếu bạn chuyển đầu ra của lệnh sang tee, bạn chỉ cần nâng cao quyền riêng tư của tee với Sudo và tee trực tiếp để ghi (hoặc nối thêm) vào tệp đang đề cập.

trong ví dụ được đưa ra trong câu hỏi có nghĩa là:

ls -hal /root/ | Sudo tee /root/test.out

cho một vài ví dụ thực tế hơn:

# kill off one source of annoying advertisements
echo 127.0.0.1 ad.doubleclick.net | Sudo tee -a /etc/hosts

# configure eth4 to come up on boot, set IP and netmask (centos 6.4)
echo -e "ONBOOT=\"YES\"\nIPADDR=10.42.84.168\nPREFIX=24" | Sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth4

Trong mỗi ví dụ này, bạn đang lấy đầu ra của một lệnh không có đặc quyền và ghi vào một tệp thường chỉ có thể ghi được bằng root, đó là Nguồn gốc của câu hỏi của bạn.

Đó là một ý tưởng tốt để làm theo cách này bởi vì lệnh tạo đầu ra không được thực thi với các đặc quyền nâng cao. Điều này dường như không quan trọng ở đây với echo nhưng khi lệnh nguồn là tập lệnh mà bạn không hoàn toàn tin tưởng, thì điều đó rất quan trọng.

Lưu ý rằng bạn có thể sử dụng tùy chọn -a để phát bóng để chắp thêm (như >>) vào tệp mục tiêu thay vì ghi đè lên nó (như >).

18
jg3

Làm cho Sudo chạy Shell, như thế này:

Sudo sh -c "echo foo > ~root/out"
15
Penfold

Cách tôi sẽ đi về vấn đề này là:

Nếu bạn cần ghi/thay thế tệp:

echo "some text" | Sudo tee /path/to/file

Nếu bạn cần thêm vào tập tin:

echo "some text" | Sudo tee -a /path/to/file
8
Nikola Petkanski

Làm thế nào về việc viết một kịch bản?

Tên tệp: myscript

#!/bin/sh

/bin/ls -lah /root > /root/test.out

# end script

Sau đó sử dụng Sudo để chạy tập lệnh:

Sudo ./myscript
5
Jd

Tôi sẽ làm theo cách này:

Sudo su -c 'ls -hal /root/ > /root/test.out'
4
fardjad

Bất cứ khi nào tôi phải làm một cái gì đó như thế này, tôi chỉ cần trở thành root:

# Sudo -s
# ls -hal /root/ > /root/test.out
# exit

Nó có thể không phải là cách tốt nhất, nhưng nó hoạt động.

3
Adam J. Forster

Đừng có ý đánh bại một con ngựa chết, nhưng có quá nhiều câu trả lời ở đây sử dụng tee, điều đó có nghĩa là bạn phải chuyển hướng stdout sang /dev/null trừ khi bạn muốn xem một bản sao trên màn hình. Một giải pháp đơn giản hơn là chỉ sử dụng cat như thế này:

Sudo ls -hal /root/ | Sudo bash -c "cat > /root/test.out"

Lưu ý cách chuyển hướng được đặt bên trong dấu ngoặc kép để nó được đánh giá bởi Shell bắt đầu bằng Sudo thay vì chạy hướng dẫn.

3
haridsv

Điều này dựa trên câu trả lời liên quan đến tee. Để làm cho mọi thứ dễ dàng hơn, tôi đã viết một tập lệnh nhỏ (tôi gọi nó là suwrite) và đặt nó vào /usr/local/bin/ với quyền +x:

#! /bin/sh
if [ $# = 0 ] ; then
    echo "USAGE: <command writing to stdout> | suwrite [-a] <output file 1> ..." >&2
    exit 1
fi
for arg in "[email protected]" ; do
    if [ ${arg#/dev/} != ${arg} ] ; then
        echo "Found dangerous argument ‘$arg’. Will exit."
        exit 2
    fi
done
Sudo tee "[email protected]" > /dev/null

Như được hiển thị trongC&AACUTE;CH SỬ DỤNGtrong mã, tất cả những gì bạn phải làm là chuyển đầu ra sang tập lệnh này theo sau là tên tệp siêu người dùng có thể truy cập và nó sẽ tự động Nhắc mật khẩu của bạn nếu cần (vì nó bao gồm Sudo).

echo test | suwrite /root/test.txt

Lưu ý rằng vì đây là trình bao bọc đơn giản cho tee, nên nó cũng sẽ chấp nhận tùy chọn -a của tee để chắp thêm và cũng hỗ trợ ghi vào nhiều tệp cùng một lúc.

echo test2 | suwrite -a /root/test.txt
echo test-multi | suwrite /root/test-a.txt /root/test-b.txt

Nó cũng có một số bảo vệ đơn giản chống lại việc ghi vào các thiết bị /dev/, một mối quan tâm được đề cập trong một trong những bình luận trên trang này.

2
jamadagni

Có lẽ bạn đã được cấp quyền truy cập Sudo vào một số chương trình/đường dẫn? Sau đó, không có cách nào để làm những gì bạn muốn. (trừ khi bạn sẽ hack nó bằng cách nào đó)

Nếu không phải như vậy thì có lẽ bạn có thể viết bash script:

cat > myscript.sh
#!/bin/sh
ls -hal /root/ > /root/test.out 

Nhấn ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Hy vọng nó sẽ giúp.

1
user15453
Sudo at now  
at> echo test > /tmp/test.out  
at> <EOT>  
job 1 at Thu Sep 21 10:49:00 2017  
0
user8648126