Setting environment variable around subprocess

I’m using something like

Seq("a","b","c").!

to execute a subprocess. I think the ! probably does a lot of work to build a process-builder, also so that it works independent of OS.

Is there a concept of environment variables for these OS independent processes? I only know UNIX, I know very little about executing subprocess on non-unix architectures.

I’d like to call the sub-process in an environment where a particular environmental variable is set to a particular value, without effecting the env var for the current process.

How can I do this? Is it even possible, or is this really only possible in UNIX?

You really should have a look at the API, sometimes soon…

Process(cmd, cwd, env*)

3 Likes

Is the idea that a Process must then be executed, or is a Process something that executes on construction?

Great! after a bit of trial and error. I discovered that a Process (despite its name) is really a description for starting a process. It still needs to be launched.
The following incantation seems to do what I need.

        val process = Process(Seq(gnuPlotPath, "-e", s"set terminal $terminal", gnuName),
                              None,
                              "LC_CTYPE" -> "en_US.UTF-8")
        val exitCode = (process #>> new File(outputFileName)).!

If you look at the scaladoc, you see that Process(...) does not give you a Process, but returns a ProcessBuilder.

And, Seq(...).! is just the same as Process(Seq(...)).! by an implicit conversion (see here)

I really appreciate the help. But it seems to me just reading the docs doesn’t convey the intent and the philosophy of these classes and the APIs thereof. This probably comes with experience using the particular library.

To me the docs for Process (trait/companion object) and ProcessBuilder look decent. In particular, the trait points to the factory methods on the companion, and both point to the builder, which is quite extensively documented at the top level. What is lacking or inaccessible in your opinion?

2 Likes

You pose a really great question. Bravo.
It is difficult to read documentation from the point of view of someone who doesn’t understand. I know that as a professor myself. Putting yourself in the place of someone seeing it for the first time is challenging. Documentation is necessarily writing by experts.

I began looking at the documentation for Process, which isn’t really helpful. However, when I now look at the documentation for ProcessBuilder, not the methods themselves, but the explanation at the top, I do see a pretty decent description of the concept.

Someone who already knows might think, “well why were you looking at Process? You should have been looking at ProcessBuilder!”

One thing that I don’t see an explanation of is the process abstraction at all. I know about UNIX processes, but I don’t know how these are similar and different from the generalisation which Scala (and probably many languages) use in order to work, on multiple operating systems. For example, are environmental variables UNIX specific, or are they supported by this OS-independent concept.

Is Scala Process an implementation of POSIX or rather something java specific? I didn’t see a claim or disclaimer in the documentation regarding that?

Not really. :slight_smile: But if you happen to start with the Process companion object (which admittedly is sparsely documented at the overview level), ProcessBuilder shows up (and is linked, of course) basically all over the place.

Documentation for abstract concepts spanning across multiple types should generally be found in the package doc (linked from the lower level docs, as well).

An actual attempt at POSIX as a JVM library would make any Java/Scala programmer run away screaming with terror - and justifiably so. :wink:

It’s a Scala layer on top of the corresponding Java API (as mentioned in the package doc). This implies that for rare fringe cases, one may actually have to dive down to the Java API (and in the worst case even further to the specific implementation for a given OS) to achieve the desired behavior (or just understand why it can’t be achieved). But for the average use case, the Scala API (and its documentation) should be fully sufficient.

1 Like