linux - permission - tee sudo




如何使用sudo將輸出重定向到我無權寫入的位置? (10)

澄清為什麼T卹選項更可取

假設您有適當的權限來執行創建輸出的命令,如果您將命令的輸出用管道輸出,則只需使用sudo提升tee的權限,並直接將tee寫入(或追加)到正在討論的文件中。

在問題中給出的例子中,這將意味著:

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

對於一些更實際的例子:

# 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

在這些例子中的每一個中,您都將輸出一個非特權命令並寫入一個通常只能由root寫入的文件,這是您的問題的根源。

這樣做是一個好主意,因為生成輸出的命令不會以提升的權限執行。 在這裡使用echo並不重要,但是當source命令是一個你不完全信任的腳本時,這是至關重要的。

請注意,您可以使用-a選項來開始追加(如>> )到目標文件而不是覆蓋它(如> )。

我已經在RedHat linux的一個開發箱中獲得了sudo訪問權限,而且我似乎經常需要將輸出重定向到我通常無法訪問的位置。

麻煩的是,這個人為的例子不起作用:

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

我剛收到回复:

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

我怎樣才能使這個工作?


不要吝嗇一匹死馬,但這裡使用tee答案太多了,這意味著除非您想在屏幕上看到副本,否則必須將stdout重定向到/dev/null 。 更簡單的解決方案就是像這樣使用cat

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

請注意重定向是如何放在引號內的,以便通過由sudo啟動而不是運行它的shell來評估。


另一個主題變體:

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

或者當然:

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

他們有(小)優勢,你不需要記住sudosh / bash任何參數


問題在於命令sudo下運行,但重定向在您的用戶下運行。 這是由shell完成的,你可以做的很少。

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

繞過這個通常的方法是:

  • 將這些命令封裝在您在sudo下調用的腳本中。

    如果命令和/或日誌文件發生更改,則可以使腳本將這些參數作為參數。 例如:

    sudo log_script command /log/file.txt
    
  • 調用shell並使用-c作為參數傳遞命令行

    這對於一個複合命令特別有用。 例如:

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

您的命令不起作用,因為重定向是由您的shell執行的,該shell沒有寫入/root/test.out的權限。 輸出的重定向不由 sudo執行。

有多種解決方案:

  • 使用sudo運行一個shell,並使用-c選項給該命令:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • 用你的命令創建一個腳本,並用sudo運行腳本:

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

    運行sudo ls.sh 如果您不想創建臨時文件,請參閱Steve Bennett的answer 。

  • sudo -s啟動一個shell然後運行你的命令:

    [[email protected]]$ sudo -s
    [[email protected]]# ls -hal /root/ > /root/test.out
    [[email protected]]# ^D
    [[email protected]]$
    
  • 使用sudo tee (如果在使用-c選項時必須轉義很多):

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

    重定向到/dev/null需要停止輸出到屏幕。 要添加而不是覆蓋輸出文件( >> ),請使用tee -atee --append (最後一個特定於GNU coreutils )。

感謝Jd , Adam J. Forster和Johnathan提供第二,第三和第四個解決方案。


我弄明白自己的一招是

sudo ls -hal /root/ | sudo dd of=/root/test.out

我會這樣做:

sudo su -c 'ls -hal /root/ > /root/test.out'

每當我必須做這樣的事情時,我就成為了根:

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

這可能不是最好的方式,但它的工作原理。


這是涉及T恤的答案的延伸。 為了使事情變得簡單,你可能想製作一個小腳本(我稱之為suwrite,或者你可以稱它為sutee),並將它放在/ usr / local / bin /中,並帶有+ x權限:

#! /bin/sh
sudo tee [email protected] > /dev/null

現在,您只需將輸出管道輸出到此腳本,然後輸入所需的超級用戶可訪問的文件名,並在需要時自動提示您輸入密碼(因為它包含sudo)。

echo test | suwrite /root/test.txt

請注意,由於這是一個簡單的T卹包裝,它也會接受T恤的-a(或任何其他)選項,以追加到您剛剛傳遞的所需文件-a:

echo test | suwrite -a /root/test.txt

這裡有人剛剛建議sudoing tee:

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

這也可以用來將任何命令重定向到一個你無權訪問的目錄。 它的工作原理是因為T卹程序實際上是“對文件的回應”程序,而重定向到/ dev / null將停止它並輸出到屏幕以保持它與上面原始的設計示例相同。







permission-denied