java 回転コマンドの作成

# まえがき

javaコマンドで回転コマンド作成した。

# 参考文献

https://blog.no42.org/code/docker-java-signals-pid1/

https://qiita.com/munieru_jp/items/02533ebe5c822e6e29bb

https://docs.oracle.com/javase/jp/8/docs/api/java/util/Scanner.html

https://stackoverflow.com/questions/1216172/how-can-i-intercept-ctrlc-in-a-cli-application

# 環境

```bash
$java --version
openjdk 13 2019-09-17
OpenJDK Runtime Environment (build 13+33)
OpenJDK 64-Bit Server VM (build 13+33, mixed mode, sharing)
$bash --version
GNU bash, バージョン 5.0.0(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$jshell --version
jshell 13
```

# スクリプト

## 1.Left_Stair.java

先頭要素取得して末尾要素に追加していくパターン。

```java
import sun.misc.Signal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Left_Stair {
    public static void main(String[] rsv_args) {
        trap(new String[]{"INT"});
        try{
            if(rsv_args.length==0){
                //via pipe args
                Scanner stdin=new Scanner(System.in);
                List<String> liz = new ArrayList<>(Arrays.asList(stdin.nextLine().split(" ")));
                circle(liz);
                stdin.close();
            }else{
                //via cmdline args
                List<String> liz = new ArrayList<>(Arrays.asList(rsv_args));
                circle(liz);
            }
        }catch(Exception e){
            usage();
            e.printStackTrace();
            System.exit(1);
        }
    }
    private static void circle(List<String> rsv_liz){
        for (int ind=0;ind<rsv_liz.size();ind++){
            String ele=rsv_liz.get(0);
            rsv_liz.remove(rsv_liz.indexOf(ele));
            rsv_liz.add(rsv_liz.size(),ele);
            System.out.println(rsv_liz);
        }
    }
    private static void trap(String[] sig_args){
        for (String sig:sig_args) {
            catch_sig(sig);
        }
    }
    private static void usage() {
        final String className = new Object(){}.getClass().getEnclosingClass().getName();
        System.out.println("\nUsage:\n" +
                "$echo {a..c} | java "+ className +"\n"+
                "$java "+ className +" {a..c}"+"\n"+
                "$java "+className +"$(echo -e '\\U1f4a'{0..9})\n"+
                "$echo -e '\\U1f4a'{0..9} | java "+className+"\n"
        );
        System.exit(1);
    }
    private static void catch_sig(String sig) {
        Signal signal = new Signal(sig);
        Signal.handle(signal, Signal -> {
            if ("INT".equals(signal.getName())) {
                usage();
            }
        });
    }
}
```

先頭要素が次の対象行の末尾要素に追加されていく様子がわかる。


```bash
$echo -e '\U1f4a'{0..9} | java Left_Stair.java
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]
```

コンパイル事前にしなくても行けるぽい。コンパイルしたときと比べてちょっと時間かかっている。

```bash
$time echo -e '\U1f4a'{0..9} | java Left_Stair.java
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]

real	0m0.414s
user	0m1.058s
sys	0m0.098s

```

コンパイル。警告でる。

```bash
$javac Left_Stair.java
Left_Stair.java:1: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
import sun.misc.Signal;
               ^
Left_Stair.java:57: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal signal = new Signal(sig);
        ^
Left_Stair.java:57: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal signal = new Signal(sig);
                            ^
Left_Stair.java:58: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal.handle(signal, Signal -> {
        ^
警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
警告5個
```

コンパイルしておいたほうがちょっと早くなった。

```bash
$time echo -e '\U1f4a'{0..9} | java Left_Stair
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]

real	0m0.069s
user	0m0.061s
sys	0m0.025s
```

javacコマンドに警告サプレスするオプションあるけど、ミュートできなかった。標準エラー出力を捨てたら、ミュートできた。

```bash
$javac -nowarn Left_Stair.java
Left_Stair.java:1: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
import sun.misc.Signal;
               ^
Left_Stair.java:57: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal signal = new Signal(sig);
        ^
Left_Stair.java:57: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal signal = new Signal(sig);
                            ^
Left_Stair.java:58: 警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
        Signal.handle(signal, Signal -> {
        ^
警告:Signalは内部所有のAPIであり、今後のリリースで削除される可能性があります
警告5個
```

```bash
$javac -nowarn Left_Stair.java 2>/dev/null
```

## 2.Right_Stair.java

末尾要素取得して先頭要素に追加していくパターン。

