2016-10-15 22 views
3

現在のgksudoコマンドは、Process.spawn_async_with_pipesで動作します。しかし、pkgxecでgksudoを切り替えると、pkexecウィンドウが表示されず、プロンプトが表示されずにコマンドが直接完了し、何も返されません。spawn非同期プロセスがpkexecで動作しない

同じpkexecコマンドでProcess.spawn_command_line_syncを使用すると、パスワードを尋ねるプロンプトが表示され、コマンドが正常に実行され、結果が返されます。

pkexecを使用する主な理由は、polkitを使用して、root権限を必要とするコマンドを後で使用するようにユーザーに求めないことです。

私のProcess.spawn_async_with_pipesコードのメソッドを以下に示します。

バックグラウンドプロセスとしてpkexecを動作させるにはヘルプが必要です。つまり、プロンプトでguiをブロックする必要がありますが、ユーザーがパスワードを入力すると、GUIに制御を戻してバックグラウンドで実行を続行する必要があります。 gksudoではまさにこれが起こります。

非同期pkexecコマンドの動作を産卵
execute_sync_multiarg_command_pipes({"pkexec", COMMAND_USING_SUDO[6]}); 
+0

いくつかのことを。 LinuxやWindowsを使用していますか?あなたのリンクを確認することができます。それは私のために働いていません。第3に、あなたが参照しているドキュメントが 'spawn_async'のものであるときになぜ' spawn_async_with_pipes'を使用していますか?ちょっと興味があるんだけど。あなたは素晴らしい質問をします。 – oldtechaa

+0

@oldtechaa Windows用のポリシーキットポートはありますか? –

+0

