【发布时间】:2017-01-05 00:24:32
【问题描述】:
这是IPC::Open3 and determining if child is waiting for input 的后续问题,尽管他们承认不相关。
获取以下示例代码:
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 脚本。子脚本调用who -m 以从终端查找谁拥有标准输入,这是为了在使用root 或其他通用系统用户调用子脚本或父脚本的情况下使用。
当我被父母调用时,我从孩子那里得到的错误如下。
Use of uninitialized value in split at child.pl line 354.
WHOAMI is undef
下面的子代码。
第 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;
}
当我从命令行调用子脚本时,上面的代码工作得很好,但是由于who -m 试图查看谁拥有终端的标准输入并且终端已被父脚本替换,我相信我需要找到一种在从父级运行时使用模拟 pty 调用 who -m 的方法。无论是通过修改孩子还是父母或两者都没有关系,因为我可以同时修改。
所以我的问题是:我怎样才能在父级内部运行子级并且仍然依赖who -m 的输出被喂给子级?
编辑:ikegami 在他的答案的 cmets 中提供了最佳解决方案。它没有回答问题,但确实解决了我的问题。
我的 ssh 守护进程设置了 env var
SSH_TTY,所以你可以使用perl -MFile::stat -E'say scalar(getpwuid(stat($ENV{SSH_TTY})->uid))'。如果未设置,则默认为scalar(getpwuid($>))。
【问题讨论】:
-
当我尝试从终端窗口运行
who -m时,它没有输出,但是当我ssh进入另一台服务器然后运行who -m时,它给了我用户名。我不确定这是否与您的问题有关.. -
这很奇怪!什么发行版和版本?
-
我使用的是 Ubuntu 16.10。我从
gnome-terminal窗口运行who -m -
有趣的是,当我在 gnome-terminal 的 CentOS7 上这样做时,它工作正常。我正在通过远程 x 会话运行 gnome-terminal,让我尝试物理会话。
-
我终于通过
scalar(getpwuid(stat(readlink("/proc/$PID/fd/1"))->uid))完成了这项工作,它消除了对who -m、ENV{$SSH_TTY}和ENV{$USER}的依赖,并避免了对被调用子进程模拟pty 的任何需要。
标签: perl input-buffer