```java
import sun.misc.Signal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Right_Stair {
    public static void main(String[] rsv_args) {
        trap(new String[]{"INT"});
        try{
            if(rsv_args.length==0){
                //via pipe args
                Scanner stdin=new Scanner(System.in);
                List<String> liz = new ArrayList<>(Arrays.asList(stdin.nextLine().split(" ")));
                circle(liz);
                stdin.close();
            }else{
                //via cmdline args
                List<String> liz = new ArrayList<>(Arrays.asList(rsv_args));
                circle(liz);
            }
        }catch(Exception e){
            usage();
            e.printStackTrace();
            System.exit(1);
        }
    }
    private static void circle(List<String> rsv_liz){
        for (int ind=0;ind<rsv_liz.size();ind++){
            String ele=rsv_liz.get(rsv_liz.size()-1);
            rsv_liz.remove(rsv_liz.indexOf(ele));
            rsv_liz.add(0,ele);
            System.out.println(rsv_liz);
        }
    }
    private static void trap(String[] sig_args){
        for (String sig:sig_args) {
            catch_sig(sig);
        }
    }
    private static void usage() {
        final String className = new Object(){}.getClass().getEnclosingClass().getName();
        System.out.println("\nUsage:\n" +
                "$echo {a..c} | java "+ className +"\n"+
                "$java "+ className +" {a..c}"+"\n"+
                "$java "+className +"$(echo -e '\\U1f4a'{0..9})\n"+
                "$echo -e '\\U1f4a'{0..9} | java "+className+"\n"
        );
        System.exit(1);
    }
    private static void catch_sig(String sig) {
        Signal signal = new Signal(sig);
        Signal.handle(signal, Signal -> {
            if ("INT".equals(signal.getName())) {
                usage();
            }
        });
    }
}
```

末尾要素が先頭要素に追加されていく様子がわかる。

```bash
$time echo -e '\U1f4a'{0..9} | java Right_Stair
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]

real	0m0.059s
user	0m0.063s
sys	0m0.026s
```

## 3.square.sh

上記スクリプトをそれぞれ左と右、右と左に並びて、与える引数を正順と逆順の2つにしたパターン。

```bash
#!/bin/bash

usage(){
  cat <<EOF
Usage:
\$$0 \$(echo -e '\U1f4a'{0..9})
\$$0 '\U1f4a'{0..9}
\$echo -e '\U1f4a'{0..9} | $0
\$seq 10 | xargs -n4 | $0
EOF
  exit 1
}

chk_single_row(){
  #単一行チェック
  local CNT=0
  while read ln;do
    [ $(echo $ln | grep -c "0a") -eq 1 ] && CNT=$((CNT + 1))
  done < <(echo "$@" | xxd -ps -c1)
  [ $CNT -gt 1 ] || echo 0
  [ $CNT -gt 1 ] && echo 1
}

chk_argc(){
  #引数個数チェック
  declare -a argv=()
  local argv=($@)
  local argc="${#argv[@]}"
  [ "${argc}" -le 1 ] && usage && exit 1
}

single_circle(){
  local rsv_args="$@";
  #単一行の場合
  while read ln;do
    paste -d' ' <(echo "${ln}" | java Left_Stair.java) <(echo "${ln}" | rev | java Right_Stair.java)
    paste -d' ' <(echo "${ln}" | java Right_Stair.java) <(echo "${ln}" | rev | java Left_Stair.java)
  done <<<"${rsv_args}"
  exit 0
}

multip_circle(){
  local rsv_args="$@";
  #複数行の場合
  while read ln;do
    paste -d' ' <(echo "${ln}" | java Left_Stair.java) <(echo "${ln}" | tac | java Right_Stair.java)
    paste -d' ' <(echo "${ln}" | java Right_Stair.java) <(echo "${ln}" | tac | java Left_Stair.java)
  done <<<"${rsv_args}"
  exit 0
}

main(){
  local init_args="$(cat -)";
  chk_argc "${init_args}"
  ret=$(chk_single_row "${init_args}")
  [ $ret -eq 0 ] && single_circle "${init_args}"
  [ $ret -eq 1 ] && multip_circle "${init_args}"
}

[ -p /dev/stdin ] && cat - | main
[ -p /dev/stdin ] || echo -ne "$@" | main

```

きれいだ。

```bash
$echo -e '\U1f4a'{0..9} | ./square.sh
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠] [💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡] [💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢] [💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣] [💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤] [💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥] [💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦] [💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧] [💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨] [💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩] [💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨] [💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧] [💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦] [💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥] [💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤] [💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣] [💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢] [💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡] [💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢]
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠] [💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩] [💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠]
```

# あとがき

ひっさしぶりにjava書いた。いろいろ変わって来てるんだなー。面白い機能ないか探していこ。
以上、ありがとうございました。

これもできる。

