Running Ruby Script via shell() function - ruby

I'm trying to (eventually) execute a ruby script via R by calling the shell() function. As a first step though, I am simply trying to verify that I can call the ruby compiler via this function, and I am getting an error. Here is my code:
dir <- shell("ruby -v", intern=TRUE)
This throws a warning: Warning message: running command
'C:\WINDOWS\system32\cmd.exe /c ruby -v' had status 1
And the 'dir' variable is blank. I have verified that the command "ruby -v" works when run in a command prompt, and that Ruby is included in my system path variables.

You need to confirm that the ruby path is within PATH environmental variable using Sys.getenv("PATH"). If it isn't, you can always add it as you stated above with Sys.setenv.
Here is a way to simply append the PATH variable with a new directory.
Sys.setenv(PATH = paste(Sys.getenv("PATH"), "/my/ruby/dir/bin", sep=":"))
I'm not aware of a more concise way to append a path to an existing environmental variable from within R.

Related

Setting environment variable to shell executed from perl script

I am running a perl file a.pm which invokes b.sh via system command.
Here, b.sh is using find utility whose path is /usr/local/bin.
If I run env on shell directly on machine, I get output as below for PATH variable.
PATH=/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/home/bin:/home/bin/samba::/home/venv/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin`
Thats why if I run the b.sh directly from shell, it is able to execute find utility.
Now, If I run b.sh via a.pm as mentioned earlier using system(), and when I print PATH env variable in b.sh, its coming as
/bin:/usr/bin:/usr/X11R6/bin:/home/bin:/home/perl5/bin
which does not have /usr/local/bin, and thats why find command is failing.
If I tried to print all ENV variables in perl before invoking system(b.sh), PATH variable is not printed.
Now, I tried adding path variable in a.pm file as follows just before invoking system(b.sh).
$ENV{'PATH'} = '/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin:/home/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/';
Now, if I try to print all ENV variables in perl before invoking system(b.sh), PATH variable is printed with above value.
Still executing the a.pm file, the PATH variable printed in b.sh is same:
/bin:/usr/bin:/usr/X11R6/bin:/home/bin:/home/perl5/bin
How can I add corresponding path /usr/local/bin to shell of b.sh invoked using a.pm?
I suspect that the Perl program is either modifying the path it gets from the shell that invokes it, or that you have left out a step somewhere. For example, if you invoke the Perl program from a different environment, it will likely have a different PATH.
You seemed to have found your answer though. Add the necessary directory to the PATH in the Perl program. But, you say this doesn't work. Again, I think there's some step that you haven't included. I suspect that the way in which you run system overwrites the PATH inherited from the parent.
For example, here's a small Perl program the merely runs a shell script:
#!perl
use v5.10;
$ENV{PATH} = '/bin:/usr/bin';
say "PATH in Perl is $ENV{PATH}";
system( "sh ./pather.sh" );
The shell script echos the PATH:
#!/bin/sh
echo "PATH in shell:" $PATH
When I run this, both PATHs match:
PATH in Perl is /bin:/usr/bin
PATH in shell: /bin:/usr/bin
But, maybe the command in system is something else. The -l switch treats the shell as a login shell, so it will load the various profiles and whatnot:
system( "sh -l ./pather.sh" );
Now the PATH is different in the shell script because my particular profiles overwrote PATH:
PATH in Perl is /bin:/usr/bin
Path in shell: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/usr/local/go/bin:...
Our answers can be more targeted you can produce a minimal working example where we see actual code that demonstrates the problem. Since we don't see what you actually run in system, we can only guess.

Accessing a ruby property in bash shell

I am trying to install and execute a ruby gem in my bash shell and I want to look at certain properties of the result in my shell script. How do I do this?
#!/bin/bash -l
source "/usr/local/rvm/scripts/rvm"
rvm use 2.4.0
gem install graphql-schema_comparator
result="$(schema_comparator compare "$NEW_SCHEMA" "$CURRENT_LIVE_SCHEMA")"
Here is the ruby gem: https://github.com/xuorig/graphql-schema_comparator
I want to be able now access the result of the comparison and perform some actions based on it?
a="$(result?.foo)"
b="$(result.bar)"
Both these are failing with the error
result?.foo: command not found
result.bar: command not found
This won't work because
result="$(schema_comparator compare "$NEW_SCHEMA" "$CURRENT_LIVE_SCHEMA")"
If you are running this as a shell script result will only be a string in your shell with whatever your method call outputs to STDOUT. It is not a ruby object and so no ruby commands can be called on it. All you can do with the shell variable is whatever shell will support if you access it in shell with $result.
Why do you even want to do this? Why not just use ruby directly?

How to set environment variables in tcl?

When I source my .cshrc file and run the Tcl script it is working fine:
$ source .cshrc-sample
$ tclsh invoke.tcl
Following is the .cshrc file:
setenv AUTOTEST "/auto/isbutest/frt"
setenv ATS_EASY "$AUTOTEST"
setenv ATS_USER_PATH "$AUTOTEST"
setenv PATH "${AUTOTEST}/bin:${PATH}"
But when I tried setting the environment variable in Tcl itself and run the script,
I get the following error:
$ tclsh invoke.tcl
can't find package ha
while executing
"package require ha"
(file "invoke.tcl" line 8)
My Tcl script - invoke.tcl:
global env
set env(AUTOTEST) "/auto/isbutest/frt"
set env(ATS_EASY) "/auto/isbutest/frt"
set env(ATS_USER_PATH) "/auto/isbutest/frt"
set env(PATH) "$env(PATH):/auto/isbutest/frt/bin:";
package require ha
How can I run the script without sourcing the .cshrc?
The thing is setting environment variable is not possible using scripts, the lifetime of the variable is within the runtime of the script. When I tried printing the PATH variable it shows what is needed, but I don't know why it is not working. Is there any other workaround for this?
There's a few possibilities. The key things to look at are whether there are any other environment variables that you've missed out, whether the Tcl auto_path global variable is correct immediately before the package require, and whether there is anything else going on.
The easiest way from the Tcl side is to add:
puts "auto_path=$auto_path"
parray env
immediately before the package require that has the error. That should print out plenty of information. (Pay particular attention to if you are setting the TCL_LIBRARY or TCLLIBPATH environment variables differently.)
Aside from that, it's possible that there is something set in the ~/.tclshrc file, which is only sourced in interactive mode (it happens before you get your prompt). That could cause observable changes. Another option is if the ha package's pkgIndex.tcl script is written to use abbreviated commands, which only work when Tcl is in interactive mode. Errors in the package index definition script will make the code that describes how to actually load/source the package's implementation not register, and could give you the error state you see. If the script is assuming it can use abbreviations, fix it as that's always a bug. Abbreviations are a convenience when using Tcl interactively, and should never be put in proper saved code.
You might want to check whether the list of packages is complete. Use this code for that:
catch {package require NoSuchPackage}; # Force immediate population of the list of packages
puts Packages:\n\t[join [lsort -dictionary [package names]] \n\t]
Again, put this in after any setting of global variables and before the problem package require.
In side tcl script, you can simply do setenv as, setenv AUTOTEST="/auto/isbutest/frt".
if you want to set a variable, use set VARNAME "/auto/isbutest/frt".
if you want to get any environment variable, use $::env(AUTOTEST).
and any variable declared using set command can be accessed using $VARNAME.

Adding to an environment variable still doesn't work

I'm trying to get emacs to become a global name so I can reference it anywhere on my filesystem. This is what I did on the command line:
$PATH = C:/emacs/bin:$PATH
But when I do that I get the following error:
sh.exe": /c/home/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program: No such file or directory
I even went directly to Start Menu->System [Properties]->Environment Variables and I tried to add C:\emacs\bin to the list of the paths but the name still came up as emacs: command not found. I don't know what I'm doing wrong.
Note that this is only a problem within C:\cygwin. Outside of that directory I can type emacs without a problem.
Your command
$PATH = C:/emacs/bin:$PATH
has several problems:
$ evaluates the variable, you need to set it
spaces are significant, you do not need them
you cannot use : inside a Cygwin path
Use this instead:
PATH=/c/emacs/bin:$PATH

environment variable expansion in first line of shell script

My ruby shell scripts specify the ruby interpreter in the first line of the script as:
#!/Users/me/.rvm/rubies/ruby-1.9.3-p194/bin/ruby
The problem is that when I upgrade to a new ruby version, I have to edit all the script files to update the interpreter. There is an environment variable available, $MY_RUBY_HOME, that expands to the current path (minus the /bin/ruby part). However, all my attempts to use:
#!{$MY_RUBY_HOME}/bin/ruby
#!${MY_RUBY_HOME}/bin/ruby
etc
fail ("bad interpreter: No such file or directory"). I suspect environment expansion isn't done on the first line, so I may just be out of luck. I would be interested if anybody has been able to use environment variable expansion on the program definition line in a shell script.
Put ${MY_RUBY_HOME}/bin in your $PATH and use #!/usr/bin/env ruby. See here.

Resources