【Java】Javaからシェル呼び出し

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
    

【Eclipse】Eclipse再設定

Eclipseで色々いじりすぎて復元できなくなった場合の再設定メモ。

EclipseはIndigoの3.7.2を利用しています。

  • 壊れたEclipse
    【モジュール】
    EclipseのworkplaceディレクトリからSVN管理されていないプロジェクトをコピーしてどこかに保存する。

    【設定】
    「ファイル」-「エクスポート」を選択する。
    「一般」-「設定」を選択し、「次へ」ボタンを押下する。
    全てをエクスポートにチェックを入れ、「宛先設定ファイル」を指定し、「完了」ボタンを押下する。

  • 新しいEclipse
    【モジュール】
    どこかにコピーしておいたプロジェクトを新しいworkplaceに配置。
    「ファイル」-「インポート」を選択する。
    「一般」-「既存プロジェクトをワークスペースへ」を選択し、「次へ」ボタンを押下する。
    ルート・ディレクトリの選択にチェックを入れ、プロジェクトを選択し、「完了」ボタンを押下する。
    SVN管理されているプロジェクトはチェックアウトする。

    【設定】
    「ファイル」-「インポート」を選択する。
    「一般」-「設定」を選択し、「次へ」ボタンを押下する。
    ソース設定ファイルを選択し、「完了」ボタンを押下する。

【Oracle】SQLPlusで空白除去

OracleのSQLPlusでSELECT結果をspoolでファイル出力した際、
CHAR型やVARCHAR2型の出力結果がサイズにあうように自動で空白埋めされてしまい、
想定結果ととても比較し難い。

「SET TRIMSPOOL ON」にしても空白が削除されないのは、
これが「行末のトリム処理を制御する」からのようです。
「項目ごとのトリム処理を制御する」なら便利だったのに。

色々調べてもSQLPlusの設定だけでやるのは無理なようで、
結局下記のようにパイプでつなげることにしました。

SELECT 項目1 || 't' || 項目2 || 't' || 項目3 FROM テーブル名;

TeraTeramで自動ログイン

TeraTermで接続情報を毎回手打ちして、
ログインするのが面倒なので、自動ログインします。

デスクトップでも好きな場所に「ファイル名.ttl」ファイルを作成します。
ファイルが「ttpmacro.exe」に関連付けられていない場合、
TeraTermのインストールディレクトリに存在する「ttpmacro.exe」に関連付けを行います。

ファイルの中身を記載します。

hostname = 'IPアドレスまたはホスト名'
username = 'ユーザ名'
passfile = 'D:/任意のディレクトリ/任意のファイル名'
keyfile = 'D:/任意のディレクトリ/秘密鍵のファイル名'

getpassword passfile username userpass

command = hostname
strconcat command ':22 /ssh /KR=UTF-8 /KT=UTF-8 /auth=publickey /user='
strconcat command username
strconcat command ' /passwd='
strconcat command userpass
strconcat command ' /keyfile='
strconcat command keyfile

connect command

end

初回ログインで1度パスワードを聞かれますが、
2回目からはファイルを自動参照します。

【bat】WinBatで自動ログイン

ファイルサーバにログインする際、接続情報を毎回手打ちして、
ログインするのが面倒なので、自動ログインします。

デスクトップでも好きな場所に「ファイル名.bat」ファイルを作成します。

ファイルの中身を記載します。

@echo off
SET COMMON_USR=ユーザ名
SET COMMON_PASS=パスワード

echo ホスト名ログイン中
net use ホスト名/ディレクトリ名 /USER:%COMMON_USR% %COMMON_PASS%

pause

接続できない場合、接続情報が残ってしまっていることがあるので、
コマンドプロンプト上で下記コマンドで削除します。

net use ホスト名/ディレクトリ名 /delete

【Excel】ショートカット割り当て

Excelで自作マクロの起動をショートカットで行います。

Sub AssignShortCutKey()
'
' AssignShortCutKye Macro
'
' ショートカットを割り当てる。
    
    ' F1:何もしない
    Application.OnKey "{F1}", ""

    ' CTRL+ALT+l:メニューオープン
    Application.OnKey "^%{l}", "MenuOpen"

    ' CTRL+t:カーソルトップ
    Application.OnKey "^{t}", "TopCursor"

    ' CTRL+r:赤い太枠四角線
    Application.OnKey "^{r}", "RedBox"

    ' CTRL+ALT+s:SELECT文作成
    Application.OnKey "^%{s}", "SqlSelectCreateYoko"
End Sub

【Excel】VBAフォーム表示

先ほど作成したVBAフォームはマクロで起動できるようにしておきます。

Sub MenuOpen()
'
' MenuOpen Macro
'
' メニューをオープンします。

    フォーム名.Show (vbModeless)

End Sub

【Excel】VBAフォーム追加

Excelで自作マクロの起動をフォームから行います。
まずはフォームを追加します。

VBAエディタを開き、左メニューの「VBAProject」-「フォーム」で右クリックし、
「挿入」-「ユーザーフォーム」を選択します。
後はボタンをGUIで配置します。
配置後にボタンやラジオ

次に追加したフォームで右クリックし、「コードを表示」を選択し、
コード上でボタンイベントで起動したいマクロを指定します。

Private Sub PageSettingModCall_Click()
    Call PageSetting
End Sub

Private Sub SqlInsertCreateModCall_Click()
    Call SqlInsertCreate
End Sub

【Excel】選択範囲のセル書式変更

選択範囲のセル書式を変更します。

Sub TblColColor()
'
' TblColColor Macro
'
' テーブル名の項目名を色付けします。
'

    '選択範囲を色づけする。
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 13434828
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With

    '選択範囲を折り返し表示する。
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 13434828
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With

    '選択範囲を太字にする。
    Selection.Font.Bold = True

End Sub