Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit from Command prompt after running r script

Tags:

r

batch-file

I am running one R script through command prompt (CMD window) but CMD window staying open after executing all batch command. I want to close it (CMD window) after executing R Script.

@ECHO OFF
START cmd.exe /k "cd C:\ABCD\" & Rscript working.r & exit

I am running above code for it but last commands exit doesn't work for me.

Did I miss something on the above code?

like image 844
Ghanshyam Savaliya Avatar asked Jan 01 '23 12:01

Ghanshyam Savaliya


2 Answers

  • You only enclosed cd C:\ABCD in "; you have to double-quote the whole sequence of commands.
  • Use the && operator, so that the script will fail if path C:\ABCD doesn't exist.

cmd /k option (run, and keep the cmd open):

start cmd.exe /k "cd /d C:\ABCD\ && Rscript working.r"

cmd /c option (run, then close the cmd window):

start cmd.exe /c "cd /d C:\ABCD\ && Rscript working.r"

The cd's /d option is used to change drive (if that's needed) in addition to the folder.

Reference: CMD.exe on SS64.

like image 83
double-beep Avatar answered Jan 04 '23 02:01

double-beep


1. Meaning of the Windows command processor option /k

The Windows command processor option /K is for running a command line and then keeps running the Windows command processor cmd.exe for interactive use by a user or just seeing the output of the executed command line.

The option /C is for running a command line and then the Windows command processor closes itself which means the console window with the output is closed too.

That is explained by the usage help of cmd.exe which can be read by opening a command prompt and running cmd /?. There is also the Microsoft documentation page for cmd explaining these two options.

2. Meaning of the Windows command processor operator &

There is single line with multiple commands using Windows batch file explaining in full details the unconditional command operator & as well as the conditional command operators && and || on being recognized by the Windows command processor outside a double quoted argument string.

The unconditional command operator & is for specifying multiple commands on one command line to execute one after the other by cmd.exe independent on success or failure of the previous executed command.

So the command line

START cmd.exe /k "cd C:\ABCD\" & Rscript working.r & exit

is interpreted by cmd.exe processing the batch file as it would be written in the batch file:

START cmd.exe /k "cd C:\ABCD\"
Rscript working.r
exit

The goal of the batch file is to change the current directory to C:\ABCD\, run Rscript.exe with the argument working.r to process this R script in the directory C:\ABCD\ and keep the console window opened for viewing the output while the console window opened on starting the batch file should be closed automatically after starting Rscript.exe. But the used command line does something completely different as explained in full details in chapter 5 below.

3. Solutions to run R script working.r in C:\ABCD

The goal to run R script working.r in directory C:\ABCD with keeping the console window opened with the output of the R script could be achieved with:

@echo off
title Run R script working.r
cd /D "C:\ABCD\"
if not errorlevel 1 Rscript.exe working.r
pause

These command lines do following:

  1. The CMD internal command ECHO is used to turn off command echo mode which is enabled by default on execution of a batch file resulting in displaying a command line to execute after parsing and processing it immediately before execution.
    @ at beginning of this line results in not printing this first command line of the batch file to the console window after processing and before executing it.
  2. The CMD internal command CD changes the current directory for the running Windows command process to the specified directory with using option /D to change also the current drive if that is necessary too.
    That works for all directory paths with a drive letter and a colon at the beginning, but not for a UNC path starting with \\ServerName\ShareName\ because of cmd.exe does not permit by default making a directory accessed with a UNC path the current directory for compatibility with executables not supporting such a directory path as current directory.
  3. If the execution of command CD was successful indicated with exit value 0, the Windows command processor searches for a file with name Rscript.exe in current directory and next in the directories listed in environment variable PATH using the file extensions listed in environment variable PATHEXT and if that file is really found, runs Rscript.exe using its fully qualified file name (drive + path + name + extension) with passing working.r as argument to the executable.
    The search for Rscript.exe and its execution is not done on CD exits with value 1 indicating an error, for example if the directory C:\ABCD was deleted in the meantime. CD outputs in this case an error message to handle STDERR (standard error) which can be seen in the console window.
  4. The command PAUSE halts processing of the batch file until the user presses any key so that all output written to the console window can be viewed by the user even on having started the execution of the batch file by double clicking on it in Windows File Explorer.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • cd /?
  • echo /?
  • if /?
  • pause /?
  • title /?

See also:

  • How does the Windows Command Interpreter (CMD.EXE) parse scripts?
  • Single line with multiple commands using Windows batch file
  • What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?

