Windows CMD syntax Generally need to use double-quotes for tokens containing a special character (esp. space character). Single quote usually does not work. But in some cases, like for 'ECHO', it will just echo exactly what you type (except for magic like "ECHO."). http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds.mspx?mfr=true :: label. Troublesome to use for comments because does not behave as comment in some block situations or where it could be interpreted as a drive designation. Use "rem"! %* All parameters ^ escapes similarly to \ in a good shell When redirecting or piping from echo, don't include any white space between the string and the | or > character, because that space will actually be piped. When piping or redirecting from echo, you will get a terminating \r\n. I guess try the 'set -p' workaround to avoid that. To escape any special characters echo'd with echo, use ^. For example: echo.this^< and A^>that Generally, always use "echo." or "echo:" to prevent spurious space. echo a blank like (like Bourne "echo"): echo. echo: (and a few equivalent alternatives). "path" is a magical env variable. Unlike other env vars, you set it like path=x instead of like set path=x Case seems to make no difference. GOTCHA: Unlike PowerShell, CMD always has an implicit %CD% as first element of search path. Elements of "" (nothing) or "." (dot) in PATH make no diff. Command lines are generally tokenized by white space and metacharacters cause their special behaviors. Only exception to this is double-quoting! Double quoting preserves special characters like > and it groups the "" expression(s) INCLUDING THE QUOTES THEMSELVES!! into single params. BEWARE: Single-quotes have no special power. Quoting and back-slashing to not work for command continuation. Looks like double-quotes themselves can be escaped with \, and double-escaped with backtick `. ^ carat is escape operator outside of double-quotes. Funny thing about this is, ^ + line delimiter prevents program from getting the line-delimiter. Many commands don't work interactively, or require different syntax to work interactively (i.e., not in batch scripts). echo a blank line like: echo: OR echo. Can joint comands with "&", but everything must be entered on one line. if 1==2 echo one & echo two If x.exe, x.bat, x.cmd are present in a directory and you run "x", the exe will execute. setlocal... endlocal This is not like not "exporting". Windows vars always export downward, since there is apparently no concept of independent shell processes. local vars do not export upward. This makes the vars behave like normal UNIX shell script execution, as opposed to UNIX shell script sourcing. Well-known WORKAROUND to strip double-quotes and normalize paths is to use the for/~ construct for scalar operands. N.b. all of the ~*v operators strip double-quotes, not just plain ~v. ~v ONLY strips double-quotes. GROUPING Use & to separate multiple commands on one line. Use () to group & commands or commands on multiple lines. If () used to group commands, then can't use ( or ) within the commands. Examples if ""=="%~VAR" set PARAM=one two three & goto ABORT_SUB if ""=="%~VAR%" ( set PARAM=one two three goto ABORT_SUB ) For statement loop variable: In scripts ONLY: Double the delimiter from % to %%. Variable name can be only a single letter (case-sensitive) For some crazy reason delimit even in the main FOR clause (where variable is set)> For some crazy reason delimit like %%x (of %x without script) (instead of %x%). Non-loop variables are referenced like %name% or !name!. Variables inside of blocks (even implicit) are expanded when the compound command expands, unless you "setlocal enabledelayedexpansion" or invoke CMD with "CMD /V". Then use ! exclamation point instead of % for variable de-reference delimiters. Can't use variable values containing ! when this is enabled, therefore when done: setlocal disabledelayedexpansion. Ref DE vars like !x! instead of like %x%. APPENDING to a variable in a loop. Impossible to set a variable WHICH CALLER CAN USE in a cmd script. The loop setting is only possible with delayedexpansion on. You must do one of the following, and the appended variable is not available to the caller in either case. Use setlocal/endlocal (disabledelayedexpansion???) Invoke interpreter /V:ON switch like "%compsec%" /V:ON /C .\lcl.cmd. I.e., need to use a nested interpreter, which has its own variable set. cd including drive: cd /d f:\dir OR pushd, popd Exit from inside script: exit /b "exit /b 3" exits entire script (not just the goto) without clobbering parent, but does not work under calls. There is no convenient way to do this from a call. Goto gets around this, but goto doesn't support parameters like call does. When want to just return from a call subroutine, use "goto :EOF". Exit values done like exit /b 1 work great from CALLs or GOTOs. The exit statuses are read like if not errorlevel 0 then... Does NOT work great for a caller's "x.cmd &&..." OR "x.cmd ||..." See GOTCHA below. %ERRORLEVEL% is about same as %? in UNIX shell. But see relavent GOTCHA below! Per http://commandwindows.com/tipsandtricks.htm Make echo behave normally and not handle special params: echo.off File existence: if exist file.txt command File non-existence: if not exist file.txt command Grep: findstr See "win.txt" for details. pushd, popd doskey still good for macros (see "win.txt" file) Doskey can alias multiple commands. Use $* on place of %*, and $T in place of &. (Hm. "&" seems to work for me now with Windows 8) Workaround for no sleep command: ping -i 1 -n X localhost (Use X = 1 + seconds-to-wait) (returns true) WARNING: ZERO file from DOS: copy /b test.txt +,, !Important: Must be in same directory for this to work. Need to write a touch.cmd script. Current user: echo %username% (For at least some sys svcs says the hostname + $ like AL-SISCVMSQLPC2$ Why?) Check status of AD domain account: net user /DOMAIN nodcaid echo %userdomain% Windows NUL == UNIX's /dev/null (n.b. one L) Current user: echo %username% (For at least some sys svcs says the hostname + $ like AL-SISCVMSQLPC2$ Why?) Check status of AD domain account: net user /DOMAIN nodcaid echo %userdomain% Windows NUL == UNIX's /dev/null (n.b. one L) Use setlocal to prevent upward export of ENV var settings, and cd's. "echo off" is never exported up, so can do @echo off setlocal at top of scripts. Read input from user. Retarded syntax: read /p VARNAME=The prompt I believe that 'read' is obsoleted by: set /p id=the prompt Pseudo-variable reference %RANDOM% does what you think it would. Can write to stderr same as from Bourne: echo message 1>&2 Reading env var value from a file: set /p Build= file.txt Write text to system clipboard echo|set /p dummyName="alpha" | clip OR from a UNIX shell like git-for-windows: echo -n something | clip VBS w3school examples all show embedded in ASP HTML. For now I am interested in non-embedded VBS: file.vbs (lets system rules determine whether executed by cscript or wscript). Non-graphical: cscript //nologo file.vbs wscript file.vbs Diff: fc Multiple commands on line line (like UNIX ;): & (Definitely fg synchronous, not bg). Registry regedit reg query HKLM\Software\... Paths are always case-insensitive Filename search. Like UNIX find but if match a directory there is no way to prevent display of everything beneath it. dir /s wild%card.* tar works for direct and gzipped (-z) but bz2 (-j) unreliable xz (-J) only works if xz is present. Doesn't work with tar filename wildcards. To change file associations for opening (e.g. *.ps1 -> PowerShell) Interactive "Open with..." config can not pass params. registry: Computer\HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\Open\Command -> "C:\...\powershell.exe" "%1" but do "%1" "%2"... "%10" (N.b. %1 gets argv[0] and %2 gets first param, etc.) Amazingly useful file associations: (I believe this makes registry changes behind the scenes). http://vim.wikia.com/wiki/Windows_file_associations Requires admin. assoc .txt ftype txtfile="C:\path to *.exe" "%1" For some reason "%*" doesn't work here, must do: ... "%1" "%2", "3"... GOTCHA! PowerShell gets into loop if argv[0] isn't a *.ps1 script name, and can get in a loop. It is possible, but be careful when mapping non-*.ps1 to PowerShell. IPV4 config netsh interface ipv4 show config TO static: netsh interface ipv4 set address name="iface name" static 192.168.101.228 BACK t DHCP: netsh interface ipv4 set address name="iface name" dhcp CMD invocation: To invoke from Git for Windows, pass all parameters as a single token. CMD [/A|/U] [/Q] [/S] /C The command to run /S modifies the /C (or /K) behavior. Crazy rules about parsing of special characters in 'The command to run'. Essential Env vars: ERRORLEVEL [see gotcha below] USERNAME COMPUTERNAME for hostname CD ($PWD) HOMEDRIVE HOMEPATH USERPROFILE usually = %HOMEDRIVE%%HOMEPATH% APPDATA ~/AppData/Roaming LOCALAPPDATA ~/AppData/Local TEMP C:\Temp or C:\Windows\TEMP. Sometimes an ephemeral dir under LOCALAPPDATA MAJOR GOTCHA!!!! When invoke CMD scripts, the returned ERRORLEVEL is unreliable clip: LOADS clipboard just like (only) the input side of Linux xclip. Input only loaded from stdin; no direct input file supported.