[MVCE](https://stackoverflow.com/help/mcve)(具体的には最小限のコード例)を用意してください。 –

答えて

0

public static int main (string[] args) { 
    MainLoop loop = new MainLoop(); 
    try { 
     string[] spawn_args = {"pkexec", "ls", "-l", "-h"}; 
     string[] spawn_env = Environ.get(); 
     Pid child_pid; 

     Process.spawn_async ("/", 
      spawn_args, 
      spawn_env, 
      SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
      null, 
      out child_pid); 

     ChildWatch.add (child_pid, (pid, status) => { 
      // Triggered when the child indicated by child_pid exits 
      Process.close_pid (pid); 
      loop.quit(); 
     }); 

     loop.run(); 
    } catch (SpawnError e) { 
     stdout.printf ("Error: %s\n", e.message); 
    } 
    return 0; 
} 
事前

おかげでこれはこれは、それが呼び出されている方法である非同期メソッド

public int execute_sync_multiarg_command_pipes(string[] spawn_args) { 
     debug("Starting to execute async command: "+string.joinv(" ", spawn_args)); 
     spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer 
     MainLoop loop = new MainLoop(); 
     try { 
      string[] spawn_env = Environ.get(); 
      Pid child_pid; 

      int standard_input; 
      int standard_output; 
      int standard_error; 

      Process.spawn_async_with_pipes ("/", 
       spawn_args, 
       spawn_env, 
       SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
       null, 
       out child_pid, 
       out standard_input, 
       out standard_output, 
       out standard_error); 

      // capture stdout: 
      IOChannel output = new IOChannel.unix_new (standard_output); 
      output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stdout"); 
      }); 

      // capture stderr: 
      IOChannel error = new IOChannel.unix_new (standard_error); 
      error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stderr"); 
      }); 

      ChildWatch.add (child_pid, (pid, status) => { 
       // Triggered when the child indicated by child_pid exits 
       Process.close_pid (pid); 
       loop.quit(); 
      }); 
      loop.run(); 
     } catch(SpawnError e) { 
      warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message); 
      spawn_async_with_pipes_output.append(e.message); 
     } 
     debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]..."); 
     return 0; 
    }` 

です

p romptが立ち上がり、結果として得られるファイルのリストは、私の "/ root"ディレクトリのものです。

したがって、問題は別の場所にある必要があります。

また、パイプで動作します:

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) { 
    if (condition == IOCondition.HUP) { 
     stdout.printf ("%s: The fd has been closed.\n", stream_name); 
     return false; 
    } 

    try { 
     string line; 
     channel.read_line (out line, null, null); 
     stdout.printf ("%s: %s", stream_name, line); 
    } catch (IOChannelError e) { 
     stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message); 
     return false; 
    } catch (ConvertError e) { 
     stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message); 
     return false; 
    } 

    return true; 
} 

public static int main (string[] args) { 
    MainLoop loop = new MainLoop(); 
    try { 
     string[] spawn_args = {"pkexec", "ls", "-l", "-h"}; 
     string[] spawn_env = Environ.get(); 
     Pid child_pid; 

     int standard_input; 
     int standard_output; 
     int standard_error; 

     Process.spawn_async_with_pipes ("/", 
      spawn_args, 
      spawn_env, 
      SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
      null, 
      out child_pid, 
      out standard_input, 
      out standard_output, 
      out standard_error); 

     // stdout: 
     IOChannel output = new IOChannel.unix_new (standard_output); 
     output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
      return process_line (channel, condition, "stdout"); 
     }); 

     // stderr: 
     IOChannel error = new IOChannel.unix_new (standard_error); 
     error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
      return process_line (channel, condition, "stderr"); 
     }); 

     ChildWatch.add (child_pid, (pid, status) => { 
      // Triggered when the child indicated by child_pid exits 
      Process.close_pid (pid); 
      loop.quit(); 
     }); 

     loop.run(); 
    } catch (SpawnError e) { 
     stdout.printf ("Error: %s\n", e.message); 
    } 
    return 0; 
} 

これでも(今あなたの例のコードの断片を含む)は動作します:

StringBuilder spawn_async_with_pipes_output; 

private static bool process_line (IOChannel channel, IOCondition condition, string stream_name) { 
    if (condition == IOCondition.HUP) { 
     stdout.printf ("%s: The fd has been closed.\n", stream_name); 
     return false; 
    } 

    try { 
     string line; 
     channel.read_line (out line, null, null); 
     stdout.printf ("%s: %s", stream_name, line); 
    } catch (IOChannelError e) { 
     stdout.printf ("%s: IOChannelError: %s\n", stream_name, e.message); 
     return false; 
    } catch (ConvertError e) { 
     stdout.printf ("%s: ConvertError: %s\n", stream_name, e.message); 
     return false; 
    } 

    return true; 
} 

public int execute_sync_multiarg_command_pipes(string[] spawn_args) { 
     debug("Starting to execute async command: "+string.joinv(" ", spawn_args)); 
     spawn_async_with_pipes_output.erase(0, -1); //clear the output buffer 
     MainLoop loop = new MainLoop(); 
     try { 
      string[] spawn_env = Environ.get(); 
      Pid child_pid; 

      int standard_input; 
      int standard_output; 
      int standard_error; 

      Process.spawn_async_with_pipes ("/", 
       spawn_args, 
       spawn_env, 
       SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, 
       null, 
       out child_pid, 
       out standard_input, 
       out standard_output, 
       out standard_error); 

      // capture stdout: 
      IOChannel output = new IOChannel.unix_new (standard_output); 
      output.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stdout"); 
      }); 

      // capture stderr: 
      IOChannel error = new IOChannel.unix_new (standard_error); 
      error.add_watch (IOCondition.IN | IOCondition.HUP, (channel, condition) => { 
       return process_line (channel, condition, "stderr"); 
      }); 

      ChildWatch.add (child_pid, (pid, status) => { 
       // Triggered when the child indicated by child_pid exits 
       Process.close_pid (pid); 
       loop.quit(); 
      }); 
      loop.run(); 
     } catch(SpawnError e) { 
      warning("Failure in executing async command ["+string.joinv(" ", spawn_args)+"] : "+e.message); 
      spawn_async_with_pipes_output.append(e.message); 
     } 
     debug("Completed executing async command["+string.joinv(" ", spawn_args)+"]..."); 
     return 0; 
    } 

public static int main (string[] args) { 
    spawn_async_with_pipes_output = new StringBuilder(); 
    execute_sync_multiarg_command_pipes ({"pkexec", "ls", "-l", "-h"}); 
    return 0; 
} 
+0

多くのありがとう。私のコードはいつも働いていました。私はexecute_sync_multiarg_command_pipesメソッドを間違って呼び出していました!私は上記のあなたの答えを受け入れました。完全な例であるので、非同期メソッドを使用しようとする人に役立つかもしれません –

関連する問題