this is something about how run can only accept arrays, and not strings (I'm curious why)

If I copy and paste the command that was given to Perl6's run, it works when given from the shell. It doesn't work when given through perl6. This isn't good, because I have to execute this command hundreds of times.

Perhaps Perl6's shell https://docs.perl6.org/routine/shell would be better? I didn't use that, because the manual suggests that run is safer. I want to capture both stdout and stderr inside a Proc class

EDIT: I've gotten this running with shell but have encountered other problems not related to what I originally posted. I'm not sure if this qualifies as being answered then. I just decided to use backticks with perl5. Yes, backticks are deprecated, but they get the job done.

Why do you split on /\s+/ ? The --notebook-params expects to be followed by one string, which is ''{"directory": "s3://bucket", "output": "s3://bucket/ext...' - but that contains spaces. So your splitting on spaces is a bad/weird idea. Most likely you will want to involve a shell by using shell $cmd instead.
– CorionJan 24 at 16:02

I don't understand the logic about why an array should be submitted to run and not a string. This makes 0 sense to me. I've tried what you said, and that doesn't work either.
– conJan 24 at 16:14

2

Your simplistic split destroys the quoted parameter '{"directory": ... .csv"}'. That needs to appear as one parameter on the command line, not as multiple.
– Stefan BeckerJan 24 at 16:21

@StefanBecker I've tried that too, and that fails
– conJan 24 at 16:22

2 Answers
2

To run shell commands, call the shell routine. It passes the positional argument you provide it, coerced to a single string, to the shell of the system you're running the P6 program on.

For running commands without involving a shell, call the run routine. The first positional argument is coerced to a string and passed to the operating system as the filename of the program you want run. The remaining arguments are concatenated together with a space in between each argument to form a single string that is passed as a command line to the program being run.

my $cmd0 = 'databricks jobs run-now --job-id 35 --notebook-params ';

That's wrong for both shell and run:

shell only accepts one argument and $cmd0 is incomplete.

The first argument for run is a string interpreted by the OS as the filename of a program to be run and $cmd0 isn't a filename.

So in both cases you'll get either no result or nonsense results.

Your other two experiments are also invalid in their own ways as you discovered.

this is something about how run can only accept arrays, and not strings (I'm curious why)

run can accept a single argument. It would be passed to the OS as the name of the program to be run.

It can accept two arguments. The first would be the program name, the second the command line passed to the program.

It can accept three or more arguments. The first would be the program name, the rest would be concatenated to form the command line passed to the program. (There are cases where this is more convenient coding wise than the two argument form.)

run can also accept a single array. The first element would the program name and the rest the command line passed to it. (There are cases where this is more convenient.)

I just decided to use backticks with perl5. Yes, backticks are deprecated, but they get the job done.

Backticks are subject to code injection and shell interpolation attacks and errors. But yes, if they work, they work.

P6 has direct equivalents of most P5 features. This includes backticks. P6 has two variants:

The safer P6 alternative to backticks is qx. The qx quoting construct calls the shell but does not interpolate P6 variables so it has the same sort of level of danger as using shell with a single quoted string.

The qqx variant is the direct equivalent of P5 backticks or using shell with a double quoted string so it suffers from the same security dangers.

"The first argument for run is a string interpreted by the OS as the filename of a program to be run and $cmd0 isn't a filename." I didn't know this, this was the key missing information
– conJan 24 at 20:28

2

OSes all have a function call where the calling code gives a name, and the OS goes off and finds and runs a program of that name. You can also pass a string that's passed on to the program so it has input arguments. The P6 run function corresponds to this raw OS level function so has the program name, plus zero or more concatenated arguments.
– raiphJan 24 at 20:38

2

Shells sit on top of OSes. Using a shell involves writing a line of text and hitting the Enter key. It's just one string. It might start with a program name or it might just be some shell code. So the P6 shell routine just takes a single string and passes that to the OS's default shell. (I believe this is configurable.)
– raiphJan 24 at 20:39