Skip to content

Add Process.new with args instead of command, args#16681

Merged
straight-shoota merged 6 commits intocrystal-lang:masterfrom
straight-shoota:feat/process.new-args
Feb 28, 2026
Merged

Add Process.new with args instead of command, args#16681
straight-shoota merged 6 commits intocrystal-lang:masterfrom
straight-shoota:feat/process.new-args

Conversation

@straight-shoota
Copy link
Copy Markdown
Member

@straight-shoota straight-shoota commented Feb 25, 2026

Implements part of #14773
See crystal-lang/rfcs#21

# and wait for it to finish.
# * `Process.exec` replaces the current process.
def initialize(args : Enumerable(String), *, env : Env = nil, clear_env : Bool = false,
input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String? = nil)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice touch to not include the shell argument 👍

Now if we could reduce the duplication between both constructors... Ideally the old one should merely wrap the new one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot just make it a wrapper because the new one does not support shell feature.
Refactoring to remove duplication is also not easy because it's an initializer and involves instance variable setup. So I opted to leave it at that for now. It's acceptable to have a bit duplication.

@straight-shoota straight-shoota added this to the 1.20.0 milestone Feb 26, 2026
@straight-shoota straight-shoota merged commit 5ce8048 into crystal-lang:master Feb 28, 2026
53 checks passed
@straight-shoota straight-shoota deleted the feat/process.new-args branch February 28, 2026 11:46
@zw963
Copy link
Copy Markdown
Contributor

zw963 commented Apr 3, 2026

Hi, why there is no a ::Process.exec overload which support new format?

            ::Process.exec(
              desired_command.split(" ", remove_empty: true),
              env: environment,
              chdir: @config.root
            )

Error: expected argument #1 to 'Process.exec' to be String, not Array(String)

Overloads are:

  • Process.exec(command : String, args : Enumerable(String) | ::Nil = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : ExecStdio = Redirect::Inherit, output : ExecStdio = Redirect::Inherit, error : ExecStdio = Redirect::Inherit, chdir : Path | String | ::Nil = nil)

For now, I use like this:

argv = ::Process.parse_arguments(desired_command)

           ::Process.exec(
             argv[0],
             argv[1..],
             env: environment,
             chdir: @config.root
           )
           ```

@zw963
Copy link
Copy Markdown
Contributor

zw963 commented Apr 3, 2026

One more question, if we are remove shell: true, how to split command like this?

$: cut -d ' ' -f1 1.txt

The expected(correct) result should be:

Process.run(["cut", "-d", " ", "-f1", "1.txt"], output: STDOUT, error: STDOUT)

But, there is no easy way to convert string into correct Array(String), there are so many quirk cases in the shell, finally, user still need use shell frequently like this:

Process.run("/bin/bash", "-c", "cut -d ' ' -f1 1.txt")

@ysbaddaden
Copy link
Copy Markdown
Collaborator

Maybe... do it in Crystal?

File.each_line("1.txt") do |line|
  fields = line.split(' ')
  print fields[1]?
end

Please, discuss on the forum or under issues. This is only indirectly related to this PR. Thanks.

@zw963
Copy link
Copy Markdown
Contributor

zw963 commented Apr 4, 2026

how to split command like this?

okay, never mind, I think the right answer is: ::Process.parse_arguments("cut -d ' ' -f1 1.txt")

This is only indirectly related to this PR

But, ::Process.exec(["ls", "-alh", "/home"]) not related to this PR, right?

Since we already support ::Process.new and ::Process.run, why isn't Process.exec supported?

Should I create a new issue for this?

@straight-shoota @ysbaddaden

@straight-shoota
Copy link
Copy Markdown
Member Author

straight-shoota commented Apr 7, 2026

Process.exec is not considered in the new API from crystal-lang/rfcs#25 because we're discussing to drop it (see #14422).
When we introduce a portable replacement, it should be expected to follow the new API design.

@zw963
Copy link
Copy Markdown
Contributor

zw963 commented Apr 7, 2026

Just a few of my humble thoughts.

Is anyone else thinking that we're sacrificing too much just for the sake of portability (specifically for Windows?)

In my opinion, if we're running Process.exec on an unsupported platform, it should just raise an error is enough.

@zw963
Copy link
Copy Markdown
Contributor

zw963 commented Apr 7, 2026

Process.exec is not considered in the new API from crystal-lang/rfcs#21 because we're discussing to drop it (see #14422). When we introduce a portable replacement, it should be expected to follow the new API design.

RFC 0021: Percent String Array Literal with Interpolation ?

@straight-shoota
Copy link
Copy Markdown
Member Author

Sry, it's crystal-lang/rfcs#25

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants