我经常使用此命令在我的开发 VM 中的用户之间切换:
✸ sudo su - otheruser
但是,如果我尝试访问/dev/stderr
或类似内容,我会遇到麻烦:
otheruser$ echo hi > /dev/stderr
-bash: /dev/stderr: Permission denied
我知道我可以>&2
在这个特定的实例中使用,但在某些情况下(例如tee /dev/stderr
)你需要一个可打开的文件,而不仅仅是一个文件描述符。
我发现我可以在 sudo 之前打开 tty 的写权限来解决这个问题:
✸ ls -ld /dev/stderr
lrwxrwxrwx 1 root root 15 Jan 13 08:06 /dev/stderr -> /proc/self/fd/2
✸ ls -ld /proc/self/fd/2
lrwx------ 1 aron aron 64 Jan 14 15:08 /proc/self/fd/2 -> /dev/pts/13
✸ ls -ld /dev/pts/13
crw--w---- 1 aron tty 136, 13 Jan 14 15:08 /dev/pts/13
✸ chmod a+w /dev/pts/13
或更简单地说:
✸ chmod a+w /dev/stderr
但我想知道我是否应该使用不同的调用,可以正确分配和/或授予权限。建议?
这是 /proc 的 Linux 实现的一个已知怪癖;多年未修好的。在 Linux 中,打开下面的链接
/proc/*/fd/*
并不会像 dup() 那样直接复制文件描述符(尽管魔术 /proc 链接理论上可以实现这一点)——相反,它会重新打开文件,并执行新的权限检查。您发现的最基本的解决方法是在使用之前授予目标用户对 tty 的权限
su
orsudo
。例如:(可能可以编写一个 PAM 模块来做同样的事情。)
一个可能更好的解决方法是使用用户切换方法,给你一个全新的 tty——
su --pty
如果你有 util-linux 版本的 su,一个这样的工具是。Systemd 有一个systemd-run
工具可以交互地运行临时服务;同样,它带有一个machinectl shell
主要用于容器的工具,但最近的版本也有一个“环回”模式:您还会得到与使用 Screen 或 tmux 等终端多路复用器的副作用相同的结果,这些终端多路复用器必然会为其窗口/窗格分配新的 tty:
所有这些工具将为嵌套会话分配一个新的 pty,在两侧之间中继所有输入/输出。