batsh-dev-team / batsh Goto Github PK
View Code? Open in Web Editor NEWA language that compiles to Bash and Windows Batch
Home Page: http://batsh.org
A language that compiles to Bash and Windows Batch
Home Page: http://batsh.org
Would be nice to have an argument parser so I can pass in --name blah --test --test2 123
and it gets normalized across platforms
Bash is not available everywhere. POSIX mandates bourne shell compatibility. So please target that instead.
echo("on");
echo("/?");
echo("off");
echo("");
This can be solved, when echo
and println
are always translated to echo(
I am sitting on an obscure linux distribution. There are too many dependency to install for getting batsh up and running.
one should be easily run batsh without this much huge dependency installation
method 1) either create " docker " for batsh
method 2) or http://portablelinuxapps.org/ for batsh . Best method
reference
https://en.wikipedia.org/wiki/Docker_%28software%29
http://anil.recoil.org/2013/11/15/docker-and-opam.html
https://github.com/avsm/ocaml-docker-scripts
ocp-build root
fails because there is no _obuild
directory. Seems like 7d4f803 fixes that, but is not included in the tarball.
from first impression.
println("Hello, world!");
Bash:
"echo" "-e" "Hello, world!"
Batch:
@echo off
setlocal EnableDelayedExpansion
setlocal EnableExtensions
echo Hello^, world^^!
Not good!
Hi @BYVoid ,
amazing compiler, very useful. :)
It might be supported already, not 100%, but it would be useful if it supported options.
e.g. script.sh -d -o output.txt
e.g. script.batch --help
If there's a way to do this already... I'll definitely be using Batsh from now on!
simple question really, is there a plan for a function to read files as opposed to just checking if they exist? something as simple as converting them into a string would likely be useful.
No-parse single quotes (like Bash, Perl, and PHP) would be a nice feature. And this would mean \
does not need to be written as \\
: '/\.abc/'
// comment %~ fails
// comment fails too ^
It should be safed against percents (by doubling) and multiline carets at the end
Batsh currently compiles to Windows batch file(.bat) and bash script
It should also compile to powershell script
that will be ultimate dream come true - for a cross platform os batchfile language :-)
Now looks like:
清华大学计算机系科协入口
Rowell (BBS)
AI9
Accounts9
Git9
Wiki9
FTP9
Career9
maybe some ServerName
issue.
eg: if [ -f "filename.xt" ]; then ....
How can we do this in batsh?
According to this page on windows one can use IF EXIST
.
http://batsh.org/ says 502 bad gateway
In bash it could be performed with for i in "${array[@]}"
In windows I think should be direct translation — call to some goto for each array element.
When I try to install batsh, I get an error for the pipebang dependency.
Trace:
$ opam install batsh
...
=-=-= Installing typerep.109.55.02 =-=-=
default Downloading https://opam.ocaml.org/archives/typerep.109.55.02+opam.tar.gz
Downloading https://opam.ocaml.org/archives/typerep.109.55.02+opam.tar.gz
Building typerep.109.55.02:
ocaml setup.ml -configure --prefix /Users/andrew/.opam/system
make
make install
Installing typerep.109.55.02.
[ERROR] Due to some errors while processing pipebang.110.01.00, the following actions will NOT proceed:
- install batsh.0.0.5
- install core_kernel.111.03.00
===== ERROR while installing pipebang.110.01.00 =====
Could not get the source for pipebang.110.01.00:
# opam-version 1.1.1
# os darwin
Cannot download https://opam.ocaml.org/archives/pipebang.110.01.00+opam.tar.gz, please check your connection settings.
The former state can be restored with opam switch import -f "/Users/andrew/.opam/system/backup/state-20140706011149.export"
'opam install batsh' failed.
Should we report this to pipebang?
System:
$ specs ocaml os
Specs:
specs 0.8
https://github.com/mcandre/specs#readme
ocamlc -version
4.01.0
opam --version
1.1.1
system_profiler SPSoftwareDataType | grep 'System Version'
System Version: OS X 10.9.4 (13E28)
Wouldn't it be better to compile to PoSh over Batch?
I use a lot of bash scripts in cygwin and would love to see cygwin-compatible bash output.
The website currently gives 502 Bad Gateway.
existence = exists("filename with spaces.txt");
turns into
if exist filename with spaces.txt (
set /a existence=1
) else (
set /a existence=0
)
which fails, even if the file would exist.
test1="Caret^";
test2="Exclam!";
test3="Caret^ and Exclam !";
Translated to
set test1=Caret^^
set test2=Exclam^^!
set test3=Caret^^ and Exclam ^^!
test3 is wrong, it contains "Caret and Exclam!" but the caret is removed.
It need to be translated to
set test3=Caret^^^^ and Exclam^^!
Phase 5) of "How does the Windows Command Interpreter (CMD.EXE) parse scripts?"
http://stackoverflow.com/a/4095133/463115
Currently, it is only possible to write using the C syntax. It would be great to be able to paste in a bash script I've written, and have it compiled as a batch file.
If it's possible to reverse engineer the compiling, it'd be easy to go bash -> current input (C) -> batch. The hardest part would be reversing the current compiler.
I can't seem to escape characters in strings. Is there a way to embed quotes?
e.g. bash("echo "test"")
Also, I notice that % is translated to %% in batch files, even if within quotes. Is this correct?
I have followed the install instructions and I'm getting this:
Building batsh.0.0.5:
ocp-build root
ocp-build build -njobs 8
ocp-build install -install-lib /Users/cmbranc/.opam/system/lib/batsh
[ERROR] The compilation of batsh.0.0.5 failed.
Removing batsh.0.0.5.
ocp-build root
ocp-build uninstall -install-lib /Users/cmbranc/.opam/system/lib/batsh
===== ERROR while installing batsh.0.0.5 =====
# opam-version 1.1.2
# os darwin
# command ocp-build root
# path /Users/cmbranc/.opam/system/build/batsh.0.0.5
# compiler system (4.01.0)
# exit-code 2
# env-file /Users/cmbranc/.opam/system/build/batsh.0.0.5/batsh-53691-ffb3fd.env
# stdout-file /Users/cmbranc/.opam/system/build/batsh.0.0.5/batsh-53691-ffb3fd.out
# stderr-file /Users/cmbranc/.opam/system/build/batsh.0.0.5/batsh-53691-ffb3fd.err
### stdout ###
# ocp-build: Entering directory `/Users/cmbranc'
# ocp-build: Leaving directory `/Users/cmbranc'
### stderr ###
# find_project_root
# Updating ocp-build.root
# Error: Could not find target project root
What am I missing?
Would be great fi this supported creating .cmd files.
http://stackoverflow.com/questions/148968/windows-batch-files-bat-vs-cmd
Demo source code:
array = [0, 1, 2, 3];
i = 2;
// Wrong
array[i] = 42;
println("array[i] = " ++ array[i]);
println("array = [" ++ array[0] ++ ", " ++ array[1] ++ ", " ++ array[2] ++ ", " ++ array[3] ++ "]");
println();
// Correct
batch("set /a array_!i!=42");
batch("for %%i in (\"!i!\") do echo array[i] = !array_%%~i!");
println("array = [" ++ array[0] ++ ", " ++ array[1] ++ ", " ++ array[2] ++ ", " ++ array[3] ++ "]");
Compiled results:
@echo off
setlocal EnableDelayedExpansion
setlocal EnableExtensions
set /a array_0=0
set /a array_1=1
set /a array_2=2
set /a array_3=3
set /a i=2
rem Wrong
set /a array_i=42
echo array[i] ^= !array_i!
echo array ^= [!array_0!^, !array_1!^, !array_2!^, !array_3!]
echo:
rem Correct
set /a array_!i!=42
for %%i in ("!i!") do echo array[i] = !array_%%~i!
echo array ^= [!array_0!^, !array_1!^, !array_2!^, !array_3!]
Execution output:
array[i] = 42
array = [0, 1, 2, 3]
array[i] = 42
array = [0, 1, 42, 3]
Regardless of building from git or installing via "opam install batsh" - both fail due to the dependency of dlist which fails to build.
j@j-VirtualBox:~/projects$ opam install batsh
The following actions will be performed:
∗ install dlist 0.1.0 [required by batsh]
∗ install batsh 0.0.6
===== ∗ 2 =====
Do you want to continue ? [Y/n] y
=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[batsh] Archive in cache
[dlist] Archive in cache
=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[ERROR] The compilation of dlist failed at "ocp-build install".
Processing 1/2: [dlist: ocp-build uninstall]
#=== ERROR while installing dlist.0.1.0 =======================================#
# opam-version 1.2.2
# os linux
# command ocp-build install
# path /home/jim/.opam/system/build/dlist.0.1.0
# compiler system (4.02.3)
# exit-code 2
# env-file /home/jim/.opam/system/build/dlist.0.1.0/dlist-13013-d2d111.env
# stdout-file /home/jim/.opam/system/build/dlist.0.1.0/dlist-13013-d2d111.out
# stderr-file /home/jim/.opam/system/build/dlist.0.1.0/dlist-13013-d2d111.err
### stderr ###
# Warning: 58 incomplete packages (will not be built):
# [...]
# in /home/jim/.opam/system/build/dlist.0.1.0
# deps: dlist core_bench threads
# Hidden: 57 incomplete packages in META files (use -print-incomplete-meta).
# Incomplete package "core_bench" missed by 1 packages
# dlist-bench (program,ocp)
# in /home/jim/.opam/system/build/dlist.0.1.0
# deps: dlist core_bench threads
# Error: project contains no targets
# Are your .ocp files empty ?
=-=- Error report -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
The following actions were aborted
∗ install batsh 0.0.6
The following actions failed
∗ install dlist 0.1.0
No changes have been performed
j@j-VirtualBox:~/projects$
Any way to access env variables from the operating system ?
function mandelbrot(width,height,max){
row = 0;
while(row<height){
col = 0;
while(col<width){
c_re = (col-width/2)*4/width;
c_im=(row - height/2)*4/width;
x=0;
y=0;
iteration=0;
tempbool = true;
while(check2Conditions(x*x+y*y<=4,iteration<max)){
x_new = x*x - y*y + c_re;
y = 2*x*y + c_im;
x = x_new;
iteration = iteration + 1;
}
if (iteration < max) putpixel(col, row, white);
else putpixel(col, row, black);
col = col+1;
}
row = row+1;
}
}
function check2Conditions(a,b){
if(a) if(b) return true;
return false;
}
mandelbrot(800,600,20);
leads to error
Expression can not compile to comparison
(Call(check2Conditions((Leftvalue(Identifier _1))(Leftvalue(Identifier _2)))))
Hi there,
I'm having trouble installing Batsh on OS X Mavericks. I'm running Opam v1.1.1, OCaml 4.01.0 and have installed all the listed dependecies as per the README, but both using opam install batsh
and make
on a cloned git repo give me this error (slightly different in Opam's case, but saying the same thing:
ERROR: the following packages are missing:
- camlp4o
- camlp4-pa-op
- camlp4-pa-o
- camlp4lib
Any ideas?
In the README, it mentions (of other scripting languages):
Functionalities like process piping are not convenient to use.
I couldn't find any pipe syntax in batch though - is it still to come?
In bash, I pretty much always use set -e
, which fails the whole program if any command fails. I also often use set -o pipefail
, which extends this to a failed command anywhere in a pipeline.
If batsh is aiming to reduce surprises and accidental bugs due to bad default shell behaviour, I think it should make error suppression explicit and mandatory (like exceptions in other languages), rather than only checking errors when the programmer remembers to check $?
.
I'm not sure what that should look like (in terms of syntax / implementation) though.
test=myFunc("1.^ 2.& 3.\" 4.^ 5.&");
function myFunc(text)
{
return text;
}
Results to (only the relevant lines)
call :myFunc _1 0 1.^^ 2.^& 3.^" 4.^^ 5.^&
set _0=!_1!
set test=!_0!
First question: Why the result is first copied to _0
and then to test
and not directly to test
?
Obviously the call will not work, as the single string will be splitted into 5 substrings.
You could try to enclose it into quotes, but even that wouldn't work always.
At all, it's simply not possible to use parameters by value with batch, only by reference it works reliable.
So the compiler should output something like
set _0=1.^^ 2.^& 3.^" 4.^^ 5.^&
call :myFunc _1 0 _0
set test=!_1!
goto :EOF
:myFunc
set text_%~2=!%~3!
set _1=!text_%~2!
x = "a|b";
compiles to set x=a|b
which is almost certainly wrong.
Hello,
This is more of a Wiki or Forum like question:
Do you have more examples on how to make use of the batch(rawStatement) and bash(rawStatement) commands?
In the http://batsh.org console, I've tried both batsh style statements:
batch(a = 1;) or batch("a = 1")
And Windows style statements:
batch(cd C:\Users) or batch("cd C:\Users")
Am I missing something important here?
Ben
Not sure if BatSh already supports this, but having "library" support where library batsh scripts can be included in the parent BatSh script can provide a means of modularizing support.
ie - assuming that batsh supported the concept of global automatic variables like argc and argv, someone could write a batsh script library like gotopt.batsh that a parent script could include with:
include("getopt.batsh");
The output in either batch or bash could be one monolithic file that includes all the logic of the libraries or break each down into their own generated code file to be evaled or however to include the logic.
How is the syntax for ENV variables?
On windows can be supported by adding 1 for each variable to some temporary variable.
In bash can be performed with ${#ArrayName[@]}
Hi, I am following this: https://github.com/BYVoid/Batsh document to install 'batsh' in by Ubuntu 12.04x64 virtual machine. I have installed opam and ocaml. Installed Dependecies with this command:
$opam install ocp-build core ounit dlist cmdliner
Downloded batsh.
but while running $make command , I am getting this error:
" root@testing:~/batsh/Batsh-0.0.5# make
ocp-build root
find_project_root
Updating ocp-build.root
ERROR: the following packages are missing:
root@testing:~/batsh/Batsh-0.0.5# "
Please help me out. All the dependencies are installed as per the document.
I mean i++
is much shorter than i=i+1
Right now && and || doesn't work in if and while
Hi there,
I guess the idea for batsh is great and I currently try to use it for a specific project. However I am missing a feature to ask a user for input.
It would be great if you would implement this feature as well.
I think there should be a build-in function to get the current path, it's common used and the way to get the path is very different in batch and bash. I didn't find such a function in README.md
readdir()
expands to
for /f "delims=" %%i in ('dir /w') do set files=%%i
which is a horrible idiom for iterating over files. First there is a bug that /w
is used where /b
has to be. Then it will break with file names that contain characters that won't fit into the OEM codepage if the batch file is run on a console with raster font (default setting, thus pretty much most of them). for
can iterate over files just fine and if you don't need the filtering and sorting capabilities of dir
, it's better to just use
for %%i in (*) do ...
Another point here: files
will contain the last line read by the for
. Which is most certainly not what you want.
set "files="
for %%i in (*) do set "files=!files! "%%i""
would probably be nicer.
I am new to hacking Ocaml stuff.
I have Ocaml 4.02.3 installed and opam 1.2.2 from system. I use opam locally and ran opam install ocp-build core ounit dlist cmdliner
just as in the documentation. No failures during installation.
This is output when typing make
.
ocp-build build batsh
find_project_root
Warning: Could not find OCaml ocamldoc tool.
Warning: missing dependency, bytecode "ocp-build" requires "ocp-build-engine" bytecode
Disabling bytecode version of "ocp-build"
Disabling native version of "ocp-build"
Warning: both versions disabled
Package "ocp-build" disabled
Warning: 2 missing and 1 disabled (use -print-missing)
Updating ocp-build.root
Warning: "oUnit.threads" depends on "threads", that only exists in native code
Disabling bytecode version of "oUnit.threads"
Warning: installed package oUnit.threads depends on source package threads
Package "oUnit.threads" disabled
Warning: missing dependency, bytecode "ocp-build" requires "ocp-build-engine" bytecode
Disabling bytecode version of "ocp-build"
Disabling native version of "ocp-build"
Warning: both versions disabled
Package "ocp-build" disabled
Warning: "core" depends on "threads", that only exists in native code
Disabling bytecode version of "core"
Warning: installed package core depends on source package threads
Package "core" disabled
Warning: missing dependency, bytecode "core.top" requires "core" bytecode
Disabling bytecode version of "core.top"
Disabling native version of "core.top"
Warning: both versions disabled
Package "core.top" disabled
Warning: missing dependency, bytecode "test" requires "core" bytecode
Disabling bytecode version of "test"
Disabling native version of "test"
Warning: both versions disabled
Package "test" disabled
Warning: 4 missing and 5 disabled (use -print-missing)
Warning: 10 package conflicts solved (use -print-conflicts)
Warning: 5 incomplete packages (will not be built):
test (program,ocp)
in /home/tatsh/dev/batsh/src
deps: batsh-lib core oUnit threads
Hidden: 4 incomplete packages in META files (use -print-incomplete-meta).
Incomplete package "core" missed by 1 packages
test (program,ocp)
in /home/tatsh/dev/batsh/src
deps: batsh-lib core oUnit threads
Incomplete package "core" missed by 1 packages
test (program,ocp)
in /home/tatsh/dev/batsh/src
deps: batsh-lib core oUnit threads
0.01s batsh-lib/_temp/symbol_table.mlpp [failed]
[92.1] Command failed: 'camlp4o' 'src/symbol_table.ml'
-- stderr for ...ild/batsh-lib/_temp/symbol_table.mlpp --
File "src/symbol_table.ml", line 7, characters 0-1:
Parse error: [semi] expected after [str_item] (in [implem])
0.01s batsh-lib/_temp/batsh_ast.mlpp [failed]
[40.1] Command failed: 'camlp4o' 'src/batsh_ast.ml'
-- stderr for _obuild/batsh-lib/_temp/batsh_ast.mlpp --
File "src/batsh_ast.ml", line 44, characters 17-21:
Parse error: [semi] expected after [str_item] (in [implem])
0.01s batsh-lib/_temp/bash_ast.mlpp [failed]
[14.1] Command failed: 'camlp4o' 'src/bash_ast.ml'
-- stderr for _obuild/batsh-lib/_temp/bash_ast.mlpp --
File "src/bash_ast.ml", line 50, characters 17-21:
Parse error: [semi] expected after [str_item] (in [implem])
0.01s batsh-lib/_temp/winbat_ast.mlpp [failed]
[115.1] Command failed: 'camlp4o' 'src/winbat_ast.ml'
-- stderr for _obuild/batsh-lib/_temp/winbat_ast.mlpp --
File "src/winbat_ast.ml", line 60, characters 8-18:
Parse error: [semi] expected after [str_item] (in [implem])
4 errors in 0.05s. 4 jobs (parallelism 0.9x), 4 files generated.
Error log:
Error:
[92.1] 'camlp4o' 'src/symbol_table.ml'
File "src/symbol_table.ml", line 7, characters 0-1:
Parse error: [semi] expected after [str_item] (in [implem])
Error:
[40.1] 'camlp4o' 'src/batsh_ast.ml'
File "src/batsh_ast.ml", line 44, characters 17-21:
Parse error: [semi] expected after [str_item] (in [implem])
Error:
[14.1] 'camlp4o' 'src/bash_ast.ml'
File "src/bash_ast.ml", line 50, characters 17-21:
Parse error: [semi] expected after [str_item] (in [implem])
Error:
[115.1] 'camlp4o' 'src/winbat_ast.ml'
File "src/winbat_ast.ml", line 60, characters 8-18:
Parse error: [semi] expected after [str_item] (in [implem])
Makefile:2: recipe for target 'build' failed
make: *** [build] Error 2
The result for \r is wrong for winbatch.
test_r="part1\r##";
compiles to batch:
`set test_r=part1
This results to an error when reaching the ##
.
There is no simply or completly native way to insert a carriage return into a variable, but it's possible.
Creating of a single carriage return:
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
CRs can only be handled with delayed expansion or for loop parameters, but never with percent expansion.
So the compiler output could look like:
@echo off
setlocal EnableDelayedExpansion
setlocal EnableExtensions
for /f %%a in ('copy /Z "%~dpf0" nul') do set "\r=%%a"
set test_r=part1!\r!##
This would actually be useful for installer/updater stuff, but it would be much more so if it were possible to include binary blobs that get compiled into blobs that can be dumped out to files in the filesystem. This would be sort of like the Unix "shar" command with a script payload, a non-compiled smart SFX.
What would be really impressive is if some form of compression were included here, but I don't know how that would be done in a platform-independent manner. Maybe if both platforms have a compression utility that is always pre-installed... maybe gzip on Unix-type systems and ????? on Windows?
The result for \n is wrong for winbatch.
test_n="line1\nline2";
compiles to batch:
set test_n=line1^
line2
But the multiline caret at the line end only results in appending the second line, but without adding a linefeed into the variable.
The result needs to be:
set test_n=line1^
line2
Or you could add a global variable with a single linefeed
@echo off
setlocal EnableDelayedExpansion
setlocal EnableExtensions
set \n=^
rem ** Two empty lines are required for the definition of \n here **
set test_n=line1!\n!line2
The extra empty line is required here, more about this at SO:Long commands split over multiple lines in Vista/DOS batch (.bat) file
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.