2016-05-23 8 views
8

javafxのアプリケーションで作業していますが、ターミナルでコマンドを使用してアプリケーションを開こうとしています。私のjavaコードを使用してコマンドを実行しています。ビルダーが更新されるときにファイル名が異なる可能性があるため、常に同じではないインストーラファイルの名前です。
ここに私が実行している正確なコマンドではないが、コマンドフォーマットは同じであるというコマンドをどのように実行しているかのサンプルがあります。JavaでOS Xのsudoコマンドを実行するには

Process process = Runtime.getRuntime().exec("echo password | sudo -S open -a safari"); 
    String line; 
    BufferedReader input = new BufferedReader(new InputStreamReader(pb.getInputStream())); 
    while ((line = input.readLine()) != null) { 
     System.out.println(line); 
    } 
    input.close(); 

このプロセスでは出力が停止し、何も起こりません。 私は同じコマンドをターミナルから試してみましたが、うまくいきます。

は、私は物事がこのリンク

How to execute bash command with sudo privileges in Java?

に言及しようとしたが、それはまた働いていませんでした。

私はまた、これらのコマンドがうまく動作する私のJavaコードから "chmod + x"のようなコマンドを実行しています。 私の元のコマンドは次のようになります - )a.getAbsolutePathは()インストーラファイルとb.getAbsolutePath(のパスです

runCommand = "echo" + " " + password + "| sudo -S " + "\"" + a.getAbsolutePath() + "\"" + " --deploymentFile=" 
          + "\"" + b.getAbsolutePath() + "\""; 

我々はアプリケーションをインストールするために使用される配布ファイルのパスです。

pb.getInputStream() 

は、コマンドを印刷し、私はコピーして貼り付けるとき、正常に動作の端末です。

pb.getErrorStream() 

は何も与えません。

私はここに私はエラー

getErrorStreamusage: sudo -h | -K | -k | -L | -V 
getErrorStreamusage: sudo -v [-AknS] [-g groupname|#gid] [-p prompt] [-u user name|#uid] 
getErrorStreamusage: sudo -l[l] [-AknS] [-g groupname|#gid] [-p prompt] [-U user name] [-u 
getErrorStream   user name|#uid] [-g groupname|#gid] [command] 
getErrorStreamusage: sudo [-AbEHknPS] [-C fd] [-g groupname|#gid] [-p prompt] [-u user 
getErrorStream   name|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [<command>] 
getErrorStreamusage: sudo -e [-AknS] [-C fd] [-g groupname|#gid] [-p prompt] [-u user 
getErrorStream   name|#uid] file ... 
+0

なぜ 'echo tester'を実行しますか?また、 '-S'は必要ありません。単純な' sudo open -a safari'で十分です。 – fedorqui

+0

実際にテスターはシステムのパスワードです、私はパスワードでコマンドを実行する必要があります。 sudoにはパスワードが必要ではありません。 – user3649361

+1

'tester'がパスワードであれば、' echo'はアイデアの中で最も安全なものではないかもしれません... – Arc676

答えて

3

次しまった

String[] cmd = {"/bin/bash","-c","echo tester| sudo -S ","\"",a.getAbsolutePath(),"\"","\""," --deploymentFile=","\"",b.getAbsolutePath()}; 

とも

String[] cmd = {"/bin/bash","-c","echo tester| sudo -S",a.getAbsolutePath(),"--deploymentFile=","\"",b.getAbsolutePath()}; 

を実行しようとした私は、あなたがアプリケーションへの完全なパスを使用しなければならないと思います。これは動作するはずです:

Runtime rt = Runtime.getRuntime(); 
rt.exec("echo password | sudo -S open -a /Applications/Safari.app"); 

を更新:あなたのコメントに基づいて

あなたがプロセスを分割しようとすることができます。チャンスは、openがインタラクティブなセッションを必要とすることが良いです。

Safariをユーザーとして開くスクリプト(openSafari.shなど)を作成します。

#!/etc/bash 
echo $1 | sudo -S open -a /Applications/Safari.app & 

それを実行可能にします。chmod +x openSafari.sh、およびJavaからそのスクリプトを呼び出します。

Runtime rt = Runtime.getRuntime(); 
rt.exec("/pathTo/openSafari.sh 'sudoPassword'"); 
+0

これはまた、 "ditto -xkV" + filepathwos + "" + outputPathのようなコマンドでは動作しません。問題なく動作していますが、アプリを起動する必要のあるコマンドは機能していないようです。 – user3649361

+0

myコマンドにはいくつかの変数があります。safariはビルドが更新されたときにファイル名が異なる可能性があるため、インストーラファイルのパスは常に同じではありません。 – user3649361

10

sudoの

私は強くsudoersファイルを編集して、パスワードの入力を求める代わりにecho passwd | sudo ...工事を行わずにsudo経由で特定のコマンドを使用するようにアプリケーションを実行しているユーザーを許可することをお勧めしたいです。

そのように、あなたは、アプリケーションまたは構成ファイルでクリアな(あるいはせいぜいわずか難読化)でパスワードを保存しないように、そしてあなたは、などのsudo呼び出すシェルスクリプトでシェルを呼び出す必要があり、

を避けますSudoersはコマンドvisudoで編集できます。ここでは、unbuntuでどのように行われているかを例として示していますが、unixでは同じです。 https://askubuntu.com/questions/159007/how-do-i-run-specific-sudo-commands-without-a-password

追加参照:https://www.sudo.ws/man/1.8.16/sudoers.man.html

私はあなたが...しかし、その操作を実行する必要があるMacアプリケーションで

Mac上の許可

を間違った質問をしていると思います追加の権利が必要なのは、sudoを使って始めるべきではありません。

アプリは代わりに認証サービスを使用することになっています。

参照:

+1

Javaについては何もしていません。 – Andremoniy

+0

私はjavaを介してそれを実行することができますし、私は別のシステムでこのアプリケーションを実行するために必要なもう一つのことは、私はそれを行うことができるでしょうか? – user3649361

+0

私は、あなたがやっているようなことをsudoに焦点を当てるのではなく、Mac上で認証サービスを使うことに目を向けるべきだと思います。 (これを指し示すために上記を編集してください) – swa66

4

私はこれを行うことをお勧めしませう - あなたは何か:)

を破るしかし、あなたが求めていることで達成できるのであれば私に叫ぶません:

String[] cmd = {"/bin/bash","-c","echo password | sudo -S open -a <path to app>"}; 
Process pb = Runtime.getRuntime().exec(cmd); 
3

Runtime.exec()メソッドを実行コマンドを直接で実行します。シェル経由ではありません。使用している特定のオーバーロードは、空白でコマンドをトークン化し、結果のトークンをコマンド名と引数として解釈します。あなたの呼び出しで実行されるコマンドのみ...

Runtime.getRuntime().exec("echo password | sudo -S open -a safari"); 

は...したがって、echoです。それ以外はすべて議論です。結果は、プロセスの標準出力に次のように出力されます。

パスワード| sudoの-Sオープン-aサファリ


あなたが望むように見えるものを達成するためにいくつかの方法は、少なくともあります。あなたの元のコードの最も簡単な変更は、おそらくあなたは、あなたが明示的にコマンドを実行するには、シェルを起動することにより、取得したと思ったものを実現し

Process process = Runtime.getRuntime().exec(
     new String[] { "bash", "-c", "echo password | sudo -S open -a safari" }); 

だろう。パスワードは、プロセスリストにプレーンテキストで表示されますので、

は、しかし、それは、かなりのセキュリティ上のリスクです。代わりに、直接パスワードでJavaプログラムフィードを持ち、その後もbashが関与避けることができます。

Process process = Runtime.getRuntime().exec("/usr/bin/sudo -S open -a safari"); 
Writer toSudo = new OutputStreamWriter(process.getOutputStream()); 
String password = "password"; 

toSudo.write(password); 
toSudo.write('\n'); // sudo's docs demand a newline after the password 
toSudo.close();  // but closing the stream might be sufficient 

その他の考慮事項:

  • sudoコマンドへのフルパスを与えることが賢明ですパス内で最初に見つかった別のsudoを実行しないようにします。権限のあるアカウントにパスワードを渡すので、悪質なプログラムを実行する可能性を最小限に抑えることが重要です。

  • また、プログラムや設定ファイルにパスワードを保存しないようにするのが賢明だろう。従って、パスワードをsudoに送ることを含む解決策は、ユーザから対話的にパスワードを入力することを含むべきである。

  • セキュリティを意識したJavaプログラムでは、パスワードがStringではなくcharの配列に保存されることが多いため、不要になったときに積極的に拭き取ることができます。 Stringは変更できません。また、VM内で無期限にハングアップする可能性があります(他の多くのオブジェクトよりもさらに多くの場合)。

  • 一般的に言えば、コンテンツの内容に関係なく、Processの入力ストリームとエラーストリームを同時に排除する必要があります。そうしないと、外部プロセスがブロックされたり終了したりすることがあります。私はそれが普通それらのストリーム上の任意の出力を生成しないと思うので、それは、しかし、おそらく特にsafariの問題ではありません。

0

多分あなたは、あなたがプロセスのJONボリンジャーを使用しているどのように修正してマチェイをすることをを組み合わせたプロセス呼び出し

内SUDO_PROMPTの的環境変数を設定することができ、この

How to setup a SUDO_ASKPASS environment variable?

を使用等が言及している。

は、その後、あなたのユーザーのパスワード・プロンプトを起動している必要があり、あるいはその中にあなたの資格情報で、PKIにアクセスします。あなたがpkiのために行くならば、少なくとも神の愛のためにそれを暗号化してください)

あなたがこれは他のマシンで実行することを意味していると言いますように、それは基本的におっしゃるuacプロンプトになります非常にマック/ Linuxのソリューションのように聞こえる。 swa66が最善の方法ですが、これはすばやく汚れてしまいます。

関連する問題