Multiple shell commands in Windows - r

I'm trying to replicate a shell command in R and cannot figure out how to string commands together. This just returns the contents of the working folder (system() fails for some reason):
> shell("dir")
Volume info ..
Directory of E:\Documents\R
contents are listed..
Now lets try and navigate to C drive and run dir (without using the obvious dir C:)..
> shell("cd C:")
C:\
> shell("dir")
Volume in drive E is GT
etc..
So it seems commands can't be entered separately as the shell doesn't remember the working directory. So..
> (cmd = "cd C:
+ dir")
[1] "cd C:\ndir"
> shell(cmd)
C:\
No luck as the C: folders are not reported. Other methods I've tried also fail. Grateful for any ideas.

The documentation explains why system doesn’t work: it executes the command directly on Windows, without spawning a shell first.
shell (or better, system2) is the way to go but as you’ve noticed, shell will always spawn a new shell so that changes to the environment don’t carry over. system2 won’t work directly either since it quotes its commands (and thus doesn’t allow chaining of commands).
The correct solution in this context is not to use a shell command to change the directory. Use setwd instead:
setwd('C:')
system2('dir')
If you want to reset the working directory after executing the command, use the following:
local({
oldwd = getwd()
on.exit(setwd(oldwd))
setwd('C:')
system2('dir')
})

I'm on Linux and this works for me:
system("cd ..;ls")
in navigating to the previous directory and running ls/dir there. In your case, on Windows, this apparently works:
shell("cd C: & dir")
or to get the output as a character vector:
shell("cd C: & dir", intern=T) and on Linux: system("cd ..; ls", intern=T)

Don't know if this helps, but collapsing the commands to one string when using system works on MacOS
cmds <- c("ls", "cd ..", "ls");
system(paste(cmds, collapse=";"))

This is a solution from here. That solved my problem in calling the windows dir command:
system("cmd.exe /c dir", intern=TRUE)

Related

Running system() with git-bash in R

I checked
How to execute git-bash command with system() or shell() in R but this didn't exactly solve the problem for me. I'm very new to R, I'm using it on Windows and I'm modifying another project. I suspect originally this project was written for a different OS.
At one point, the main script calls a .sh file from inside R in a for loop, and uses system() to run it. The sh file creates a new directory, copies files from one directory to the other and modifies them slightly (removes first row & adds another).
The part in the code that calls the file goes like this: (run_this is the sh file we want to run)
directory_name = "data/clean"
for (i in 1:n) {
filename = sprintf("%s.json",i)
cmd = sprintf("run_this.sh %s %s", filename, directory_name)
system(cmd)
}
I suspect system() calls command prompt in Windows, which I've checked doesn't run this sh file. But I've found I can run them from Git Bash. Unfortunately I'd have to do them one by one if I choose this option and since n is large this doesn't work very well for me.
So, I'm wondering
1) is there any way to direct system() or system2() to use Git Bash from inside R? (I have Git Bash to my environment variables.)
2) any other possible solutions to run sh files from command prompt?

How to Execute R Script from Windows Command Prompt

I have the following added to my system path on Windows 10: C:\Program Files\R\R-3.4.3\bin\x64
Then I tried running from cmd prompt ~:> R myscript.R
ARGUMENT 'example_batch.R' ignored
It proceeded to an interactive session without any execution.
No idea how it seemed to work in this answer. I would prefer something this simple, as it is in Python.
The following works R -e "source('myscript.R')"
But I'll never remember this when I need it.
Lucas's solution gave me an error when run in Powershell/Windows termianl (which is now the default on Windows 11). It seems that when the executable dir is inside quotation marks (""), Powershell treats it as a string.
To execute Rscript.exe in Powershell, you need to add & before the dir
& "C:\Program Files\R\R-4.2.2\bin\Rscript.exe" "C:\PATH\TO\SCRIPT.r"
The best way I've found is by executing Rscript.exe (it's installed with R.exe inside R directory).
You can do:
"C:\Program Files\R\R-3.6.0\bin\Rscript.exe" D:\path\to\yourRfile.r arg1 arg2 arg3
The quotation marks ("") are necessary because dir name Program Files has space between it and Windows CMD wouldn't recognize it without quotation marks.
If you don't want to write R path, you can put R Path to your windows PATH environment variable. This way you could run like:
Rscript.exe D:\path\to\yourRfile.r arg1 arg2 arg3
If you have doubts how to add R path to Windows PATH environment variable, you can follow these instructions (they are for adding Java to PATH, but you can use for R, the idea is the same).

Space in argument causing errors in Windows Command Prompt

