Development Tip

sudo를 사용하여 쓰기 권한이없는 위치로 출력을 리디렉션하려면 어떻게해야합니까?

yourdevel 2020. 9. 28. 10:13
반응형

sudo를 사용하여 쓰기 권한이없는 위치로 출력을 리디렉션하려면 어떻게해야합니까?


저는 개발 RedHat 리눅스 박스 중 하나에서 sudo 액세스 권한을 받았으며 일반적으로 쓰기 액세스 권한이없는 위치로 출력을 리디렉션해야하는 경우가 자주있는 것 같습니다.

문제는이 인위적인 예제가 작동하지 않는다는 것입니다.

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

방금 응답을 받았습니다.

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

이 작업을 수행하려면 어떻게해야합니까?


에 쓰기 권한이없는 셸에서 리디렉션을 수행하므로 명령이 작동하지 않습니다 /root/test.out. 출력의 방향 재 지정은 sudo에 의해 수행 되지 않습니다 .

여러 솔루션이 있습니다.

  • sudo로 쉘을 실행하고 -c옵션 을 사용하여 명령을 제공하십시오 .

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • 명령으로 스크립트를 만들고 sudo로 해당 스크립트를 실행합니다.

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

    을 실행 sudo ls.sh합니다. 임시 파일을 생성하지 않으려면 Steve Bennett의 답변을 참조하십시오 .

  • 를 사용하여 셸을 sudo -s시작한 다음 명령을 실행합니다.

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • 사용 sudo tee( -c옵션을 사용할 때 많이 이스케이프해야하는 경우 ) :

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

    화면에 가 출력되는 /dev/null것을 중지하려면로 리디렉션 이 필요합니다 . 출력 파일 ( ) 을 덮어 쓰는 대신 추가 하려면 또는을 사용 하십시오 ( 마지막 파일 GNU coreutils 에만 해당됨 ).>>tee -atee --append

두 번째, 세 번째 및 네 번째 솔루션에 대해 Jd , Adam J. ForsterJohnathan 에게 감사드립니다 .


여기 누군가가 sudoing 티를 제안했습니다.

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

또한 액세스 권한이없는 디렉터리로 명령을 리디렉션하는 데 사용할 수도 있습니다. tee 프로그램은 사실상 "파일에 에코"프로그램이기 때문에 작동하며 / dev / null 로의 리디렉션은 위의 원래 인위적인 예제와 동일하게 유지하기 위해 화면에 출력하는 것을 중지하는 것입니다.


내가 알아 낸 속임수는

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

문제는 명령 이에서 실행 sudo되지만 리디렉션 이 사용자 아래 에서 실행 된다는 것 입니다. 이것은 쉘에 의해 수행되며 이에 대해 수행 할 수있는 작업이 거의 없습니다.

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

이를 우회하는 일반적인 방법은 다음과 같습니다.

  • sudo에서 호출하는 스크립트로 명령을 래핑하십시오.

    명령 및 / 또는 로그 파일이 변경되면 스크립트에서이를 인수로 사용할 수 있습니다. 예를 들면 :

    sudo log_script command /log/file.txt
    
  • 셸을 호출하고 다음을 사용하여 명령 줄을 매개 변수로 전달합니다. -c

    이것은 일회성 복합 명령에 특히 유용합니다. 예를 들면 :

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

주제에 대한 또 다른 변형 :

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

또는 물론 :

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

그들은 sudo또는 sh/에 대한 논쟁을 기억할 필요가 없다는 (작은) 이점이 있습니다.bash


티 옵션이 선호되는 이유에 대해 설명

출력을 생성하는 명령을 실행할 적절한 권한이 있다고 가정하고 명령의 출력을 tee로 파이프하면 tee의 권한을 sudo로 높이고 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

이러한 각 예제에서는 권한이없는 명령의 출력을 가져 와서 일반적으로 질문의 출처 인 루트 만 쓸 수있는 파일에 작성합니다.

It is a good idea to do it this way because the command that generates the output is not executed with elevated privileges. It doesn't seem to matter here with echo but when the source command is a script that you don't completely trust, it is crucial.

Note you can use the -a option to tee to append append (like >>) to the target file rather than overwrite it (like >).


Make sudo run a shell, like this:

sudo sh -c "echo foo > ~root/out"

The way I would go about this issue is:

If you need to write/replace the file:

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

If you need to append to the file:

echo "some text" | sudo tee -a /path/to/file

How about writing a script?

Filename: myscript

#!/bin/sh

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

# end script

Then use sudo to run the script:

sudo ./myscript

I would do it this way:

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

Whenever I have to do something like this I just become root:

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

It's probably not the best way, but it works.


Don't mean to beat a dead horse, but there are too many answers here that use tee, which means you have to redirect stdout to /dev/null unless you want to see a copy on the screen. A simpler solution is to just use cat like this:

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

Notice how the redirection is put inside quotes so that it is evaluated by a shell started by sudo instead of the one running it.


This is based on the answer involving tee. To make things easier I wrote a small script (I call it suwrite) and put it in /usr/local/bin/ with +x permission:

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

As shown in the USAGE in the code, all you have to do is to pipe the output to this script followed by the desired superuser-accessible filename and it will automatically prompt you for your password if needed (since it includes sudo).

echo test | suwrite /root/test.txt

Note that since this is a simple wrapper for tee, it will also accept tee's -a option to append, and also supports writing to multiple files at the same time.

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

It also has some simplistic protection against writing to /dev/ devices which was a concern mentioned in one of the comments on this page.


Maybe you been given sudo access to only some programs/paths? Then there is no way to do what you want. (unless you will hack it somehow)

If it is not the case then maybe you can write bash script:

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

Press ctrl + d :

chmod a+x myscript.sh
sudo myscript.sh

Hope it help.


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

참고URL : https://stackoverflow.com/questions/82256/how-do-i-use-sudo-to-redirect-output-to-a-location-i-dont-have-permission-to-wr

반응형