重定向输出到受权限拒绝错误影响的位置?


概述

我们知道,我们可以使用 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 的命令,我们可能会遇到“权限被拒绝”错误。

我们在这里详细介绍了这个问题,包括它的原因、解决方案和一些避免它的最佳实践。

更新于:2022年12月26日

580 次浏览

启动您的职业生涯

完成课程后获得认证

开始
广告