There are also multiple other solutions possible.

A shorter version of above:

@echo off
title Run R script working.r
cd /D "C:\ABCD\" && Rscript.exe working.r
pause

Another single line solution starting one more command processor:

@start "Run R script working.r" /D "C:\ABCD" %ComSpec% /D /K Rscript.exe working.r

This single command line results in

  • starting the Windows command processor cmd.exe using its fully qualified file name as defined by the system environment variable ComSpec
  • with option /D to ignore the AutoRun command in Windows registry if existing at all and
  • with option /K as explained in chapter 1
  • as separate task in a new console window with the window title Run R script working.r and
  • with C:\ABCD as current directory for the started cmd.exe which has to
  • search for file Rscript.exe and if found execute it with R script file name working.r as first and only argument with current directory C:\ABCD as defined for cmd.exe.

For help on command START run in a command prompt window start /?.

One more single line solution is:

@start "Run R script working.r" /D "C:\ABCD" %SystemRoot%\System32\cmd.exe /D /K Rscript.exe working.r

This is the same as the single command line version above with just the small difference that %SystemRoot%\System32\cmd.exe is used instead of %ComSpec% which in fact is defined by default with exactly that string as system environment variable.

Last but definitely not least can be used also the single command line:

@start "Run R script working.r" %SystemRoot%\System32\cmd.exe /D /S /K "cd /D "C:\ABCD" && Rscript.exe working.r"

This solution becomes a nightmare if the directory path of file working.r contains itself the character & as in this case the ampersand in directory path must be escaped with ^ left to & as the command line is processed by two cmd.exe. The cmd.exe instance processing the batch file has to interpret all ampersands on the command line as literal characters while & in directory path has to be interpreted as literal character and && as conditional AND operator by the second cmd.exe.

Example of last solution with & in directory path:

@start "Run R script working.r" %SystemRoot%\System32\cmd.exe /D /S /K "cd /D "C:\Temp\Development ^& Test" && Rscript.exe working.r"

That is much more complex than:

@start "Run R script working.r" /D "C:\Temp\Development & Test" %SystemRoot%\System32\cmd.exe /D /K Rscript.exe working.r

4. Alternative solution not using a batch file at all

The execution of an executable like Rscript.exe with one or more arguments in a specific directory used as current directory with using the Windows command processor to see the output can be done also using a Windows .lnk shortcut file instead of a batch file which has multiple advantages in comparison to the batch file solution.

The shortcut file for executing Rscript.exe with working.r as argument in directory C:\ABCD can be created using the following steps:

  1. Browse in Windows File Explorer to the directory System32 in the Windows directory containing cmd.exe which is usually C:\Windows\System32.
  2. Click with secondary (right) pointing device (mouse) button on the file cmd.exe to open the context menu and click in submenu Send to on the menu item Desktop (create shortcut).
  3. Switch to the Windows desktop which has now an additional shortcut file with name cmd.exe.lnk whereby the file extension .lnk is not visible, just the file name cmd.exe.
  4. Click with secondary (right) pointing device (mouse) button on cmd.exe and click in opened context menu on menu item Rename to change the file name for example to Run R Script resulting in shortcut file being rename to Run R Script.lnk.
  5. Click with secondary (right) pointing device (mouse) button on Run R Script and click in opened context menu on last menu item Properties.
  6. There is opened the Properties dialog window with by default selected tab Shortcut. On this tab must be modified first the property Target on which to append a space character and the string /D /K Rscript.exe working.r. Well, even better would be appending after a space the string /D /K "C:\Full Path\Rscript\Rscript.exe" working.r so that cmd.exe does not need to search for file Rscript.exe with using the environment variables PATH and PATHEXT.
  7. There must be next modified the property Start in where C:\ABCD must be entered as this is the directory which should be the current directory on starting first cmd.exe and next Rscript.exe because of containing the R script file working.r. The Start in directory path should be defined always without double quotes even on containing a space or one of these characters &()[]{}^=;!'+,`~ as this string is not processed by the started cmd.exe as explained below in chapter 5.

There can be modified also other properties of the shortcut file. There can be defined a Shortcut key like Ctrl + Alt + R to able to execute the R script working.r in C:\ABCD by pressing this combination of keys independent on which application has currently the input focus. There can be added a Comment like Run R script working.r in C:\ABCD displayed as tooltip when the pointing device pointer is positioned over the shortcut on Windows desktop. A nice icon can be selected for this shortcut and a different font or font size can be set, etc.

