输出重定向错误处理
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权限。
接下来,让我们看看是否可以 使用sudo将echo输出重定向到目标文件:
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中打印文本,我们将tee的stdout重定向到*/dev/null*。