2

私は簡単なCプログラムを書きました:

#include <unistd.h>
#include <stdio.h>

int main( int argc, char *argv[] ) {
  printf( "%s\n", getlogin() );
  return 0;
}

...いくつかのことを試してみてください。制御端末がないことを確認してgetlogin()を失敗させようとしましたが、それでもログイン名を取得して出力しています。これを実証するための最も極端な例:

#!/bin/bash
for i in $(env | grep -vP ^PATH\\b | awk -F= \{print \$1\}); do
  unset $i;
done;
(tty; perl -e 'setpgrp; sleep( 1 ); exec( qw( getlogin_test ) );' ) &

説明の方法では、PATHを除くすべての環境変数の設定を解除してから、「tty」を実行してからperlインスタンスを実行するサブシェルを実行します。サブシェルは背景になっています。setpgrpを呼び出して、プロセスグループを使用して親の制御端末を見つけていないことを確認します(そうは思わないが、仮定が間違っていた場合に備えて、そこに配置します)。

この時点で、私は途方に暮れています。それでもユーザー名は出力されます。かなりの数のソースから見たより単純な例は、同じ動作をします。

sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' &'
sh -c 'time perl -e '"'"'$|=1; print getlogin(), chr(10);'"'"' & wait'

これらは両方とも、Solaris10とRedhat6の両方で、異なるバージョンのperl、bash、sh、およびtcshを使用してユーザー名を出力します。

4

1 に答える 1

1

STDIN を閉じたり、ファイルにリダイレクトしたりするとうまくいきます。

$ perl -wE'say getlogin()'
eric

$ perl -wE'open STDIN, "<", "/dev/null" or die $!; say getlogin()'
Use of uninitialized value in say at -e line 1.

これは、Debian ボックスで自作の Perl (デフォルト オプション) です。

于 2012-06-21T18:48:55.573 に答える