```bash
$echo -e '\U1f4a'{0..9}>input
$cat input
💠 💡 💢 💣 💤 💥 💦 💧 💨 💩
$cat input | ./square.sh 
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠] [💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡] [💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢] [💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣] [💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤] [💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥] [💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦] [💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧] [💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨] [💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩] [💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨] [💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧] [💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦] [💦, 💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥] [💥, 💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤] [💤, 💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣] [💣, 💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢] [💢, 💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡] [💡, 💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢]
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠] [💠, 💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩] [💩, 💨, 💧, 💦, 💥, 💤, 💣, 💢, 💡, 💠]
```

ちょっとたのしい。^^

```bash
$seq 3 | ./square.sh 
[1] [1]
[1] [1]
[2] [2]
[2] [2]
[3] [3]
[3] [3]
$seq 10 | xargs -n3 | ./square.sh 
[2, 3, 1] [3, 1, 2]
[3, 1, 2] [2, 3, 1]
[1, 2, 3] [1, 2, 3]
[3, 1, 2] [2, 3, 1]
[2, 3, 1] [3, 1, 2]
[1, 2, 3] [1, 2, 3]
[5, 6, 4] [6, 4, 5]
[6, 4, 5] [5, 6, 4]
[4, 5, 6] [4, 5, 6]
[6, 4, 5] [5, 6, 4]
[5, 6, 4] [6, 4, 5]
[4, 5, 6] [4, 5, 6]
[8, 9, 7] [9, 7, 8]
[9, 7, 8] [8, 9, 7]
[7, 8, 9] [7, 8, 9]
[9, 7, 8] [8, 9, 7]
[8, 9, 7] [9, 7, 8]
[7, 8, 9] [7, 8, 9]
[10] [10]
[10] [10]
```

# 20191116追記

コメント頂いた方からの追記

```java
private static void circle(List<String> rsv_liz){
	for (int ind=0;ind<rsv_liz.size();ind++){
	    Collections.rotate(rsv_liz, -1);
	    System.out.println(rsv_liz);
	}
}
private static void circle(List<String> rsv_liz){
    for (int ind=0;ind<rsv_liz.size();ind++){
        Collections.rotate(rsv_liz, 1);
        System.out.println(rsv_liz);
    }
}
```

## Rotate.java

```java
import sun.misc.Signal;

import java.util.*;

public class Rotate {
    public static void main(String[] rsv_args) {
        trap(new String[]{"INT"});
        try{
            if(rsv_args.length==0){
                //via pipe args
                Scanner stdin=new Scanner(System.in);
                List<String> liz = new ArrayList<>(Arrays.asList(stdin.nextLine().split(" ")));
                circle(liz);
                stdin.close();
            }else{
                //via cmdline args
                List<String> liz = new ArrayList<>(Arrays.asList(rsv_args));
                circle(liz);
            }
        }catch(Exception e){
            e.printStackTrace();
            System.exit(0);
        }
    }
    private static void circle(List<String> rsv_liz){
        for (int ind=0;ind<rsv_liz.size();ind++){
            Collections.rotate(rsv_liz, 1);
            System.out.println(rsv_liz);
        }
    }
    private static void trap(String[] sig_args){
        for (String sig:sig_args) {
            catch_sig(sig);
        }
    }
    private static void usage() {
        final String className = new Object(){}.getClass().getEnclosingClass().getName();
        System.out.println("\nUsage:\n" +
                "$echo {a..c} | java "+ className +"\n"+
                "$java "+ className +" {a..c}"+"\n"+
                "$java "+className +"$(echo -e '\\U1f4a'{0..9})\n"+
                "$echo -e '\\U1f4a'{0..9} | java "+className+"\n"
        );
        System.exit(0);
    }
    private static void catch_sig(String sig) {
        Signal signal = new Signal(sig);
        Signal.handle(signal, Signal -> {
            if ("INT".equals(signal.getName())) {
                usage();
            }
        });
    }
}
```

実行結果

```bash
$javac Rotate.java 2>/dev/null
$java Rotate {a..e}
[e, a, b, c, d]
[d, e, a, b, c]
[c, d, e, a, b]
[b, c, d, e, a]
[a, b, c, d, e]
```

## Rev_Rotate.java

