Accessing environment variables using $ in Scala process - scala

I'm trying to use a command that uses environment variables, and following is working fine( this is not the actual command I'm going to use).
Seq("echo "+System.getenv("JAVA_HOME"))!
but is there way to use the following kind of syntax ? In the case if we load the command from .sh file ?
Seq("echo ${JAVA_HOME}")!

You can use scala process with bash -c to get environment variables:
import scala.sys.process._
val value = Seq("bash", "-c", "echo $JAVA_HOME").lines.head

Related

How to get & set environment variables in Scala?

I want to set Scala variable to environmental variables and get the variable in shell scripting.
Setting environment variables
The companion object of scala.sys.process.Process has several apply factory methods that allow you to specify various parameters, such as
the arguments passed to the executable
current working directory of the started process
extra environment variables
For example:
import scala.sys.process.Process
import java.io.File
Process(
List("bash", "-c", """echo "pwd=$(pwd) FOOBAR=${FOOBAR}";"""),
Some(new java.io.File("..")),
"FOOBAR" -> "42"
).!!
will start bash in the parent directory of your current working directory, with an additional environment variable FOOBAR set to "42".
Getting environment variables
Works in exactly the same way as for Java, with System.getenv.
For example, if you start scala/scala3 from your terminal with
BARFOO="someValue" scala3
and then in the Scala-REPL run
System.getenv("BARFOO")
then it will return
"someValue"

How to switch NVM environments within perl

I am writing a perl script, and I want to run a simple shell command to use a certain version of NVM:
Here is my code snippet:
print "\n*** Switching to correct nvm environment for dashboard builds\n";
system("nvm use 8.12.0") == 0 or die $?;
But I am getting the following error:
Can't exec "nvm": No such file or directory
Can someone help?
Update (June 30, 2021):
I also tried adding the command:
my $nvm_version = "8.12.0";
system ("bash", "-lic", "nvm use $nvm_version");
But nothing happens:
I'm not familiar with nwm, but I think I get the gist of what it does. And if so, the attempt is fundamentally flawed. Even if you fixed this to run the proper shell so that nvm could run, I believe all the tool does is change the shell's environment variables, a shell you immediately exit. This means it would have no effect even if if it ran successfully.
Again, it this tool does what I think it does, such tool are meant to be used in interactive shells. In other instances, you simply use the path the to correct executable instead of relying on the PATH.
With that in mind, you can use the following to run the command in bash:
# Non-interactive shell.
system("bash", "-c", "nvm use 8.12.0")
or
# Interactive shell.
# This is improper and fragile as interactive shells
# often create aliases that override basic commands.
system("bash", "-ic", "nvm use 8.12.0")
Just to reiterate, at least one of these will allow the command to run (if it normally works from bash), but I believe it's unlikely this will produce the results you expect.
The nvm command is shell function which is different from a shell command. Also the nvm command is not an exported function so it will not be seen by sub shells. For example, in Bash shell:
$ nvm ls
-> v15.0.1
$ my-test-script.sh
./my-test-script.sh: line 3: nvm: command not found
where my-test-script.sh is:
#! /bin/bash
nvm use 16.4
The error nvm: command not found is because nvm is not exported. I can source the script in the current shell context to make it work:
$ source my-test-script.sh
Now using node v16.4.0 (npm v7.18.1)
$ node --version
v16.4.0
So a Perl script cannot change the node version of the current shell, but it can calculate the version and pass it back to shell, which can set the version. For example:
$ nvm use $(perl -E'$v=15.0; print $v')
Now using node v15.0.1 (npm v7.0.3)

How to get .bashrc / .profile variables in Scala

I am unable to get access to the environmental variables in either ~/.bashrc or ~/.profile from Scala. How do I access the environmental variables from a Scala Process? Also I am unable to update the paths like this:
Process("myProgram", None, "PATH"-> ".:/path/to/myProgram").!!
However this works:
Process("/path/to/myProgram",None).!!
Works fine. However, when myProgram depends on some environmental variables being set this doesnt work anymore.
How do I change the PATH variable from a Scala program?
And even better, how can I get Scala to access the environmental variables from .bashrc or .profile. Currently none of those are available.
Thanks for your time and help
How do I access the environmental variables from a Scala Process?
The util.Properties object offers 3 different methods for inspecting the environmental variables that the Scala process/program has inherited. Here's an example:
util.Properties.envOrNone("LC_COLLATE")
//res0: Option[String] = Some(POSIX)
How do I change the PATH variable from a Scala program?
A running process is not allowed to alter its own environment, but it can launch a new process with a modified environment. There are a couple different ways to go about this.
One is to launch the shell of your choice and use shell syntax to make the modifications before invoking the target command.
import sys.process._
Seq("sh", "-c", "PATH=$PATH:$HOME/Progs myProg").!!
// a single arg:^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Or you can supply the environment mods as an argument to one of the many overloaded Process.apply() methods.
import scala.sys.process._
Process("./myProg"
,new java.io.File("/full/path/to")
,"PATH"->s"${Properties.envOrElse("PATH",".")}:/full/path/to"
).!!
...can I get Scala to access the environmental variables from .bashrc or .profile?
If your Scala program is launched from a shell with the proper environment then every process launched from your program should inherit the same. If, for whatever reason, your program has not inherited a fully equipped environment then the easiest thing to do is to launch a fully equipped shell to launch the target command.
import scala.sys.process._
Seq("sh", "-c" , ". $HOME/.bashrc && myProg").!!

run Scala in TextMate

I am trying to run Scala in TextMate. I have created a new variable TM_SCALA and set it to the path which I obtained on executing the following command on the terminal
which scala
But when I try to run a Scala program, I get the error
Run Script: line 4: scala: command not found
This is the run script
#!/usr/bin/env bash
[[ -f "${TM_SUPPORT_PATH}/lib/bash_init.sh" ]] && . "${TM_SUPPORT_PATH}/lib/bash_init.sh"
scala -classpath . -savecompiled "$TM_FILEPATH"
I am unable to understand the problem. Thanks in advance.
Make sure you have scala downloaded.
update PATH variable in TextMate preferences. Append scalac path there.
Add a new command (or replace the 'run script' one) with this:
#!/usr/bin/env ruby -w
cmd = ENV['SCALA_HOME'] + "/scala -nocompdaemon -howtorun:script '" + ENV['TM_FILEPATH'] + "'"
result = "" + `#{cmd}`
puts "#{result}"
That assumes that you have a SCALA_HOME environment variable set to something like this:
export SCALA_HOME="/path/to/my/scala/scala-2.11.4/"

running ipython in non-interactive mode

I was hoping it would be easy to rewrite a few bash scripts using ipython by using the "!" command. Unfortunately if I try to run ipython in non-interactive mode like so:
ipython -p sh myipythonscript.py
where myipythonscript.py contains commands like:
env=%env
d=!ls
This doesn't work. I get SyntaxError.
Is there an option which allows ipython to be run in non-interactive mode?
Python also has modules which makes it easy to completely replace bash calls. these are easier to debug and give better error handling.
for example instead of ls you can use glob, it supports the same syntax:
files=glob.glob('myfiles*.txt')
for environment variables:
env = os.environ
for path related functions:
os.path
for common operations, os.mkdir, os.chmod, os.getcwd [same as pwd]