2

最終的にphpのshell_exec機能を使用して新しいLinuxユーザーを作成しようとしています。ただし、デバッグでも問題が発生しています。これが私のコードです

<?PHP 

function adduser($username,$password,$server){ 
    try{
        //3 debug statements
        $output=shell_exec("pwd"); 
        echo $output;
       shell_exec("touch test.txt");

        //3 debug statements are requested by Christian
        echo '<pre>';
        print_r(execute('pwd'));
        print_r(execute('touch test.txt'));

        //actuall code
        $output=shell_exec("ssh root@$server \"adduser $username; echo $password | passwd $username --stdin\"");
    }
    catch(Exception $e){
        echo 'could not add user '.$e->getMessage();
    }
} 

$servers = array('192.168.1.8'); 

foreach($servers as $server){ 
    echo $_GET['USER']."   ".$_GET['PASSWORD'];
    adduser($_GET['USER'],$_GET['PASSWORD'],$server); 
}

try-catchステートメントは何もしないので、シェル エラーは PHP エラーとして伝播されないと思います (Python もこの方法です) 。行$output=shell_exec("pwd")は正しいディレクトリを返します。ただし、行shell_exec("touch test.txt")はファイルtest.txtの作成に失敗します(フルパス「/home/user/.../test.txt」を指定しても)。

言うまでもなく、ユーザーを追加するための実際のコードも機能しません。

編集私はコードのいくつかを修正することができました。このtouch test.txtエラーは、権限が不十分であることが原因でした。Apache はユーザー www-data でログインします。私は単純にそのユーザーのホーム フォルダーを作成し、そのホーム フォルダー内のファイルに触れるようにしました。

ただし、Christian の要求による 3 つのデバッグ ステートメントの追加は、現在問題を引き起こしています。

編集さらに調査すると、ユーザーwww-dataとしてログインするときにルートとしてsshできないことに関係しています。ssh -v戻りますdebug1: read_passphrase: can't open /dev/tty: No such device or address。私の推測では、ssh は一般的な「xxx を known_hosts に永続的に追加しますか」と尋ねていますが、応答できません。ユーザーを既知のホスト リストに手動で追加する方法はありますか?

4

2 に答える 2

1
  • PHP の内部関数の多く (ほとんど?) は例外をスローせず、エラーを発生させます。例外がスローされることはないと思いますshell_exec()
  • 返された値を明示的に認識できるようにするために、戻り値を var_dump() する場合があります。
  • 入力の問題を回避するために、escapeshellarg()などの関数を調べることもお勧めします。

一般的なケースとして、PHP にいくつかのコマンドを順番に実行させるのではなく、必要なすべてを実行するシェル スクリプトを作成し、PHP から呼び出します。デバッグ時にチェーン内のリンクが 1 つ少なくなり、はるかに簡単になりました。

SSH コマンド自体に関しては、apache が として実行されwww-dataているため、問題のマシンに root としてどのようにログインしていますか? Apache ユーザーのキーをリモート マシンに追加しましたか。

于 2011-04-18T00:13:20.283 に答える
1

ここにある私の機能を使用してください。

次のコードを実行して、その出力を教えてください。

echo '<pre>';
print_r(execute('pwd'));
print_r(execute('touch test.txt'));

編集:私のスクリプトをよりOO指向にしたい場合:

function execute_o($cmd,$in){
    $out=execute($cmd,$in);
    if($out['return']!=0)
        throw new Exception('Error '.$out['return'].': '.$out['stderr'].'.');
}
于 2011-04-18T00:40:12.423 に答える