The last step is clicking on button OK to save the changed shortcut properties.

The shortcut file can be kept on Windows desktop, but could be moved or copied also into the Windows start menu or pinned on the Windows taskbar as it can be done with any shortcut file.

So with usage of a shortcut file the execution of the R script can be simplified, especially on having a shortcut key defined too. The font and font size can be changed to see output larger than usually in a command prompt window. A nice icon could be selected displayed in the Windows taskbar while the R script is running, etc.

5. How is the batch file processed as posted in the question?

The batch file as posted in the question is most likely executed by double clicking on it. For that reason explorer.exe is most likely the first executable processing the batch file.

5.1 Processing of the batch file by explorer.exe

A batch file with file extension .bat or .cmd is a text file and does not contain itself CPU instructions. Therefore the Windows File Explorer has to find out first what to do with the double clicked batch file. So it searches in the Windows registry under various keys how to open a file with file extension .bat or .cmd depending on which file extension the batch file has.

  1. The Windows File Explorer finds the key HKEY_CLASSES_ROOT\.bat with the default string batfile of type REG_SZ.
  2. There is next looked for registry key HKEY_CLASSES_ROOT\batfile\shell\open\command with the default string "%1" %* of type REG_SZ.
    Batch files are registered different to other file extensions. There is usually configured for the Windows shell command open of a file extension the fully qualified file name of the executable to use with %1 as placeholder for the fully qualified name of the double clicked file enclosed in double quotes.
    Example for .txt file extension: HKEY_CLASSES_ROOT\.txt has the default string txtfile and referencing therefore HKEY_CLASSES_ROOT\txtfile\shell\open\command with the default string %SystemRoot%\system32\notepad.exe %1 of type REG_EXPAND_SZ instead of REG_SZ as containing an environment variable reference.

The above sequence of registry accesses is extremely simplified as otherwise it would be really too long to list all registry accesses made by explorer.exe to find out what to do with the double clicked batch file.

There is called finally by explorer.exe the Windows library function CreateProcess. This function has multiple parameters and it is really worth for any programmer working on Windows to read the documentation of this function and of the structure STARTUPINFO.

Most of the properties of a shortcut file just define how CreateProcess is called by explorer.exe with which data set in the structure STARTUPINFO.

Most of the options supported by the CMD internal command START just define the data to pass to CreateProcess by cmd.exe.

Some examples:

  • Function parameter lpCurrentDirectory is a long pointer to a string with the current directory to set for the process to create. If this pointer is a null pointer, CreateProcess uses the current directory of the process which creates the new process. Otherwise the specified string is interpreted as path of the current directory for the new process. The shortcut property Start in is the string passed by explorer.exe using lpCurrentDirectory to function CreateProcess. The string after option /D of command START of CMD is the string passed without the double quotes by cmd.exe using lpCurrentDirectory to function CreateProcess.
  • The structure STARTUPINFO has the element dwFlags which is a bitfield with one bit being STARTF_USESHOWWINDOW. cmd.exe runs a Windows console application like Rscript.exe specified in a batch file by default using CreateProcess with this bit in dwFlags in STARTUPINFO passed with a pointer to CreateProcess with the value 0. So no new console window is opened on running Rscript.exe. But on using command START the flag STARTF_USESHOWWINDOW has always the value 1 on CreateProcess being called by cmd.exe to run the application always with a new window. explorer.exe sets always STARTF_USESHOWWINDOW.
  • The structure STARTUPINFO has the elements hStdInput, hStdOutput and hStdError which are defined by cmd.exe depending on a console application like Rscript should use the standard input, standard output and standard error streams of cmd.exe or new streams should be created by CreateProcess for this application which is one more difference between running Rscript.exe directly from within a batch file or using the command START.

Every Windows executable capable of running one more Windows executable calls CreateProcss in the Windows kernel library kernel32.dll. So it is really useful for every Windows programmer to have knowledge about this function, which data can be passed to it and how it works.

So finally explorer.exe uses CreateProcess to run, for example:

C:\Windows\System32\cmd.exe /c ""C:\Users\UserName\Desktop\RunRscript.bat" "

A new console window is opened by CreateProcess as requested by explorer.exe by using by default the options as stored under registry key HKEY_CURRENT_USER\Console on starting cmd.exe with option /c to process the double clicked batch file and then close itself.

5.2 Processing of the batch file by cmd.exe

