sudo cat << EOF > 文件无法工作,sudo su可以。

93

我在bash的命令提示符下尝试了以下操作:

sudo cat << EOF > /etc/yum.repos.d/some-name.repo
#Content
#....
#...
EOF

它抱怨道:

-bash: /etc/yum.repos.d/some-name.repo: Permission denied

然后我执行了sudo su,并尝试了与cat之前的sudo完全相同的操作,这次却没有任何问题。在上述步骤中我漏掉了什么?

5个回答

130

在使用您的UID运行时,输出重定向(例如>)由bash执行,而不是cat执行。要使用root的UID运行,请使用sudo:

sudo bash -c 'cat << EOF > /etc/yum.repos.d/some-name.repo
line1
line2
line3
EOF'

我不理解的部分是,我已经在使用bash提示符,那么为什么我需要bash -c - iamauser
1
因为在这种情况下,重定向将由以“root” uid 启动的 bash 执行,该用户具有足够的权限来写入 /etc/yum.repos.d/。 - Yuriy Nazarov
2
您可以使用任何其他可重定向输出的实用工具。例如,“cat << EOF | sudo tee /etc/yum.repos.d/some-name.repo”。 - Yuriy Nazarov

76
另一个选择是使用tee命令。
cat << EOF | sudo tee -a /etc/yum.repos.d/some-name.repo
...
EOF

40
作为对 @Yuriy Nazarov 答案的变化,只有通过管道输出的内容需要通过 sudo 进行提升权限,管道输入可以保持不提升权限:
sudo bash -c 'cat > /etc/yum.repos.d/some-name.repo' << EOF
line1
line2
line3
EOF

这意味着命令中需要引用并发送到sudo的部分要小得多。


3
在我这种情况下,这比被接受的答案要好得多,因为我的管道输出充满了变量、shebang和其他东西。 - Chuck Wilbur

12

正如其他人所指出的,shell重定向是由当前shell而不是cat执行的。sudo仅更改执行的程序的权限,而不是进行重定向的shell的权限。我的解决方案是避免重定向:

sudo dd of=/etc/yum.repos.d/some-name.repo << EOF

5

如果您在文本中使用'字符,则可以使用以下方法:

$ sudo bash -c "cat > /etc/postfix/mysql-virtual_forwardings.cf << EOF
user = mail_admin
password = password
dbname = mail
query = SELECT destination FROM forwardings WHERE source='%s'
hosts = 127.0.0.1
EOF
"

这是在谷歌云的虚拟服务器CentOS 7.0上测试的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接