Perl IPC::Run3:如何模拟 stdin 到 child 进程的 pty?
Perl IPC::Run3: How to emulate a pty for stdin to child process?
这是 的跟进问题,尽管它们确实不相关。
取下面的示例代码:
use strict;
use warnings;
use IPC::Run3;
sub foo
{
my $cmd = shift;
my $CH_IN = "foo\n";
run3($cmd, $CH_IN, my $CH_OUT, my $CH_ERR);
return 1;
}
my @LIST = ( 'command','arg1','arg2','arg3' );
foo \@LIST;
以上代码command
是另一个perl脚本。 child 脚本调用 who -m
以从终端查找谁拥有 stdin,这是为了在 child 或 parent 脚本被使用 root 或其他通用调用的情况下使用系统用户。
当 parent 调用时,我从 child 得到的错误如下。
Use of uninitialized value in split at child.pl line 354.
WHOAMI is undef
Child 下面的代码。
第 354 行附近的代码:
# Function Name: 'determine_user'
# Function Inputs: 'Optional Scalar: Username to login as'
# Function Returns: 'If username is provided: Scalar: the username provided, If username is not provided: The output of who -m'
# Function Description: 'Figures out the user to login as'
sub determine_user
{
my $USER = shift;
if (!defined $USER)
{
my $WHOAMI;
open my $WHOPROC, q{-|}, 'who -m' or die "Unable to open 'who -m' for output.\n";
$WHOAMI=<$WHOPROC>;
close $WHOPROC or die "Unable to close 'who -m'.\n";
$USER = split m{[\s]+}xms, $WHOAMI or die "WHOAMI is undef\n"; # This is line 354
}
chomp $USER;
return $USER;
}
当我从命令行调用 child 脚本时,上面的代码工作得很好,但是由于 who -m
试图查看谁拥有终端的标准输入,并且终端已被替换parent 脚本,我相信我需要找到一种方法来在 运行 从 parent 中调用 who -m 时使用模拟 pty。无论是通过修改 child 还是 parent 或两者都没有关系,因为我可以修改两者。
所以我的问题是:我如何 运行 parent 内部的 child 并且仍然依赖 who -m
的输出被馈送到 child?
编辑:ikegami 在他的回答评论中提供了最佳解决方案。它没有回答问题,但确实解决了我的问题。
My ssh daemon sets env var SSH_TTY
, so you could use perl -MFile::stat -E'say scalar(getpwuid(stat($ENV{SSH_TTY})->uid))'
. Default to scalar(getpwuid($>))
if it's not set.
who -m
专门给出了有关连接到其标准输入的终端的信息。
-m only hostname and user associated with stdin
您更换了终端,因此无法从中获取信息。
$ who -m
ikegami pts/1 ...
$ who -m </dev/null
$
您可以删除 -m
并只使用 who
。
$ who </dev/null
ikegami pts/1 ...
或者,您可以使用 $ENV{USER}
或 getpwuid($>)
(执行进程的用户名)。
这是
取下面的示例代码:
use strict;
use warnings;
use IPC::Run3;
sub foo
{
my $cmd = shift;
my $CH_IN = "foo\n";
run3($cmd, $CH_IN, my $CH_OUT, my $CH_ERR);
return 1;
}
my @LIST = ( 'command','arg1','arg2','arg3' );
foo \@LIST;
以上代码command
是另一个perl脚本。 child 脚本调用 who -m
以从终端查找谁拥有 stdin,这是为了在 child 或 parent 脚本被使用 root 或其他通用调用的情况下使用系统用户。
当 parent 调用时,我从 child 得到的错误如下。
Use of uninitialized value in split at child.pl line 354.
WHOAMI is undef
Child 下面的代码。
第 354 行附近的代码:
# Function Name: 'determine_user'
# Function Inputs: 'Optional Scalar: Username to login as'
# Function Returns: 'If username is provided: Scalar: the username provided, If username is not provided: The output of who -m'
# Function Description: 'Figures out the user to login as'
sub determine_user
{
my $USER = shift;
if (!defined $USER)
{
my $WHOAMI;
open my $WHOPROC, q{-|}, 'who -m' or die "Unable to open 'who -m' for output.\n";
$WHOAMI=<$WHOPROC>;
close $WHOPROC or die "Unable to close 'who -m'.\n";
$USER = split m{[\s]+}xms, $WHOAMI or die "WHOAMI is undef\n"; # This is line 354
}
chomp $USER;
return $USER;
}
当我从命令行调用 child 脚本时,上面的代码工作得很好,但是由于 who -m
试图查看谁拥有终端的标准输入,并且终端已被替换parent 脚本,我相信我需要找到一种方法来在 运行 从 parent 中调用 who -m 时使用模拟 pty。无论是通过修改 child 还是 parent 或两者都没有关系,因为我可以修改两者。
所以我的问题是:我如何 运行 parent 内部的 child 并且仍然依赖 who -m
的输出被馈送到 child?
编辑:ikegami 在他的回答评论中提供了最佳解决方案。它没有回答问题,但确实解决了我的问题。
My ssh daemon sets env var
SSH_TTY
, so you could useperl -MFile::stat -E'say scalar(getpwuid(stat($ENV{SSH_TTY})->uid))'
. Default toscalar(getpwuid($>))
if it's not set.
who -m
专门给出了有关连接到其标准输入的终端的信息。
-m only hostname and user associated with stdin
您更换了终端,因此无法从中获取信息。
$ who -m
ikegami pts/1 ...
$ who -m </dev/null
$
您可以删除 -m
并只使用 who
。
$ who </dev/null
ikegami pts/1 ...
或者,您可以使用 $ENV{USER}
或 getpwuid($>)
(执行进程的用户名)。