写入 stdin 时权限被拒绝

写入 stdin 时权限被拒绝

我有两个由两个不同用户运行的进程。这两个用户都属于同一组。我想stdin通过写入 从一个进程写入/proc/<pid>/fd/0,但权限仅为另一个用户设置,因此我得到的是permission denied。我能否以某种方式更改权限,以便另一个进程可以写入它?

$ ls -lsa /proc/<pid>/fd/
0 lrwx------ 1 foo group1 64 Feb 14 23:15 0 -> /dev/pts/3

答案1

0 lrwx------ 1 foo group1 64 Feb 14 23:15 0 -> /dev/pts/3

我是否可以以某种方式改变权限以便其他进程可以写入它?

是的,但是写作可能不会达到你想要的效果。

/dev/pts/3是伪终端从属设备。您跟踪的进程从伪终端获取输入。您可以使用 更改此类设备的权限chmod。命名的节点0不会反映更改,但/dev/pts/3会。要使用更改的权限,您需要写入/dev/pts/3,而不是0

但结果很可能不符合您的预期。为了解释这一点,请在终端仿真器(konsole, xterm)或终端多路复用器(tmux, screen)中运行 shell 并调用ls -l /proc/$$/fd/。您会发现 shell 读取和写入相同的pts。当它读取时,它会读取您输入的内容。当它写入时,它会让字符出现在终端中。

如果您写入/dev/pts/3:也会发生相同的情况,终端中将出现字符,为相关进程提供输入。您的操作不会像在终端中键入一样注入输入,即它不会为进程提供输入。

要注入像您键入的那样的输入,您需要写入相应的主设备。这是 不简单简而言之

在 Linux 上,使用devpts,没有主设备文件。主端的进程使用通过打开 获得的文件描述符ptmx,但没有相应的设备节点。

“主端上的进程”是终端仿真器、终端多路复用器sshd(如果客户端请求伪终端)expect……

然而另一个答案状态:

有一个特殊的 ioctl ( TIOCSTI),它允许您将一个字节插入到 tty 的输入队列中,就好像它是从另一端接收的一样。TIOCSTI只有当不在调用它的进程的控制 tty 上使用时,才会以 root 身份工作。

有关详细信息,请参阅完整答案。我猜这对您可能不是很有用,因为需要 root 访问权限。


(单向)连接两个进程的最简单方法是使用管道连接它们:

foo | bar

如果进程即将由两个不同的用户启动,请使用命名管道而不是未命名管道:

# any user
mkfifo pipeA
chmod …     # allow access for the other user

# user1
foo >pipeA

# user2
<pipeA bar

命名管道的行为符合您的预期,而伪终端从属设备则不然。

注意foobar启动时各自的 stdout 和 stdin 已经重定向。正在运行的进程可以重定向自己的 stdin(例如 shell 可以根据需要重定向),但没有简单/优雅的方法来强制它

例如,如果所讨论的进程是交互式的,则可以通过调用bash使其将其 stdin 从重定向。然后,您可以从另一个控制台执行类似操作,并且 shell 将像您键入它一样执行(并且它可能会退出,因为写入管道的所有描述符现在都已关闭;为避免这种情况,请首先在 shell 中打开命名管道以进行写入:)。pipeAexec 0<pipeAecho date >pipeAdateexec 0<>pipeA

答案2

一般来说,您无法写入标准输入。顾名思义,标准输入用于输入,而不是输出,即使它是一个常规文件,您也不能假设它已使用只读访问权限以外的任何方式打开。

听起来你试图做的是在另一个程序的输入上产生一个程序的输出,这通常只有在它们通过管道连接时才会起作用。如果你打开该文件描述符文件(如果允许),而不是创建到该进程现有标准输入的管道,你只会写入该进程的 TTY。该 TTY 的用户会对此非常不满,这就是为什么通常不允许这样做的原因。

可以通过连接管道来生成不同用户的进程,但通常需要 root 权限或具有该权限的程序的帮助(如sudo)。

如果您需要在两个进程之间进行通信,但不能或不想使用管道,那么您可能想使用 Unix 套接字。一个进程应该打开套接字并对其进行侦听,然后其他进程可以打开套接字并连接到它,从而在两个进程之间创建双向通道。由于套接字位于文件系统中,因此您可以授予它权限,以便同一组的成员都可以使用它。

相关内容