私は決定するための最も効率的な方法を検討しています:
- ユーザー提供のコマンドラインの前にシェル実行可能ファイルを追加する必要がありますか
- はいの場合、その実行可能ファイルは何ですか? (/bin/sh? /usr/bin/perl? /usr/bin/ksh? c:/../cmd.exe?)
Java からシェル スクリプトを開始するには、代わりにシェルを開始する必要があることが知られています。
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "script.sh", "arg1", "arg2);
バイナリを開始するには、バイナリ自体を開始する必要があります。
ProcessBuilder pb = new ProcessBuilder("/path/binary", "arg1", "arg2);
シェルでバイナリを実行すると、次のエラーが発生します。
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "/path/binary", "arg1", "arg2);
(sh: cannot execute binary file)
シェル バイナリなしでシェル スクリプトを実行すると、次のエラーが発生します。
ProcessBuilder pb = new ProcessBuilder("script.sh", "arg1", "arg2);
(error 2: file not found)
アプリケーションがバイナリかスクリプトかを認識できない状況に陥っています。
開始されたアプリケーションは、エンド ユーザーによって提供されるイベント ハンドラです。Unix で実行されるシェル スクリプトである可能性が最も高いです。ただし、Windows では *.cmd である場合もあれば、あいまいなプラットフォームで実行される Perl スクリプトである場合もあります。結局のところ、それは Java です。
私の最初の素朴な試みは、シェルでコマンドラインを開始し、それが機能するかどうかを確認することでした. そうでない場合は、バイナリとして実行してみてください。
これは見苦しく危険です。プラットフォームとシェルの未知の組み合わせでは、2 回目の実行でもスクリプトが実行され、2 回目の結果が予測不能になる可能性があります。
また、スクリプトを開始できなかったときから、スクリプト自体の問題が原因でスクリプトがいつ正常に開始され、失敗したのかわかりません。
私が今考えている最善のことは次のとおりです。
- スクリプトを読み、印刷できないバイトを探します
- 見つかった場合は、バイナリと見なします
- そうでない場合は、/bin/sh (Windows の場合は cmd.exe) を追加します。
何か良い案があればアドバイスお願いします。
更新/部分的な解決
私と考えを共有してくれたすべての人に感謝します。
結局、私は自分自身とインターネットの残りの部分を混乱させました:)
次の場合、ユーザーが入力したコマンド ラインの前に、shall バイナリを追加する必要はありません。
- スクリプトはPATHにあります
- (Unix の場合) スクリプトは実行可能です
- (Unix の場合) スクリプトには #!/path/to/interpreter があります
コードをテストしているときに、これらの条件のいずれかが満たされませんでした。:-(
スクラッチスクリプトから慎重にテストを実行した後、実行されました。
ポイント 3 はユーザーのみが行うことができ、ユーザー マニュアルに記載する必要があります。
これらのスクリプトがターゲット システムに伝達される方法が原因で、スクリプトが実行可能でなく、PATH に含まれていない場合があります。
私が気にする唯一のパスは相対パスなので、相対パスの前に ./ を追加するだけで十分です。
Unix (およびその他のプラットフォーム) でスクリプトを実行可能にすることは、さらに困難です。WORAではありません。その前に /bin/sh を配置すると役立つ場合がありますが、覚えている限り、Solaris のすぐ下では、シェルは実行不可能なスクリプトを実行しません。
今週後半に別の更新を投稿します。