Let's assume you want a script (not too complex) to run on the major platforms around: Windows, Linux and MacOSX.
Linux and MacOSX are both Unix-like OSes, thus probably they'll run BASH or SH consoles (by default). Let's assume we don't have to cope with other shells, like CSH.
The idea may be to install bash on windows, you can using cygwin. Then you can create a script that goes on bash and just rely on bash's portability.
But... Is it possible to make a script that runs on Windows and Linux+Mac natively? That is, writing a script which run on both DOS and SH without using particular tools?
Yes, you can.
On Windows (assuming the good old prompt shell, runnable via "cmd"), script are batch files, that is sequences of commands. Just like SH :)
To run a DOS batch file, just name it foo.bat and you can execute it on the shell.
To run a SH script file, just make it executable and add the shebang at the first line.
... Or call the script (executable or not, shebang or not), directly with the shell:
sh myscript.lol
Now, it's clear that if we create a script.bat, we can call it on DOS writing:
C:\> script.bat
and on SH by writing
~$ sh script.bat
The problem is: how to write the script itself? SH commands and DOS ones aren't the same.
Yep, but... They're similar :) And we can exploit commands like "REM" (DOS) and "alias" (SH) to overcome many difficulties.
For example, the comments issue: in DOS you write:
REM this line won't be executed.
in SH you write
# this line won't be executed.
Now, if you write
REM ; echo "Something"
when executing the script on DOS, the line won't be executed, BUT on SH it will, because "REM" will be an invalid command (or variable), but - since it's followed by semicolon - the next command is valid and will be executed!
So, just write
REM ; alias REM="#"
and just use "REM" for all your comments :) It will work both on SH and DOS.
In the same way, we could execute commands exclusively on one system and not the other, creating a script which works on both platforms.
For example, let's say you've to copy some files. In DOS you use the "copy" command, on SH you use "cp":
REM ; alias copy="cp"
copy file.txt anotherfile.txt
Bigger problems are for complex constructs or with non-isomorphic construct, for example IF, which do exists on both DOS and SH, but isn't easy to make them match.
On DOS you have: IF COND EXPR
while on SH you have: if [ cond ] ; then block; fi
And you often use GOTOs on DOS, but not on SH.
In these cases, unless you have something really complex to do (and in that case probably you prefer a good portable platform for scripting, like Ruby or Python) instead of this portable script, we can exploit again the above trick, to write parts of code mutually exclusive:
REM ; alias REM="#" # This allows you to write code not executable on SH
REM Next command is executed on DOS but not SH
IF EXISTS c:\file.txt CP myfile.txt c:\file.txt
REM Next is executed on SH but not DOS :)
REM if [ -e /file.txt ] ; then cp myfile.txt /file.txt ; fi
The problem is that you probably write most of your script twice, one for DOS and one for SH...
Also because both variables and paths are written in different ways:
DOS: %MYVAR%=c:\my\path\
SH: MYVAR=/my/path/
REM ; alias REM="#"
REM DOS PART-----------------------------------
ftp -s:getFile.txt some.host.com
unzip thatFile.zip
FOR %%c in (*.txt) DO move %%c foo_%%c.lol
copy *.lol "c:\Documents and settings\myuser\Desktop\"
REM SH PART------------------------------------
REM ; wget ftp://some.host.com/blah/file.zip
REM ; unzip thatFile.zip
REM ; for i in `ls *.txt`; do mv $i foo_$i.lol ; done
REM ; cp *.lol ~/Desktop/
Anyway, maybe you can map many commands from DOS to SH, and maybe it becomes convenient to use this way, when creating large-diffusion scripts.
I written all this without testing on both platforms :D
Stay --sync
2 commenti: