Contents

输出重定向错误处理

1. 概述

众所周知,我们可以使用Linux 命令行中的“ > ”运算符将命令的标准输出 ( stdout )重定向 到文件。

但是,有时,我们希望重定向到我们没有写入权限的文件——例如,“ sudo command > file_requires_root_permission ”。

在这种情况下,即使我们使用了sudo 命令,我们也可能会收到“Permission denied”错误。

在本快速教程中,我们将分析此问题的原因并找到解决问题的正确方法。

2. 问题介绍

一个例子可能是解释这个问题的最好方法。

假设我们有一个空的纯文本文件:

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文件。

现在,我们尝试以普通用户kent的身份将echo命令的输出重定向到上述文件:

kent$ echo "Linux is awesome!" > /opt/output.txt
bash: /opt/output.txt: Permission denied

我们收到“权限被拒绝”错误。这并不难理解。这是因为我们以kent用户执行echo命令并重定向输出,但用户kent对文件 /opt/output.txt没有写权限。

我们知道如果我们使用sudo 执行命令,该命令将以root用户身份执行。假设用户kent已被授予 sudo权限。

接下来,让我们看看是否可以 使用sudoecho输出重定向到目标文件:

kent$ sudo echo "Linux is awesome!" > /opt/output.txt
[sudo] password for kent:
bash: /opt/output.txt: Permission denied

糟糕,在我们提供密码后,我们仍然收到相同的错误消息。

我们可能会问,为什么我们使用了sudo命令仍然没有写入文件的权限?

接下来,让我们来寻找问题的答案。

3. 为什么会出现“Permission Denied”错误?

为了回答这个问题,让我们仔细看看整个echo命令。该命令有两个部分:

  • 命令部分:sudo echo “Linux is awesome!”
  • 重定向部分:  > /opt/output.txt

sudo命令允许我们以 root用户身份执行echo命令。但是,当我们写“sudo command > file”时,sudo命令不会影响重定向部分

换句话说,重定向仍然以普通用户kent 的身份执行。因此,我们遇到“权限被拒绝”错误。

现在我们了解了问题的原因,让我们讨论解决方案。

我们将介绍几种不同的方法来解决这个问题:

  • 启动*“root”* shell 来执行命令
  • 将命令包装在 shell 脚本中
  • 将重定向部分更改为命令

接下来,让我们一一看看这三种方法。

4. 启动“ root ”Shell 执行命令

如果我们可以启动一个以 root用户身份登录的 shell 并在这个 shell 中执行我们的命令,那么重定向也将由root完成。

我们可以将 -s选项传递给 sudo命令以获得“ 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 -s后,我们处于与root用户的交互式 shell 中。然后,我们可以以root身份执行整个命令和重定向。

输出也已成功写入目标文件。

5. 将命令包装在 Shell 脚本中

如果我们可以将命令和重定向变成一个命令,我们可以使用sudo执行它,以便重定向由root完成。

按照这个想法,我们可以创建一个简单的 shell 脚本文件,其中包含我们的 echo命令:

kent$ cat myScript.sh
#!/bin/bash
echo "Linux is awesome! - (shell script)" > /opt/output.txt

接下来,让我们清空*/opt/output.txt*文件并测试我们的 myScript.sh

kent$ sudo ./myScript.sh 
[sudo] password for kent:
kent$ cat /opt/output.txt
Linux is awesome! - (shell script)

我们的 shell 脚本按预期工作。

但是,如果我们总是必须为带有重定向的命令创建 shell 脚本文件,这可能会很不方便。

如果我们只想快速执行一次这样的命令,我们可以使用sudo bash -c “Command > file”在子 shell 中执行带有重定向的命令,以便root用户执行命令和重定向

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)

6.将重定向更改为命令

我们从上一节中了解到,sudo命令不会影响重定向部分。但是,如果我们可以将重定向更改为命令,我们可以再次使用sudo执行它。

tee 命令正是我们正在寻找的 。 ** tee允许我们将输入重定向到文件和stdout。此外,我们可以启动“ sudo tee …”以使tee命令以root用户身份执行。

接下来,让我们用我们的示例测试这种方法:

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)

如上例所示,我们已将预期值写入*/opt/output.txt*文件。

由于我们不想在stdout中打印文本,我们将teestdout重定向到*/dev/null*。