web-dev-qa-db-ja.com

JavaでSudo権限でbashコマンドを実行するにはどうすればよいですか?

ProcessBuilderを使用してbashコマンドを実行しています。

import Java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            Process pb = new ProcessBuilder("gedit").start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

しかし、私はこのようなものを作りたい:

Process pb = new ProcessBuilder("Sudo", "gedit").start();

スーパーユーザーのパスワードをbashに渡す方法は?

("gksudo", "gedit")は、Ubuntu 13.04から削除されたため、トリックを実行しません。デフォルトのコマンドで使用可能にしてこれを行う必要があります。

編集

gksudoは、最後の更新でUbuntu 13.04に戻りました。

24
Vare Zon

あなたはこれを使用できると思いますが、私はそれを投稿することを少しheしています。だから私はちょうど言います:

これは推奨されませんが、私を訴えないなど、自己責任で使用してください...

public static void main(String[] args) throws IOException {

    String[] cmd = {"/bin/bash","-c","echo password| Sudo -S ls"};
    Process pb = Runtime.getRuntime().exec(cmd);

    String line;
    BufferedReader input = new BufferedReader(new InputStreamReader(pb.getInputStream()));
    while ((line = input.readLine()) != null) {
        System.out.println(line);
    }
    input.close();
}
31
Erik Pragt

/ etc/sudoersをvisudoで編集し、特定のスクリプトに対するNOPASSWD権限をユーザーに付与します。

ユーザー名ALL =(ALL)NOPASSWD:/opt/yourscript.sh

12
JointEffort

私のソリューションは、コマンドラインでパスワードを公開せず、プロセスの出力ストリームにパスワードをフィードするだけです。これは、必要なときにユーザーにパスワードを要求できるため、より柔軟なソリューションです。

public static boolean runWithPrivileges() {
    InputStreamReader input;
    OutputStreamWriter output;

    try {
        //Create the process and start it.
        Process pb = new ProcessBuilder(new String[]{"/bin/bash", "-c", "/usr/bin/Sudo -S /bin/cat /etc/sudoers 2>&1"}).start();
        output = new OutputStreamWriter(pb.getOutputStream());
        input = new InputStreamReader(pb.getInputStream());

        int bytes, tryies = 0;
        char buffer[] = new char[1024];
        while ((bytes = input.read(buffer, 0, 1024)) != -1) {
            if(bytes == 0)
                continue;
            //Output the data to console, for debug purposes
            String data = String.valueOf(buffer, 0, bytes);
            System.out.println(data);
            // Check for password request
            if (data.contains("[Sudo] password")) {
                // Here you can request the password to user using JOPtionPane or System.console().readPassword();
                // I'm just hard coding the password, but in real it's not good.
                char password[] = new char[]{'t','e','s','t'};
                output.write(password);
                output.write('\n');
                output.flush();
                // erase password data, to avoid security issues.
                Arrays.fill(password, '\0');
                tryies++;
            }
        }

        return tryies < 3;
    } catch (IOException ex) {
    }

    return false;
}
5
kato2

@jointEffortが答えたように、特にSudo特権を持つユーザーの場合、システムパスワードをファイルに単純に書き込もうとしないでください。発行された特権は、アプリ作成者ではなくシステム管理者が解決する必要があります。 Sudoを使用すると、特定のコマンドに対する特権を特定のユーザーに付与できます。これで十分です。 this post

メイン#includedirs /etc/sudoers.d/ファイルに/etc/sudoersを追加するだけで(ほとんどのLinuxディストリビューションで既に実行されている場合)、ファイルを作成する場合は、メインsudoersファイル以外の別のファイルで特権を管理することもできます。 ifconfig-userのように:

 USER_NAME ALL=(ALL) NOPASSWD: /sbin/ifconfig

もう1つ、構文エラーがあるときにシステムの制御を失った場合に備えて、visudoを使用して構成ファイルを編集することを忘れないでください。

2
armnotstrong

プロセスを生成すると、入力ストリームと出力ストリームを抽出できます。パスワードを出力ストリームに渡すだけです(プロセスの入力にパスワードを出力します)。したがって、コードは次のようになります-

Process pb = new ProcessBuilder("gedit").start();
OutputStream out = pb.getOutputStream();
out.write(password);
1
David Grinberg

私はこれが古いスレッドであることを知っていますが、私はこれをここに置きたいだけです:

processインスタンスを作成するために渡すコマンドとしてSudo -S *command*を使用できます。次に、出力ストリームを取得してパスワードを書き込み、最後に新しい行とcを追加します。リターン(\n\r)。返品は不要かもしれませんが、念のために合格しました。また、ストリームをフラッシュして、すべてが書き込まれていることを確認することをお勧めします。私はそれを数回やったことがあり、それは魅力のように機能します。そして、ストリームを閉じることを忘れないでください:)。

1
mcrius