JavaからWindowsのコマンドプロンプトを呼び出して、
ファイルコピーは実施したことありましたが、
現場の実作業でLinuxのシェルを呼び出して欲しいと言われました。
普通はナイナイと話していたのに実際にあるとは驚きました。
自宅で試してみました。
-
呼ばれる側
cat /home/ユーザ名/java/シェル名.sh #!/bin/sh echo "Hellow World !!" cd aaaa
標準出力とエラー出力の両方があった場合を試したかったので、
わざと存在しないディレクトリに移動しています。
実行権限をつけておきます。chmod -x シェル名
-
呼び出し側
/** * メイン処理 * @param args 引数 */ public static void main(String[] args) { ArrayList<String> cmd = new ArrayList<String>(); cmd.add("/home/ユーザ名/java/シェル名.sh"); try { ProcessBuilder processBuilder = new ProcessBuilder(cmd); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); InputStream inputStream = process.getInputStream(); printInputStream(inputStream); System.out.println(process.waitFor()); } catch (Exception e) { e.printStackTrace(); } } /** * 入力ストリームの内容を出力する。 * @param inputStream 入力ストリーム * @throws IOException [入出力エラーが発生した場合] */ public static void printInputStream(InputStream inputStream) throws IOException { try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));) { for (;;) { String line = bufferedReader.readLine(); if (line == null) { break; } System.out.println(line); } } }
-
実行結果
javac クラス名.java java クラス名
Hellow World !! /home/ユーザ名/java/シェル名.sh: line 3: cd: aaa: そのようなファイルやディレクトリはありません 1
ProcessBuilderクラスのredirectErrorStreamをtrueにしたので、
標準出力とエラー出力が同時に出力されています。
ただしこのバッファは1024バイトまでらしいです。
⇒echoで1050バイトほど出力するようなシェルにしてみましたが、
出力できてしまいました。謎です。また、異常終了したので戻り値も「1」になっています。
-
恥ずかしながらはまったこと
シェル名.shをWindowsで作成していたため、改行コードがCRLFのままでした。
改行コードがCRLFのままシェルを実行すると、下記エラーが出力されます。-bash: ./シェル名.sh: /bin/bash^M: bad interpreter: そのようなファイルやディレクトリはありません
「^M」が出ているのがわかります。
sedコマンドでLFに置換しました。sed -i 's/r//' /home/ユーザ名/java/シェル名.sh