{"id":4801,"date":"2013-02-19T11:56:03","date_gmt":"2013-02-19T10:56:03","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=4801"},"modified":"2013-02-19T12:21:50","modified_gmt":"2013-02-19T11:21:50","slug":"my-notes-on-windows-command-line-batch-scripting","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=4801","title":{"rendered":"My notes on Windows command line batch scripting"},"content":{"rendered":"<p>From time to time I find myself having to write or modify windows batch files.\u00a0 Sometimes it might be better to use PowerShell, VBScript or Python\u00a0but other times a simple batch script will do fine.\u00a0 As I&#8217;ve been writing these scripts, I&#8217;ve kept notes on how to do things for future reference.\u00a0 Here&#8217;s a summary of these notes.\u00a0 They were written for my own personal use and I put them here for my own convenience but if you find them useful, or have any comments or corrections, that&#8217;s great.<\/p>\n<p>These notes were made for Windows 7 and may contain mistakes, please let me know if you spot any.\u00a0 If you use any of the information here, we agree that its not my fault if you break your Windows installation.\u00a0 No warranty and all that.<\/p>\n<p>These notes are not meant to be a tutorial.<\/p>\n<p><strong>Comments<\/strong><\/p>\n<p>Comments in windows batch files start with REM. Some people use :: which is technically a label. Apparently using :: can result in faster script execution (See <a href=\"http:\/\/xset.tripod.com\/tip3.htm\">here<\/a> and <a href=\"http:\/\/www.robvanderwoude.com\/comments.php\">here<\/a>). I&#8217;ve never checked.<\/p>\n<pre>REM This is a comment\r\n:: This is a comment too...but different. Might be faster.<\/pre>\n<p><strong>If statements<\/strong><\/p>\n<pre>If \"%foo%\"==\"bar\" (\r\nREM Do stuff\r\nREM Do more stuff\r\n)\r\nelse (\r\nREM Do different stuff\r\n)<\/pre>\n<p><strong>Check for existence of file<\/strong><\/p>\n<pre>if exist {insert file name here} (\r\n    rem file exists\r\n) else (\r\n    rem file doesn't exist\r\n)<\/pre>\n<p>Or on a single line (if only a single action needs to occur):<\/p>\n<pre>if exist {insert file name here} {action}<\/pre>\n<p>for example, the following opens notepad for autoexec.bat, if the file exists:<\/p>\n<pre>if exist c:\\autoexec.bat notepad c:\\autoexec.bat<\/pre>\n<p><strong>Echoing and piping output<\/strong><br \/>\nTo get a newline in echoed output, chain commands together with &amp;&amp;<\/p>\n<pre>echo hello &amp;&amp; echo world<\/pre>\n<p>gives<\/p>\n<pre>hello\r\nworld<\/pre>\n<p>To pipe output to a file use &gt; or &gt;&gt; The construct 2&gt;&amp;1 ensures that you get both standard output and standard error in your file<\/p>\n<pre>REM &gt; Clobbers log.txt, overwriting anything you already have in it\r\n\"C:\\SomeProgram.exe\" &gt; C:\\log.txt 2&gt;&amp;1\r\n\r\nREM &gt;&gt; concatenates output of SomeProgram.exe to log.txt\r\n\"C:\\SomeProgram.exe\" &gt;&gt; C:\\log.txt 2&gt;&amp;1<\/pre>\n<p><strong>Environment Variables<\/strong><\/p>\n<p>set and setx<\/p>\n<ul>\n<li>set &#8211; sets variable immediately in the current\u00a0context only.\u00a0 So, variable\u00a0will be lost when you close cmd.exe.<\/li>\n<li>setx &#8211; sets variable permanently but won&#8217;t be valid until you start a new context (i.e. open a new cmd.exe)<\/li>\n<\/ul>\n<p>List all environment variables defined in current session using the set command<\/p>\n<pre>set<\/pre>\n<p>To check if the environment variable FOO is defined<\/p>\n<pre>if defined FOO (\r\n echo \"FOO is defined and is set to %FOO%\"\r\n)<\/pre>\n<p>To permanently set the system windows environment variable FOO, use setx \/m<\/p>\n<pre>setx FOO \/m \"someValue\"<\/pre>\n<p>To permanently unset the windows environment variable FOO, set it to an empty value<\/p>\n<pre>setx FOO \"\"<\/pre>\n<p>A reboot may be necessary. Strictly speaking this does not remove the variable since it will still be in the registry and will still be visible from <strong>Control Panel-&gt;System-&gt;Advanced System Settings-&gt;Environment variables<\/strong>. However, the variable will not be listed when you perform a<strong> set<\/strong> command and <strong>defined FOO<\/strong> will return false.\u00a0 To remove all trace of the variable, delete it from the registry.<\/p>\n<p><strong>Environment variables in the registry<\/strong><\/p>\n<p>On Windows 7:<\/p>\n<ul>\n<li>\u00a0System environment variables are at HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment<\/li>\n<li>\u00a0User environment variables are at HKEY_CURRENT_USER\\Environment<\/li>\n<\/ul>\n<p>If you change environment variables using the registry, you will need to reboot for them to take effect.<\/p>\n<p><strong>Pausing<\/strong><br \/>\nThis command will pause for 10 seconds<\/p>\n<pre>TIMEOUT \/T 10<\/pre>\n<p><strong>Killing an application<\/strong><\/p>\n<p>This command will kill the notepad.exe window with the title Readme.txt<\/p>\n<pre>taskkill \/f \/im notepad.exe \/fi \"WINDOWTITLE eq Readme.txt\"<\/pre>\n<p><strong>Time stamping<\/strong><\/p>\n<p>The variable %time% expands to the current time which leads you to do something like the following to create time stamps between the execution of commands.<\/p>\n<pre>echo %time%\r\ntimeout \/t 1\r\necho %time%<\/pre>\n<p>This works fine unless your code is in a block (i.e. surrounded by brackets), as it might be if it is part of an if-statement for example:<\/p>\n<pre>(\r\necho %time%\r\ntimeout \/t 1\r\necho %time%\r\n)<\/pre>\n<p>If you do this, the echoed time will be identical in both cases because the %time% entries get parsed at the beginning of the code block. This is almost certainly not what you want.<\/p>\n<pre>Setlocal EnableDelayedExpansion\r\n(\r\necho !time!\r\ntimeout \/t 1\r\necho !time!\r\n)<\/pre>\n<p>Now we get the type of behaviour we expect.<br \/>\n<strong><\/strong><\/p>\n<p><strong>Where is this script?<\/strong><\/p>\n<p><strong><\/strong>Sometimes your script will need to know where it is.\u00a0 Say test.bat is at C:\\Users\\mike\\Desktop\\test.bat and contains the following<\/p>\n<pre>set whereAmI=%~dp0<\/pre>\n<p>When you run test.bat, the variable whereAmI will contain C:\\Users\\mike\\Desktop\\<\/p>\n<p>Details on %dp0 can be <a href=\"http:\/\/stackoverflow.com\/questions\/5034076\/what-does-dp0-mean-and-how-does-it-work\">found at StackOverflow<\/a>.<\/p>\n<p><strong>V<\/strong><strong>ariable substrings<\/strong><br \/>\nThis came from StackOverflow&#8217;s <a href=\"http:\/\/stackoverflow.com\/questions\/245395\/hidden-features-of-windows-batch-files\">Hidden features of Windows batch files<\/a>\u00a0which is a great resource.\u00a0 They&#8217;ve tightened up on what\u00a0constitutes\u00a0a &#8216;valid question&#8217; these days and so great Q+A such as this won&#8217;t be appearing there in future.<\/p>\n<pre>&gt; set str=0123456789\r\n&gt; echo %str:~0,5%\r\n01234\r\n&gt; echo %str:~-5,5%\r\n56789\r\n&gt; echo %str:~3,-3%\r\n3456<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>From time to time I find myself having to write or modify windows batch files.\u00a0 Sometimes it might be better to use PowerShell, VBScript or Python\u00a0but other times a simple batch script will do fine.\u00a0 As I&#8217;ve been writing these scripts, I&#8217;ve kept notes on how to do things for future reference.\u00a0 Here&#8217;s a summary [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7,69,66],"tags":[],"class_list":["post-4801","post","type-post","status-publish","format-standard","hentry","category-programming","category-software-deployment","category-windows"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-1fr","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/4801","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4801"}],"version-history":[{"count":13,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/4801\/revisions"}],"predecessor-version":[{"id":4851,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/4801\/revisions\/4851"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4801"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}