I need to do a fair bit of scripting in my job as a SQL Server DBA. Sometimes, I need to deploy a fix script to a very restricted environment, where the only option for scripting may be DOS Batch. In one such environment, even VBScript/WSH isn't a possibility, let alone PowerShell. Anyone who has written enough batch files on DOS and Windows knows that it's very limited and a huge PIA when you need to do anything too complicated. This is especially true for folks who have worked with Unix shell scripting, Perl, Tcl, Python, Ruby, etc.
A possible solution to this would be a CMD preprocessor that would add some of the useful functionality from more capable scripting languages. I've tried to find such a utility, but so far I've had no luck.
Which finally leads to my question: is anyone aware of a such a CMD preprocessor? If not, what functionality would you like to see in one?
Addendum:
If you're unfamiliar with the idea of a preprocessor see this Wikipedia entry.
To clarify, I'm thinking of a tool that would add features like:
Functions
Backtick (`) ala Unix shell
...and possibly others. Those are two features I've wished CMD had and can think of a way to implement them with a CMD preprocessor. Functions could be implemented with env vars and GOTO/labels; backticks by piping to a temp file and using set /p =< to read in the result to an env var.
You can already achieve these same ends, but it gets to be very tedious and verbose- which is how I came to the idea of having a preprocessor handle the boilerplate for features like those.
Example
Using the example of backticks, here is an example of unprocessed code from my hypothetical Batch++ and processed vanilla batch script, ready to be run by CMD.exe:
Batch++ Source (test.batpp)
copy `dir /b /s c:\ | find "CADR-README.htm"` \\srv01\users
Run it through the preprocessor
bpp test.batpp > post_test.bat
Resulting CMD/BAT code (post_test.bat)
dir /b /s c:\ | find "CADR-README.htm" > _bt001.tmp
set /p _BT001 =< _bt001.tmp
copy %_BT001% \\srv01\users
set _BT001=
del _bt001.tmp
I am not sure to interpret correctly your question. If you run in a controlled environment that doesn't allow you to run any scripting extension, how are you going to access such a preprocessor?
However, and in regard of the two features you request, you are OK with .BATs. Both features are supported by BAT processing in current Windows versions.
Functions: you have the extended CALL syntax, that supports parameter passing thru argument references %1 .. %9, and enhanced with expansion substitution using %~ syntax. Read HELP CALL.
Backtick: not sure what you want but, in the FOR /F command you may pass a backticked string to be run and its output captured. Read HELP FOR.
Related
If you are in a Cygwin or MinGW bash shell, environment variables like $PATH are in "UNIX" format - using forward slashes as dir separators and using the colon to separate multiple paths. But if, inside this shell, you run something like cmd.exe /c 'echo %PATH%' the resulting output is in "Windows" format, using backslashes and semicolons respectively.
Is this magical conversion documented somewhere? Or better yet, can somebody point to the code that makes this happen?
(The reason I ask is because it seems the conversion doesn't always happen and I'm trying to understand the exact conditions needed for it to occur.)
The internal conversions between Unix and Windows path format are
performed by the funtions in path.cc
https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/path.cc;h=3cb46c9c812e17460d56def2f915b21c7227f3bf;hb=HEAD
When a Cygwin program executes a Windows program the spawn process is
performed by functions in spawn.cc
https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=winsup/cygwin/spawn.cc;h=37db52608e24e866e80401668ef13562f0cb67ea;hb=HEAD
If you need more details or ask clarification use the cygwin mailing list.
How do you embed scripting language inside BAT file in Windows?
Effectively I am after Unix shebang for Windows: put JS/C#/Python/Java text into a BAT file, have a small header on top then have it compiled/run by just running the container BAT file.
Some scripting engines are guaranteed to exist: VBScript, JS, MSHTA/HTML — are there good shebangs for those?
Others are technically optional, but may be expected: C#, VB.NET, PowerShell, node.js, Python — any clues as to how to wrap those with a shebang?
Finally, there might be a way to smuggle a compiled binary within a BAT file, and shake/goad OS into running it. Any ideas how to do that?
Two useful Javascript shebangs I've come across. Those are crafted for CSCRIPT, MS JScript guaranteed to be bundled with Windows. Can be trivially retargeted for node.js too -- if you're certain node.js would be on the path at runtime.
DARTH shebang, called after the /*-*\ smiley:
title /*-*\&#cscript/nologo /E:jscript %~f0 %*&#goto:EOF&:*/=0
WScript.Echo('OK');
Stealth clubman shebang, called after the scary man with a club emoticon:
0</* :
#cscript/nologo /E:jscript %~f0 %*&#goto:EOF&:*/0
WScript.Echo('OK');
The tradeoff between those two is whether we make it apparent the script is shebanged at runtime or have a more conspicuous header. DARTH would print one line to console, and set the console title. Stealth clubman would take two lines at the JS header.
I noticed that Windows 7 enables to execute .sh files as if they were .bat files. That got me wondering whether it is possible to write a .sh file such that it can be executed in Windows and Linux (let's say bash).
The first thing that comes to my mind is to fabricate an if-statement such that Windows and Ubuntu can deal with it and jump into the according block to execute plattform-specific commands. How could this be done?
Note: I know this is not good practice. I also know that scripting languages like Python are far better suited to solve this problem than a mixed-syntax command line script would be. I'm just curious...
You could use this:
rem(){ :;};rem '
#goto b
';echo sh;exit
:b
#echo batch
It's valid shell script and batch, and will execute different blocks depending on how it's run.
Modify the echo and #echo lines to do what you want.
AFAIK, you can't directly run .sh files from Windows' cmd.exe. For that you'll need a *nix emulation layer to run the shell. Check out Cygwin or Msys/MinGW
In Python you are not obliged to use a file, you can specify -c "..." and gives the Python commands to the Python interpreter via a string on the command line.
Can I achieve the same result with vbscript?
I've seen solutions that need you to use a batch script,
But what if I am on a system with zero writing permissions?
Following the answer from #Syberdoor, I can run this:
mshta vbscript:Execute("dim result:result=InputBox(""message"",""title"",""input"")(window.close):echo result")
but it still doesn't print the result in the console.
There is one trick you can possibly use and that is mshta.exe.
You can execute code like this:
mshta vbscript:Execute("<your code here, delimit lines with : (colon)>:close")
This is of course a fantasticly insane hack and on a system where you are not even allowed to create a file I am not sure if mshta.exe would be allowed.
Maybe you can also find additional inspiration from this thread (the mshta solution is also posted there). Although mostly batch related it is imo a great compendium of several really crazy ways to fool windows into executing vbs code.
No, the interpreters shipped with Windows (wscript.exe and cscript.exe) don't support that. If you can't create a file anywhere you're out of luck. You need some kind of wrapper script to transform the argument into something that VBScript interpreters can execute.
The naïve approach would be to create a VBScript with an ExecuteGlobal statement like this:
With WScript.Arguments.Named
If .Exists("c") Then ExecuteGlobal .Item("c")
End With
However, that won't work correctly, because double quotes aren't preserved in the arguments. If you ran the above script like this:
C:\> vbsrunner.vbs /c:"WScript.Echo "foo""
it would effectively execute the statement WScript.Echo foo instead of WScript.Echo "foo", and I was unable to find a way to escape nested double quotes so that they're preserved in the argument.
What will work is a batch script that writes the argument to a temporary file, and then executes that file with a VBScript interpreter:
#echo off
setlocal
set "tempfile=%TEMP%\%RANDOM%.vbs"
>"%tempfile%" echo.%~1
cscript.exe //NoLogo "%tempfile%"
del /q "%tempfile%"
That way you can run VBScript statements on the command line like this:
C:\> vbsrunner.cmd "WScript.Echo "foo" : WScript.Echo "bar""
foo
bar
If you wanted to replicate Python's interactive mode you could use my vbsh, but that would still require the ability to create a file somewhere.
I am writing my shell scripts using notepad++ editor in windows xp but I can not check for systax error in this editor. Is there any tool which can check the syntax of the shell scripts in windows xp?
Thanks
Try Shel script editor for windows http://www.editrocket.com/features/shellscript_editor.html
If you mean batch files, then it's getting fairly difficult. My syntax highlighter can show me some things, e.g. using %f instead of %%f but not much else I could do wrong. That is mostly because the syntax for batch files isn't really described by a formal grammar but instead parsed in a more ad-hoc manner.
Just learn to write correct code, in that case. No editor will be of much help, especially given the subtleties that can arise with batch files. Or do you see the error in the following code?
#echo off
for %%x in (World,Moon) do (
echo Hello %%x :-) - A good morning to you.
)