Detect OS and change the path appropriately in R - linux

I have two operating systems installed on my computer - windows and linux. When I write my scripts in windows and then I try to run them on linux, I have to change every path.
For example, to set my working directory in windows, I have to type setwd("d://MyStatistics").
However, in linux, this command is setwd("/media/55276F9D5951EC83/MyStatistics").
Is it possible to automatically detect current operation system and change the path if it is from the other system?

Use an if condition which tests R.version$platform or .Platform$OS.typ.
# It's as simple as...
path <- "/media/55276F9D5951EC83/MyStatistics"
if( .Platform$OS.type == "windows" )
path <- "d:\\MyStatistics"
setwd( path )

This link would be helpfull.
Sys.info() returns details of the platform R is running on

You could potentially achieve your "one path fits all" aim easily if both systems have the same sets of folders in one place (edit: just re-read the question, and since your talking about one computer, this should be the case). You could then either set that location as the working directory at the beginning of your script, using a method like Roland's answer, or make it the default directory that R opens with by adding it to Rprofile.site in each OS. You could then just set working directories by pasting to the initial directory.
Something like:
#add line to Rprofile.site for both OS
setwd("/path/to/folder/containing/data/folders")
then in the script:
starting.directory = getwd() #at beginning of script
setwd(paste0(starting.directory, "/MyStatistics"))
You could also add "starting.directory" as an object in Rprofile.site instead:
#add line to Rprofile.site for both OS
starting.directory <- "/path/to/folder/containing/data/folders"
then use the same paste0 as above.
You could also alter Rprofile.site in both OS to contain objects with names of various working directories, which point to the same folder with OS specific paths so that they can just be referred to as "setwd(myStatsDirectory)", and pasted to as above. Maybe the best way is to do something like that for every drive you'd like to be able to use with both systems, so you could do something like:
setwd(D.Drive)
setwd(paste0(D.Drive, "/folder1/folder2/etc"))
(edit: this is a similar method to Simon O'Hanlon's comment on Roland's answer, using tilde with the home directory)

Related

How can I find all the versions of a Unix program on a system?

This came up in coursework, and I'm stuck:
Many systems have more than one version of a utility program so that users can choose the one they want. Suggest a command to find all the versions of make on a system. What determines which one a user actually gets? How might a user override the defaults?
How would you do that?
How UNIX finds programs
Unix-like systems store their executable programs in various directories for historical reasons.
The directories that are searched when you want to run a command are stored in an environment variable called $PATH, separated by colons (:). To see its contents, type echo "$PATH" in a terminal window. On my system, that shows (split to avoid a long line)
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:
/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
They're searched in that order. If I want to run make, the system will first check /usr/local/sbin/make (which doesn't exist), then /usr/local/bin/make (also non-existant), then /usr/bin/make (which does exist, so it runs that).
How to figure out which one would run
The program which can be used to look through $PATH to figure out what program would be chosen. Running which make on my system produces the output /usr/bin/make.
Conveniently, which has a -a flag to print all executables that match, not just the first one. (I found this by consulting its manual, by running man which.) So which -a java should tell you where all of the versions of java are.
Changing the defaults
If you like, you can change the contents of the $PATH variable, like you can change any environment variable: If I run PATH="$PATH:/home/anko/bin", the next time the system needs to find a program, it will check through all of what $PATH used to be, plus a directory called bin in my home directory if it couldn't find anything else.
I could also prepend the directory, to make it take precedence over anything else, by doing PATH="/home/anko/bin:$PATH".

How to get gdb on Linux to find source file for binary cross compiled on windows

I am trying to debug an application that is cross-compiled on a Windows host for a Linux target.
The problem:
Because the initial compilation is in windows the stored source file paths in the binary is of the form C:\Users\foo\project\.... On the Linux target I have put the source files under \home\foo\project\.... By default gdb does not find the source file because of the different path.
What I have tried so far:
Use "directory" command in gdb to give an exact path for the .c source file in the target Linux system where the app is being debugged. This works but unfortunately there are literally hundreds of files so this solution is unrealistic.
Use the set substitute-path C:\\Users\\foo\\project /home/foo/project command to have gdb substitute all prefixes. Note that the \\ seems necessary such that show substitute-path registers the right string. This unfortunately does not work. My guess is that the substitute-path command does not handle ms-dos style paths.
Tried separating the debug info out into a separate .debug file (see How to generate gcc debug symbol outside the build target?) and then using debugedit to change the paths with the command debugedit --base-dir=C:\Users\foo --dest-dir=/home/foo project.debug. Unfortunately this does not work either. debugedit seems to work fine if the existing path is all UNIX/Linux like but doesn't seem to work with ms-dos style paths.
I have looked around stackoverflow and while there are similar topics I can't find anything that will help me. Would really appreciate any suggestions/help. I realize that cross compiling from Windows is a very roundabout way but can't avoid that for the moment.
Thanks
Although it's rather old question, I did encountered the same problem. I managed to resolve it but using sed on binary executable... (yeah, a 'bit' hack-ish, but did not found another way). With sed I've managed to replace symbols paths right inside the executable, the trick is that new path's length should be the same as the old one.
sed -i "s#C:/srcpath#/srcpath/.#g" ./executable
Be sure to make new path the same length, otherwise the executable will brake.
I also have this same problem. Your option 1 isn't as bad as you think because you can script creating all the 'directory' commands with something like this python code:
def get_directory_paths():
return_array = list()
unix_path = os.path.join('my','unix','path')
for root, dirs, files in os.walk(unix_path):
for dir in dirs:
full_unix_path = os.path.join(root,dir)
escaped_unix_path = re.sub("\s", "\\\\ ", full_unix_path)
return_array.insert(0, "directory " + escaped_unix_path)
return '\n'.join(return_array)
The downside is that if you have two source files with the same name in different directories, I don't think gcc can pick the right one. That worries me, but in my particular situation, I think I'm safe.
For option 2 (which I suspect would fix the aliasing condition from #1), I think the problem is that the substitutions are not ending with a "file separator" according to the linux so they aren't applied:
To avoid unexpected substitution results, a rule is applied only if the from part of the directory name ends at a directory separator. For instance, a rule substituting /usr/source into /mnt/cross will be applied to /usr/source/foo-1.0 but not to /usr/sourceware/foo-2.0. And because the substitution is applied only at the beginning of the directory name, this rule will not be applied to /root/usr/source/baz.c either." (from https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath )
I haven't tried anything like your #3 and I also considered something like #dragn suggestion, but in my situation the paths are not even close to the same length, so that will be an issue.
I think I'm stuck with #1 and a script, but if anyone has other suggestions, I'm interested options :-)

