Linux 如何使用 sudo 将输出重定向到我无权写入的位置?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/82256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:26:45  来源:igfitidea点击:

How do I use sudo to redirect output to a location I don't have permission to write to?

linuxpermissionssudoio-redirectionpermission-denied

提问by Jonathan

I've been given sudo access on one of our development RedHat linux boxes, and I seem to find myself quite often needing to redirect output to a location I don't normally have write access to.

我已经获得了对我们开发的 RedHat linux 机器之一的 sudo 访问权限,我似乎发现自己经常需要将输出重定向到我通常没有写访问权限的位置。

The trouble is, this contrived example doesn't work:

问题是,这个人为的例子不起作用:

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

I just receive the response:

我刚收到回复:

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

How can I get this to work?

我怎样才能让它发挥作用?

采纳答案by Cristian Ciupitu

Your command does not work because the redirection is performed by your shell which does not have the permission to write to /root/test.out. The redirection of the output is notperformed by sudo.

您的命令不起作用,因为重定向是由您的 shell 执行的,它没有写入/root/test.out. sudo执行输出的重定向。

There are multiple solutions:

有多种解决方案:

  • Run a shell with sudo and give the command to it by using the -coption:

    sudo sh -c 'ls -hal /root/ > /root/test.out'
    
  • Create a script with your commands and run that script with sudo:

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

    Run sudo ls.sh. See Steve Bennett's answerif you don't want to create a temporary file.

  • Launch a shell with sudo -sthen run your commands:

    [nobody@so]$ sudo -s
    [root@so]# ls -hal /root/ > /root/test.out
    [root@so]# ^D
    [nobody@so]$
    
  • Use sudo tee(if you have to escape a lot when using the -coption):

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

    The redirect to /dev/nullis needed to stop teefrom outputting to the screen. To appendinstead of overwriting the output file (>>), use tee -aor tee --append(the last one is specific to GNU coreutils).

  • 使用 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 的回答

  • 启动一个 shell,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需要重定向到以阻止tee输出到屏幕。要追加而不是覆盖输出文件 ( >>),请使用tee -aor tee --append(最后一个特定于GNU coreutils)。

Thanks go to Jd, Adam J. Forsterand Johnathanfor the second, third and fourth solutions.

感谢JdAdam J. ForsterJohnathan提供的第二、第三和第四个解决方案。

回答by Jonathan

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 运行脚本:

sudo ./myscript

回答by Penfold

Make sudo run a shell, like this:

使 sudo 运行一个 shell,如下所示:

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

回答by Adam J. Forster

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

每当我必须做这样的事情时,我就会成为 root:

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

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

这可能不是最好的方法,但它有效。

回答by user15453

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)

也许您只获得了对某些程序/路径的 sudo 访问权限?那么就没有办法做你想做的事了。(除非你会以某种方式破解它)

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

如果不是这种情况,那么也许您可以编写 bash 脚本:

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

Press ctrl+ d:

ctrl+ d

chmod a+x myscript.sh
sudo myscript.sh

Hope it help.

希望有帮助。

回答by Jonathan

Someone here has just suggested sudoing tee:

这里有人刚刚建议 sudoing tee:

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

This could also be used to redirect any command, to a directory that you do not have access to. It works because the tee program is effectively an "echo to a file" program, and the redirect to /dev/null is to stop it also outputting to the screen to keep it the same as the original contrived example above.

这也可用于将任何命令重定向到您无权访问的目录。它之所以有效是因为 tee 程序实际上是一个“echo to a file”程序,重定向到 /dev/null 是为了停止它也输出到屏幕以使其与上面的原始人为示例相同。

回答by dsm

The problem is that the commandgets run under sudo, but the redirectiongets run under your user. This is done by the shell and there is very little you can do about it.

问题是命令在 下运行sudo,但重定向在您的用户下运行。这是由外壳程序完成的,您对此无能为力。

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

The usual ways of bypassing this are:

绕过这个的常用方法是:

  • Wrap the commands in a script which you call under sudo.

    If the commands and/or log file changes, you can make the script take these as arguments. For example:

    sudo log_script command /log/file.txt
    
  • Call a shell and pass the command line as a parameter with -c

    This is especially useful for one off compound commands. For example:

    sudo bash -c "{ command1 arg; command2 arg; } > /log/file.txt"
    
  • 将命令包装在您在 sudo 下调用的脚本中。

    如果命令和/或日志文件发生更改,您可以让脚本将这些作为参数。例如:

    sudo log_script command /log/file.txt
    
  • 调用 shell 并将命令行作为参数传递 -c

    这对于一次性复合命令特别有用。例如:

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

回答by rhlee

A trick I figured out myself was

我发现自己的一个技巧是

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

回答by fardjad

I would do it this way:

我会这样做:

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

回答by Steve Bennett

Yet another variation on the theme:

主题的另一个变化:

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

Or of course:

或者当然:

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

They have the (tiny) advantage that you don't need to remember any arguments to sudoor sh/bash

它们具有(微小的)优势,您无需记住任何参数sudosh/bash