読者です 読者をやめる 読者になる 読者になる

ゲンゾウ用ポストイット

Java、Groovy、Linux関連の備忘録

windows・Cygwinからの実行時のコマンドライン引数の数に限界がある

GroovyスクリプトをCygwinからコマンドライン実行するとき、どうもうまく動かないときがあった。どんな時に問題が発生するのかいまいち切り分けができていなかった。

  • Groovy-1.7.2
  • いずれの場合もシェバングを利用してGroovyスクリプトを実行している。

CliBuilderを使用したGroovyスクリプト

"-d"や"-e"などのオプションを用意したりするとあっという間にコマンドライン引数が10ぐらいになる場合がある。この場合正常に動作しない。

"*.txt"のような複数ファイルを引数で指定可能なGroovyスクリプト

こちらも正常に動作しない場合がある。
これもファイル数が少ない場合にはうまく動作するようだが、ファイル数が一定数を越えるとスクリプトエラーとなってしまう。

startGroovyを除いてみると・・・

bashに詳しいわけではないので何とも言えないが、groovyスクリプト実行時に実行されるbashの一部、startGroovyにそれっぽい処理がかかれている。

201行目辺りからの処理を除いてみたら、以下のようになっていた。

~~~一部抜粋~~~
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    GROOVY_HOME=`cygpath --mixed "$GROOVY_HOME"`
    JAVA_HOME=`cygpath --mixed "$JAVA_HOME"`
    GROOVY_CONF=`cygpath --mixed "$GROOVY_CONF"`
    CP=`cygpath --path --mixed "$CP"`    
    TOOLS_JAR=`cygpath --mixed "$TOOLS_JAR"`
    STARTER_CLASSPATH=`cygpath --path --mixed "$STARTER_CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GROOVY_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GROOVY_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        if [ $CHECK -ne 0 ] ; then
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=`expr $i + 1`
    done
    case $i in
        0) set -- ;;
        1) set -- "$args0" ;;
        2) set -- "$args0" "$args1" ;;
        3) set -- "$args0" "$args1" "$args2" ;;
        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac

fi
~~~一部抜粋~~~

Cygwinの場合は、引数が最大9つまでしか受け取れないということなのかな?それなら今までCygwin上で動作させていたときにエラーとなっていたのがわかる。もちろんLinux上で動作させていたときはこんな問題は発生していない。
Cygwin上からコマンドラインで実行する際には、コマンドライン引数の増えすぎに注意。