Monday, April 11, 2011

Cross platform shell script / batch file (Windows NT & Unix)

Here's a neat little hack I've come up with to script across both Windows and Unix.

It requires a ".bat" extension under Windows, and the execute bit set under Unix.

It uses the GOTO command in Windows to skip the Unix part, and it abuses the stderr redirect in Unix to effectively ignore the Windows IF and GOTO commands on line 1.


if %OS% == Windows_NT goto WINDOWS
then
:
## Hack to make a cross-OS compatible script
fi 2> /dev/null

# ------------------------------------------------------------------------------
# Unix execution
# ------------------------------------------------------------------------------

NAME=$0
NAME=${NAME%.bat}
NAME=${NAME##*/}

echo "My name is ${NAME}, and I work in Unix environments"

exit

# ------------------------------------------------------------------------------
# Windows execution
# ------------------------------------------------------------------------------

:WINDOWS
@echo off

set NAME=%~n0

echo My name is %NAME%, and I work in Windows NT environments"

# ------------------------------------------------------------------------------

4 comments:

  1. Refined Software LLC
    This is our hack in "myscript.sh.bat" files for remarks that work without error in .sh and .bat at the same time as well as how to run a command for either one without any error on the other. Anyone can use these without reference to us although it is appreciated.

    rem= # Universal remark.

    rem= # Only .bat
    echo ^>/dev/null \>nul \& exit

    rem= # Only .sh
    echo ^>/dev/null \>nul ^& exit

    rem= # Easiest way to use
    echo ^>/dev/null \>nul \& goto windows
    # .sh stuff only
    exit
    :windows
    rem .bat stuff only
    exit

    EXPLANATION:
    rem= #
    .bat only sees the "rem" which ignores everything after it.

    .sh sees "rem" as a variable which is set to nothing ( because of the: "= " ) and sees the "#" as a separate command which ignores everything after it.

    EXPLANATION:
    echo ^>/dev/null \>nul \& goto windows

    both use the ">" command to change where the echo displays.

    .bat uses "\" to escape the ">" so that it is not a command.

    .sh uses "^" to escape the ">" so that it is not a command.

    .bat uses ">nul" to make the non-errored echo invisible.

    .sh uses ">/dev/null" to make the non-errored echo invisible.

    both use "&" to call a new command on the same line but if the "&" is escaped with the correct "\" or "^" the whole line is just an invisible echo.

    ReplyDelete
  2. Starting your "file.sh.bat" with the following two lines will give each Script a single error of either "#!" or "@" is not a command. This is preferable to .bat displaying "C:\echo ^>/dev/null \>nul \& goto windows" and .sh not being able to be run at all.

    #!/bin/sh
    @ echo off

    ReplyDelete