I'm trying to run an R script through the command prompt. My operating system is Windows 10. I'm having trouble running the code because there is a space in the file path of my argument. This is what I paste into the command prompt.
"C:\Program Files\R\R-3.4.3\bin\Rscript.exe" "C:\Users\Scott\Google Drive\RScriptsB\Bundle_Runner.R"
I get this error:
The filename, directory name, or volume label syntax is incorrect.
However, when I run it using a file path with no spaces, it runs fine.
"C:\Program Files\R\R-3.4.3\bin\Rscript.exe" "C:\Users\Scott\Desktop\Bundle_Runner.R"
The same behavior happens when I schedule the task through Task Scheduler: it doesn't work with the space, and it works when I remove the space from the file path.
I'm using Google Drive to sync work from multiple computers, so I'd like to be able to run my scripts using the file path with a space.
Any solutions?
FOR %%a IN ("C:\Users\Scott\Google Drive\RScriptsB\Bundle_Runner.R") DO "C:\Program Files\R\R-3.4.3\bin\Rscript.exe" %%~sa
would be my approach - the problem appears to be with R, not cmd.
Try this:
C:/PROGRA~1/R/R-3.4.3/bin/Rscript.exe "C:\Users\Scott\Desktop\Bundle_Runner.R"
Or
C:/PROGRA~1/R/R-3.4.3/bin/Rscript.exe C:/Users/Scott/Google~1/RScriptsB/Bundle_Runner.R
This is possibly related to an error reported at r-devel ("[Rd] Bug in RScript.exe for 3.5.0", https://stat.ethz.ch/pipermail/r-devel/2018-April/075869.html) that has been fixed the next day.
Perhaps the problem was already present in R 3.4.3 (you are using in your question).
Proposed workaround:
...add an extra first argument that has no space in it, e.g. Rscript --vanilla "foo bar.R"
To minimize the impact caused by --vanilla you could use
Rscript --no-save "foo bar.R"
instead (which just does not save the workspace at the end of the session).

Way to get jupyter server root directory

Consider following:
$ cd /home/mydir
$ jupyter notebook --port=8888
In plain English, I am running jupyter server from /home/mydir directory.
Is there a simple way to get this directory from within a notebook regardless if it's a R notebook or a Python notebook or whatever? Maybe there is some magic command or variable?
NOTE: getwd() is not an answer as it returns directory of a current notebook but not the jupyter server root.
I have a similar problem and found your post, although I don't see a viable solution yet. Eventually I did found a solution, although it works only because I only care about Linux and I only care about Python. The solution is this magic line:
J_ROOT = os.readlink('/proc/%s/cwd' % os.environ['JPY_PARENT_PID'])
(I put it in a module in my PYTHONPATH so that I can easily use it in any Python notebook.) See if it is good for you.
Remember that your iPtyhon is just a Python module, so you can execute any valid Python code in a cell. So, if you started your notebook and haven't executed any directory changes in your code, you should be able to retrieve your cwd with the following in a cell:
import os
os.getcwd()
But furthermore, you can execute shell commands in cells, so you can retrieve other information in the cell. For example:
!which jupyter
should give you the path to your jupyter executable.
Which then leads you to running something like:
!jupyter --paths
which should give you something similar to:
​
config:
/Users/yourdir/.jupyter
/usr/local/etc/jupyter
/etc/jupyter
data:
/Users/yourdir/Library/Jupyter
/usr/local/share/jupyter
/usr/share/jupyter
runtime:
/Users/yourdir/Library/Jupyter/runtime
Frankly I'm surprised that all this time later there is still no built-in way to do this. I have used Isaac To's solution on Linux but recently had to make a jupyter notebook portable to Windows as well. Simply using os.getcwd() is fragile because a cell using it to set your JUPYTER_ROOT_DIRECTORY can potentially be called again, after you have changed your working directory.
Here is what I came up with:
try:
JUPYTER_ROOT_DIRECTORY
except NameError:
JUPYTER_ROOT_DIRECTORY = os.getcwd()
I put it in one of the first couple cells with the initial import statements. If the cell gets called again, it will not re-set the variable value because the variable exists and does not throw an exception.
It should be noted that unlike Isaac To's solution it sets the value to the directory the current .ipynb was run from, which is not necessarily the same directory as the top-level dir the user can access in the left hand file pane.
My suggestion is to use an intuitive approach.
Create a new folder within the Jupyter environment with a very unique name, for example, T246813579.
You can now locate the Jupyter working path by searching in your file explorer. For example, you can use the Windows Explorer in order to locate your new folder.
The expected result should look something like this:
C:\Users\my_user_name\JupyterHome\T246813579
The answer from #Isaac works well for Linux, but not all systems have /proc. For a solution that works on macOS and Linux, we can use shell commands, taking advantage of the ! shell assignment syntax in Jupyter:
import os
JPY_ROOT = ! lsof -a -p {os.environ['JPY_PARENT_PID']} -d cwd -F n | tail -1 | cut -c 2-
JPY_ROOT = JPY_ROOT[0]
print(JPY_ROOT) # prints Jupyter's dir
Explanation:
Get the process ID (pid) of the current jupyter instance with os.environ['JPY_PARENT_PID']
Call lsof to list the process's open files, keeping only the current working dir (cwd)
Parse the output of lsof using tail and cut to keep just the directory name we want
The ! command returns a list, here having only one element
Alternate Version
To save the os import, we could also use shell commands to get the PID. We could also do the subsequent string wrangling in python, rather than calling tail and cut from the shell, as:
JPY_ROOT = ! lsof -a -p $(printenv | grep JPY_PARENT_PID | cut -d '=' -f 2) -d cwd -F n
JPY_ROOT = JPY_ROOT[2][1:]

Use cmd commands in QT

Hi i was checking and anyone can use commands very similar in cmd like dir mkdir etc.
But for example when i try to use command (cd ..) i couldn't
QProcess consola;
consola.start("cmd.exe /C " + comando);
consola.waitForFinished();
consola.waitForReadyRead();
This is the question how i can use more commands in cmd for qt for example.
At least from the command line:
cmd /C "cd \"
works as did directories other than root. (Note the parenthesis around the command since it contains embedded spaces.) However, this example isn't very useful because this executes the command shell, changes the directory in that command shell, and then the command shell disappears, and your current directory is back to where you started.
I recommend looking into the QDir class, which has methods such as "current ()" and "setCurrent ()" for getting and setting the current directory. There are equivalents for mkdir and many others. Also, using QDir is much more cross-platform friendly, where using the "cmd" shell is Windows-specific.
You don't say what you're trying to accomplish, so beyond that suggestion, it's impossible to know how to best help you.
Your process's current directory can be and mostly is different than current directory of your is running. Please read chdir manpage for that.
That command is mostly working but changing the current directory of your process.

Resources