The Windows command processor first parses the argument strings passed to it by explorer.exe which are /c and a command line to execute enclosed in " whereby the first and the last " are removed to have finally just the fully qualified file name of the batch file enclosed in double quotes.

For that reason the Windows command processor opens the batch file, reads the first line, parses it, finds out that no more line must be read, closes the batch file and executes the first command line which is @ECHO OFF resulting in turning off the command echo mode.

Next cmd.exe opens the batch file again, sets the file pointer to beginning of second line, reads that line, parses it, finds out that no more line must be read, closes the batch file and splits up internally the command line

START cmd.exe /k "cd C:\ABCD\" & Rscript working.r & exit

to the following commands added to its internal command queue:

START cmd.exe /k "cd C:\ABCD\"
Rscript working.r
exit

So there are three commands to execute next independent on the execution results of each previous command.

5.2.1 Starting one more cmd.exe as separate task

The first command to execute is the internal command START. So cmd.exe parses the arguments as described for the command START.

There is defined neither a window title string nor any other START specific option. So the first argument cmd.exe is the application name to pass to CreateProcess. But the path is missing and for that reason cmd.exe processing the batch file has to search first for this file.

There is most likely no cmd.exe in current directory. So the first folder path from the environment variable PATH is used next to search for cmd.exe. The Windows default is %SystemRoot%\System32 as first folder path of PATH and this directory contains indeed cmd.exe. So the search for the fully qualified file name of cmd.exe could be finished quickly and the application name string passed to function CreateProcess by using the function parameter lpApplicationName is defined completely.

All other arguments after cmd.exe are to pass to CreateProcess as string with using the pointer lpCommandLine.

Therefore cmd.exe processing the batch file now calls CreateProcess with C:\Windows\System32\cmd.exe as application name, the string /k "cd C:\ABCD\" as command line, a null pointer for the current directory, a null pointer for the environment, etc. to start one more cmd.exe running parallel to current cmd.exe process with its own console window and its own standard input, standard output and standard error streams.

The cmd.exe process processing the batch file gets back from CreateProcess a nonzero value for successful creation of the process. So it continues with the next command in its internal command queue while the started cmd.exe is running now parallel.

5.2.2 Calling Rscript with the argument working.r

The next command in internal command queue of cmd.exe processing the batch file is:

Rscript working.r

Rscript is not an internal command of CMD. So this string is interpreted as executable or script file name which must be first found at all as specified with just the file name without full path and without file extension. Therefore cmd.exe uses again the environment variables PATH and PATHEXT to find a program/script file with that name and finds most likely indeed Rscript.exe in right directory.

There is to call again CreateProcess, but this time the application name is Rscript.exe with its full path, the command line is the string working.r, lpEnvironment is again a null pointer (as used always with a null pointer by cmd.exe), lpCurrentDirectory is a null pointer, etc. The difference is that this time Rscript.exe is not started as separate task with its own window, standard streams, etc. Rscript is called by cmd.exe.

Therefore Rscript.exe runs now and processes the command line. If the file working.r is found at all, cannot be determined by the provided information in the question. If the R script file is in same directory as the batch file, then the inheritance of the current working directory as defined by explorer.exe starting cmd.exe to process the batch file and cmd.exe on starting Rscript.exe to process the R script file results in a by chance working execution of the R script file now. Otherwise Rscript.exe exits most likely with an error as the file working.r could not be found in the current directory.

After Rscript.exe finished without or with execution of working.r, the Windows command processor instance processing the batch file continues with its internal command queue.

5.2.3 Exiting the Windows command processor

The remaining command in the internal command queue is exit which is an internal command of CMD. It instructs to immediately exit itself without further processing the batch file. So cmd.exe processing the batch file closes itself now.

5.3 Processing of second started cmd.exe

The cmd.exe process started by cmd.exe processing the batch file processes first its arguments.

There is the option /k to instruct cmd.exe to execute the command line specified with the next argument(s) and then to keep running.

The command line to execute is cd C:\ABCD\ whereby CD is recognized as internal command of CMD and C:\ABCD\ as the directory path.

The command CD is executed and if the current drive is the drive C:, the current directory is changed now for the second cmd.exe process while the first cmd.exe process is searching parallel for Rscript.exe.

There is nothing more to do for second cmd.exe, but it keeps running for user interactions.

The console window of second cmd.exe remains open with a prompt indicating C:\ABCD as current directory and waiting for user input.

like image 35
Mofi Avatar answered Jan 04 '23 00:01

Mofi