重定向输出到受权限拒绝错误影响的位置?
概述
我们知道,我们可以使用 Linux shell 脚本末尾的 “>” 运算符将 Linux shell 脚本的标准输出 (std out) 重定向到文件。
有时,我们需要重定向到需要 root 权限的文件——例如,‘sudo command > file_requires_root_。
如果我们使用 ‘su’ 命令,即使我们使用了 ‘su’,我们也可能会收到“访问被拒绝”的消息。
我们将探讨此问题的原因,并查看是否有任何解决方案。
问题简介
一个很好的例子是对问题的解释。
假设我们有一个名为“output.txt”的空纯文本文档。
kent$ ls -l /opt/output.txt -rw-r--r-- 1 root root 0 May 8 10:43 /opt/output.txt
上面的 ls 命令显示只有用户“root”可以访问“/opt/output.txt”目录。
我们现在尝试将 echo 语句的输出重定向到指定的文本文档,作为普通用户 ken −
kent$ echo "Linux is awesome!" > /opt/output.txt bash: /opt/output.txt: Permission denied
我们收到了“访问被拒绝”错误。这很容易理解。因为我们执行“echotest”脚本并将其输出作为 kent 帐户重定向,但 kent 帐户对文件 /opt/.output.txt 没有任何权限。
如果我们使用“su”命令运行命令,则该命令将作为超级用户 (root) 运行。让我们假设用户 kent 已获得 sudo 权限。
现在让我们看看是否可以使用 sudo 将 stdout(默认输出)重定向到我们的新文本文档 −
kent$ sudo echo "Linux is awesome!" > /opt/output.txt [sudo] password for kent: bash: /opt/output.txt: Permission denied
输入密码后,我们仍然收到相同的错误消息。
我们可能会问,为什么即使我们使用了 sudo(超级用户)命令,也不允许我们写入文件?
现在我们需要找到这个问题的答案。
为什么会出现“权限被拒绝”错误?
要理解 echo 命令,我们首先需要检查其完整的语法。该命令由两部分组成 −
命令部分:sudo echo “Linux 真棒!”
重定向部分:> /opt/output.txt
当我们使用 sudo(超级)权限以 root 帐户身份运行命令时,sudo 不会更改重定向行为。
重定向仍然由普通帐户 ken 执行。因此,我们遇到“访问被拒绝”错误。
在理解问题原因(缺乏睡眠)后,现在我们需要讨论解决方案。
有几种不同的方法可以解决这个问题。让我们逐一看看它们。
启动“root” shell 来执行命令
将命令包装在 shell 脚本中
将重定向部分更改为命令
接下来,让我们逐一看看这三种方法。
启动“root” Shell 来执行命令
如果我们可以以 root 用户身份启动交互式 bash 会话并在其中运行我们的命令,则重定向也将在 root 级别进行。
运行 sudo su −c "echo 'Hello World' > /tmp/file" 时可以使用 −s 选项来创建 root shell。
kent$ sudo -s [sudo] password for kent: [root]# echo "Linux is awesome!" > /opt/output.txt [root]# exit kent$ cat /opt/output.txt Linux is awesome!
运行 sudo −i 后,我们现在处于具有超级用户(或“超级用户”)权限的交互式 bash 会话中。然后我们可以运行整个命令并以 root 身份进行重定向。
输出已成功保存到目标文件夹。
将命令包装在 shell 脚本中
我们可以使用 sudo 将这两个命令组合成一个命令,这意味着重定向将由超级用户(拥有管理员权限的用户)执行。
我们可以使用简单的 shell 脚本技术将“echo”命令写入文本文件。
kent$ cat myScript.sh #!/bin/bash echo "Linux is awesome! - (shell script)" > /opt/output.txt
让我们首先清空 output.txt 文件,然后运行我们的脚本。
kent$ sudo ./myScript.sh [sudo] password for kent: kent$ cat /opt/output.txt Linux is awesome! - (shell script)
我们期望我们的 shell 脚本按预期工作。
如果我们总是为带有重定向的命令行程序创建 shell 脚本,这可能会很不方便。
要从另一个 shell 脚本中运行单个 shell 脚本,我们可以使用 sudo sh −c "Script > File" 来运行第一个 shell 脚本并将它的输出重定向到第二个 shell 脚本。
kent$ sudo bash -c 'echo "Linux is awesome! - (sub-shell)" > /opt/output.txt' [sudo] password for kent: kent$ cat /opt/output.txt Linux is awesome! - (sub-shell)
将重定向更改为命令
从上一节我们知道,“su”命令不会影响重定向。如果我们可以将重定向更改回命令,我们可以再次使用 `su` 运行它们。
波浪号 (~) 字符用于指示备用位置。我们在这里使用它来告诉 shell 在哪里查找我们的输出。然后,我们运行 sudo 以便 shell 以 root 帐户身份执行命令。最后,我们再次使用波浪号 (~) 字符来告诉 shell 输出应该去哪里。
现在我们将使用一个示例来测试这种方法。
kent$ sudo echo "Linux is awesome! - (using tee)" | sudo tee /opt/output.txt >/dev/null [sudo] password for kent: kent$ cat /opt/output.txt Linux is awesome! - (using tee)
如上面的示例所示,我们已经在 output.txt 文档中计算出了预期值。
我们不需要显示 tee 的输出,因为我们将它的输出重定向到 /dev/null。
结论
如果我们运行类似 sudo command > file_requires_root 的命令,我们可能会遇到“权限被拒绝”错误。
我们在这里详细介绍了这个问题,包括它的原因、解决方案和一些避免它的最佳实践。