Linux function name conflict MATLAB

I'm currently using a MATLAB software suite which includes a function called "Swap". Running this code on my personal machine runs just fine, but when attempting to run on a Linux server, it seems to be trying to use the built-in "Swap" function on the Linux terminal.
Is there some way that I can force the terminal to ignore this built-in Swap and simply call the "Swap" function which is part of the MATLAB suite?
Thanks!
Assumptions: When you said built-in "Swap" function on the Linux terminal, I am assuming you are talking about running MATLAB on the linux terminal itself. I am also assuming that the built-in swap command is something from the MATLAB platform and not the linux environment and this answer is based on these assumptions.
In a general case, when you would like to add a function file whose name is identical to an already exisiting function, you have to move the path of the function file to be added to somewhere above the path of the existing function file in the list of MATLAB search paths. The way it works is that when you mention the use of a function, MATLAB starts looking for a match from the top until the bottom of the list.
One can view the MATLAB search paths by running -
path
So, to answer your question, just add the path of the suite to the top of MATLAB search paths by using addpath -
addpath(PATH_TO_SUITE);
If PATH_TO_SUITE has subdirectories, one of which has the swap function file, use genpath along with addpath -
addpath(genpath(PATH_TO_SUITE));
This could be interesting too for you to follow - Access m-files in a subfolder without permanently adding it to the path.

Path variable: Find folder path of specific file

On Linux and other Unix-likes, how do I find the path to a specific file that I can use because of the PATH environment variable? For example, if I can use, from the command line:
ls # technically the file name is "ls.exe"
is there a way I can find the path of the ls.exe file explicitly without looking through the PATH variable myself (i.e. maybe have a program search through it but not look myself)?
I understand there are many pitfalls/caveats of doing this, for example a PATH can be a file or even part of a file (I think), plus symlinks, etc. could make it unreliable, but I'm looking for general use cases.
The reason I am asking is I have Windows with msysgit so I have A LOT of folders in my path, and searching every one would be annoying & time-consuming, not to mention harder because of Windows limitations, but I can still presumably use almost anything Linux can use.
$ type ls.exe
ls.exe is /usr/bin/ls.exe

What is PATH on a Mac (UNIX) system?

I'm trying to setup a project, storm from git:
https://github.com/nathanmarz/storm/wiki/Setting-up-development-environment
Download a Storm release , unpack it, and put the unpacked bin/ directory on your PATH
My question is: What does PATH mean? What exactly do they want me to do?
Sometimes I see some /bin/path, $PATH, or echo PATH.
Can someone explain the concept of PATH, so I can setup everything easily in the future without just blindly following the instructions?
PATH is a special environment variable in UNIX (and UNIX-like, e.g. GNU/Linux) systems, which is frequently used and manipulated by the shell (though other things can use it, as well).
There's a somewhat terse explanation on wikipedia, but basically it's used to define where to search for executable files (whether binaries, shell scripts, whatever).
You can find out what your current PATH is set to with a simple shell command:
: $; echo $PATH
(Note: the : $; is meant to represent your shell prompt; it may be something very different for you; just know that whatever your prompt is, that's what I'm representing with that string.)
Depending on your system and prior configuration, the value will vary, but a very simple example of the output might be something like:
/usr/bin:/bin:/usr/local/bin
This is a colon(:)-separated list of directories in which to search for executable files (things like ls, et cetera.) In short, when you try to execute a command from your shell (or from within some other program in certain ways), it will search through each of the directories in this list, in order, looking for an executable file of the name you're provided, and run the first one it finds. So that's the concept, per your question.
From there, what this documentation is telling you to do is to add the directory where you've unpacked the software, and in particular its bin subdirectory, into your $PATH variable. How to do this depends a bit on which shell you're using, but for most (Bourne-compatible) shells, you should be able to do something like this, if you're in the directory where that bin directory is:
: $; PATH="$PATH:$PWD/bin"; export PATH
In just about all but an actual Bourne shell, this can be shortened to:
: $; export PATH="$PATH:$PWD/bin"
(I won't bother explaining for CSH-compatible shells (because: I agree with other advice that you don't use them), but something similar can be done in them, as well, if that happens to be your environment of choice for some reason.)
Presumably, though, you'll want to save this to a shell-specific configuration file (could be ~/.profile, ~/.bashrc, ~/.zshrc... depending on your shell), and without reference to $PWD, but rather to whatever it expanded to. One way you might accomplish this would be to do something like this:
: $; echo "export PATH=\"\$PATH:$PWD/bin\""
and then copy/paste the resulting line into the appropriate configuration file.
Of course you could also generate the appropriate command in other ways, especially if your $PWD isn't currently where that bin directory is.
See also:
An article about $PATH (and more)
a related question on superuser.com

Resources