it-swarm-id.com

Bagaimana cara menggunakan Sudo untuk mengarahkan output ke lokasi yang saya tidak punya izin untuk menulis?

Saya telah diberi akses Sudo pada salah satu kotak RedHat linux pengembangan kami, dan saya sepertinya mendapati diri saya cukup sering perlu mengarahkan ulang output ke lokasi yang biasanya tidak saya miliki akses tulisnya.

Masalahnya adalah, contoh buatan ini tidak berfungsi:

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

Saya baru saja menerima tanggapan:

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

Bagaimana saya bisa membuatnya bekerja?

760
Jonathan

Perintah Anda tidak berfungsi karena pengalihan dilakukan oleh Shell Anda yang tidak memiliki izin untuk menulis ke /root/test.out. Pengalihan output tidak dilakukan oleh Sudo.

Ada beberapa solusi:

  • Jalankan Shell dengan Sudo dan berikan perintah padanya dengan menggunakan opsi -c:

    Sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Buat skrip dengan perintah Anda dan jalankan skrip itu dengan Sudo:

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

    Jalankan Sudo ls.sh. Lihat jawaban Steve Bennett jika Anda tidak ingin membuat file sementara.

  • Luncurkan Shell dengan Sudo -s lalu jalankan perintah Anda:

    [[email protected]]$ Sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • Gunakan Sudo tee (jika Anda harus banyak melarikan diri saat menggunakan opsi -c):

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

    Pengalihan ke /dev/null diperlukan untuk menghentikan tee dari keluaran ke layar. Untuk tambahkan alih-alih menimpa file output (>>), gunakan tee -a atau tee --append (yang terakhir khusus untuk GNU coreutils ).

Terima kasih untuk Jd , Adam J. Forster dan Johnathan untuk solusi kedua, ketiga dan keempat.

1068
Cristian Ciupitu

Seseorang di sini baru saja menyarankan tee sudoing:

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

Ini juga dapat digunakan untuk mengarahkan ulang perintah apa pun, ke direktori yang Anda tidak memiliki akses. Ini berfungsi karena program tee secara efektif merupakan program "gema ke file", dan redirect ke/dev/null adalah untuk menghentikannya juga menampilkan ke layar agar tetap sama dengan contoh asli yang dibuat di atas.

89
Jonathan

Trik yang saya temukan sendiri adalah

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

Masalahnya adalah bahwa command dijalankan di bawah Sudo, tetapi redirection dijalankan di bawah pengguna Anda. Ini dilakukan oleh Shell dan ada sangat sedikit yang dapat Anda lakukan.

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

Cara biasa untuk melewati ini adalah:

  • Bungkus perintah dalam skrip yang Anda panggil di bawah Sudo.

    Jika perintah dan/atau file log berubah, Anda dapat menjadikan skrip Menganggapnya sebagai argumen. Sebagai contoh:

    Sudo log_script command /log/file.txt
    
  • Panggil Shell dan lewati baris perintah sebagai parameter dengan -c

    Ini sangat berguna untuk perintah one off compound . Misalnya:

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

Variasi lain pada tema:

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

Atau tentu saja:

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

Mereka memiliki keuntungan (kecil) yang Anda tidak perlu mengingat argumen apa pun untuk Sudo atau sh/bash

19
Steve Bennett

Klarifikasi sedikit tentang mengapa opsi tee lebih disukai

Dengan asumsi Anda memiliki izin yang sesuai untuk mengeksekusi perintah yang menciptakan output, jika Anda mengirimkan output dari perintah Anda ke tee, Anda hanya perlu meninggikan hak istimewa tee dengan Sudo dan tee langsung untuk menulis (atau menambahkan) ke file yang dimaksud.

dalam contoh yang diberikan dalam pertanyaan yang berarti:

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

untuk beberapa contoh yang lebih praktis:

# 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

Dalam masing-masing contoh ini Anda mengambil output dari perintah yang tidak diistimewakan dan menulis ke file yang biasanya hanya dapat ditulis oleh root, yang merupakan asal dari pertanyaan Anda.

Ini adalah ide yang baik untuk melakukannya dengan cara ini karena perintah yang menghasilkan output tidak dieksekusi dengan hak istimewa yang ditinggikan. Tampaknya tidak masalah di sini dengan echo tetapi ketika perintah sumber adalah sebuah skrip yang tidak Anda percayai sepenuhnya, itu sangat penting.

Catatan Anda dapat menggunakan opsi -a untuk tee untuk menambahkan append (seperti >>) ke file target daripada menimpanya (seperti >).

18
jg3

Buat Sudo menjalankan Shell, seperti ini:

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

Cara saya membahas masalah ini adalah:

Jika Anda perlu menulis/mengganti file:

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

Jika Anda perlu menambahkan file:

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

Bagaimana kalau menulis naskah?

Nama file: myscript

#!/bin/sh

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

# end script

Kemudian gunakan Sudo untuk menjalankan skrip:

Sudo ./myscript
5
Jd

Saya akan melakukannya dengan cara ini:

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

Setiap kali saya harus melakukan sesuatu seperti ini, saya menjadi root:

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

Ini mungkin bukan cara terbaik, tetapi berhasil.

3
Adam J. Forster

Jangan bermaksud mengalahkan kuda mati, tetapi ada terlalu banyak jawaban di sini yang menggunakan tee, yang berarti Anda harus mengarahkan stdout ke /dev/null kecuali Anda ingin melihat salinan di layar. Solusi yang lebih sederhana adalah dengan menggunakan cat seperti ini:

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

Perhatikan bagaimana pengalihan dimasukkan ke dalam tanda kutip sehingga dievaluasi oleh Shell yang dimulai oleh Sudo alih-alih yang menjalankannya.

3
haridsv

Ini didasarkan pada jawaban yang melibatkan tee. Untuk mempermudah, saya menulis skrip kecil (saya menyebutnya suwrite) dan memasukkannya ke /usr/local/bin/ dengan izin +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

Seperti yang ditunjukkan padaPENGGUNAANdalam kode, yang harus Anda lakukan adalah menyalurkan output ke skrip ini diikuti dengan nama file yang dapat diakses pengguna super yang diinginkan dan itu akan secara otomatis meminta Anda untuk kata sandi Anda jika diperlukan (karena itu termasuk Sudo).

echo test | suwrite /root/test.txt

Perhatikan bahwa karena ini adalah pembungkus sederhana untuk tee, ia juga akan menerima opsi -a untuk ditambahkan, dan juga mendukung penulisan ke beberapa file secara bersamaan.

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

Ini juga memiliki beberapa perlindungan sederhana terhadap penulisan ke perangkat /dev/ yang menjadi perhatian yang disebutkan dalam salah satu komentar di halaman ini.

2
jamadagni

Mungkin Anda diberi akses Sudo ke hanya beberapa program/jalur? Maka tidak ada cara untuk melakukan apa yang Anda inginkan. (kecuali jika Anda akan meretasnya entah bagaimana)

Jika bukan itu masalahnya, mungkin Anda bisa menulis skrip bash:

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

Tekan ctrl + d :

chmod a+x myscript.sh
Sudo myscript.sh

Semoga ini bisa membantu.

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