```java
import sun.misc.Signal;

import java.util.*;

public class Rev_Rotate {
    public static void main(String[] rsv_args) {
        trap(new String[]{"INT"});
        try{
            if(rsv_args.length==0){
                //via pipe args
                Scanner stdin=new Scanner(System.in);
                List<String> liz = new ArrayList<>(Arrays.asList(stdin.nextLine().split(" ")));
                circle(liz);
                stdin.close();
            }else{
                //via cmdline args
                List<String> liz = new ArrayList<>(Arrays.asList(rsv_args));
                circle(liz);
            }
        }catch(Exception e){
            e.printStackTrace();
            System.exit(0);
        }
    }
    private static void circle(List<String> rsv_liz){
        for (int ind=0;ind<rsv_liz.size();ind++){
            Collections.rotate(rsv_liz, -1);
            System.out.println(rsv_liz);
        }
    }
    private static void trap(String[] sig_args){
        for (String sig:sig_args) {
            catch_sig(sig);
        }
    }
    private static void usage() {
        final String className = new Object(){}.getClass().getEnclosingClass().getName();
        System.out.println("\nUsage:\n" +
                "$echo {a..c} | java "+ className +"\n"+
                "$java "+ className +" {a..c}"+"\n"+
                "$java "+className +"$(echo -e '\\U1f4a'{0..9})\n"+
                "$echo -e '\\U1f4a'{0..9} | java "+className+"\n"
        );
        System.exit(0);
    }
    private static void catch_sig(String sig) {
        Signal signal = new Signal(sig);
        Signal.handle(signal, Signal -> {
            if ("INT".equals(signal.getName())) {
                usage();
            }
        });
    }
}
```

実行結果

```
$javac Rev_Rotate.java 2>/dev/null
$java Rev_Rotate {a..e}
[b, c, d, e, a]
[c, d, e, a, b]
[d, e, a, b, c]
[e, a, b, c, d]
[a, b, c, d, e]
```

# コマンドラインからJshellにパラメタ渡して実行

もうこれでいいな。

```bash
echo -e '\U1f4a'{0..9} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
import java.util.*;
List<String> liz = new ArrayList<>(Arrays.asList("@".split(" ")));
for(int ind=0;ind<liz.size();ind++){
  Collections.rotate(liz,1);
  System.out.println(liz);
}
/exit
EOS
)
'
```

```bash
$echo -e '\U1f4a'{0..9} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
import java.util.*;
List<String> liz = new ArrayList<>(Arrays.asList("@".split(" ")));
for(int ind=0;ind<liz.size();ind++){
  Collections.rotate(liz,1);
  System.out.println(liz);
}
/exit
EOS
)
'
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]

```

```bash
echo -e '\U1f4a'{0..9} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
import java.util.*;
List<String> liz = new ArrayList<>(Arrays.asList("@".split(" ")));
for(int ind=0;ind<liz.size();ind++){
  Collections.rotate(liz,-1);
  System.out.println(liz);
}
/exit
EOS
)
'
```

```bash
$echo -e '\U1f4a'{0..9} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
import java.util.*;
List<String> liz = new ArrayList<>(Arrays.asList("@".split(" ")));
for(int ind=0;ind<liz.size();ind++){
  Collections.rotate(liz,-1);
  System.out.println(liz);
}
/exit
EOS
)
'
[💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠]
[💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡]
[💣, 💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢]
[💤, 💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣]
[💥, 💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤]
[💦, 💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥]
[💧, 💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦]
[💨, 💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧]
[💩, 💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨]
[💠, 💡, 💢, 💣, 💤, 💥, 💦, 💧, 💨, 💩]
```


#20191117追記

構造生み出せた。処理内容には特に意味はない。

```bash
#!/bin/bash

echo  {a..e} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
private <T> List<T> cons(T first, List<T> remain) {
    List<T> ret = new ArrayList<>();
    ret.add(first);
    ret.addAll(remain);
    return ret;
}
private void process(List<String> rsv_args,int cnt){
  for(int ind=0;ind<cnt;ind++){
    String ele = rsv_args.remove(0);
    System.out.println(ele);
    System.out.println(rsv_args);
    List<String> liz_done = cons(ele,rsv_args);
    System.out.println(liz_done);
  }
}
private void main(List<String> rsv_args){
  process(rsv_args,rsv_args.size());
}
main(new ArrayList<>(Arrays.asList("@".split(" "))));
/exit
EOS
)
'
```

```bash
$echo  {a..e} | xargs -I@ bash -c '
jshell -s <(cat <<EOS
private <T> List<T> cons(T first, List<T> remain) {
    List<T> ret = new ArrayList<>();
    ret.add(first);
    ret.addAll(remain);
    return ret;
}
private void process(List<String> rsv_args,int cnt){
  for(int ind=0;ind<cnt;ind++){
    String ele = rsv_args.remove(0);
    System.out.println(ele);
    System.out.println(rsv_args);
    List<String> liz_done = cons(ele,rsv_args);
    System.out.println(liz_done);
  }
}
private void main(List<String> rsv_args){
  process(rsv_args,rsv_args.size());
}
main(new ArrayList<>(Arrays.asList("@".split(" "))));
/exit
EOS
)
'
a
[b, c, d, e]
[a, b, c, d, e]
b
[c, d, e]
[b, c, d, e]
c
[d, e]
[c, d, e]
d
[e]
[d, e]
e
[]
[e]
```