Process.run error when use :inherit for output:

Hi, today I was testing (again) my software ( a tool to build a full linux system from scratch).

When my tool start to build Rustc, I had this error. To be honest, I don’t understand the problem.

(ISM Chroot) root:~# ism software install xorg-server
ChCChhCheCcCkCiDone !

    Rustc /1.52.0/  { }
    Xorg-Libraries /1.20.13/  { }
    Js /78.13.0/  { }
    Polkit /0.119.0/  { Linux-Pam Elogind }
    Elogind /246.10.0/  { Openrc Linux-Pam Polkit }
    Xorg-Server /1.20.13/  { Elogind Libepoxy Wayland-Protocols Acpid }

6 new softwares will be install

Would you like to install these softwares ?[y/n]y

<< [1 / 6] Installing Rustc /1.52.0/

Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'macro_140340635089920'

Code in .ISM.task.cr:25:1

 25 | {{ read_file("/usr/share/ism//ISM/Software.cr"
      ^
Called macro defined in .ISM.task.cr:25:1

 25 | {{ read_file("/usr/share/ism//ISM/Software.cr"

Which expanded to:

 > 547 | process = Process.run(  arguments[0],
 > 548 |                         args: arguments[1..arguments.size-1],
 > 549 |                         output: :inherit,
                                 ^
Error: expected argument 'output' to 'Process.run' to be (IO | Process::Redirect), not Symbol

Overloads are:
 - Process.run(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | ::Nil = nil)
 - Process.run(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Pipe, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | ::Nil = nil, &)

The calling program is this one:

 runPythonCommand(   ["./x.py","build","--exclude","src/tools/miri"],
                            buildDirectoryPath,
                            {"RUSTFLAGS" => "-C link-args=-lffi"})

And this is the function where come from the error:

def runChrootTasks(chrootTasks) : Process::Status
            File.write(Ism.settings.rootPath+ISM::Default::Filename::Task, chrootTasks)

            process = Process.run("chmod",  args: [ "+x",
                                                    "#{Ism.settings.rootPath}#{ISM::Default::Filename::Task}"],
                                            output: :inherit,
                                            error: :inherit,
                                            shell: true)

            process = Process.run("chroot",   args: [ Ism.settings.rootPath,
                                                    "./#{ISM::Default::Filename::Task}"],
                                            output: :inherit,
                                            error: :inherit,
                                            shell: true)

            File.delete(Ism.settings.rootPath+ISM::Default::Filename::Task)

            return process
        end

        def runSystemCommand(arguments = Array(String).new, path = String.new, environment = Hash(String, String).new) : Process::Status
            environmentCommand = (environment.map { |key| key.join("=") }).join(" ")

            if Ism.settings.installByChroot
                chrootCommand = <<-CODE
                #!/bin/bash
                cd #{path} && #{environmentCommand} #{arguments.join(" ")}
                CODE

                process = runChrootTasks(chrootCommand)
            else
                process = Process.run(  arguments[0],
                                        args: arguments[1..arguments.size-1],
                                        output: :inherit,
                                        error: :inherit,
                                        shell: true,
                                        chdir: path,
                                        env: environment)
            end

            return process
        end

        def runPythonCommand(arguments = Array(String).new, path = String.new, environment = Hash(String, String).new)
            process = runSystemCommand(["python"]+arguments, path, environment)

            if !process.success?
                Ism.notifyOfRunSystemCommandError(arguments, path, environment)
                Ism.exitProgram
            end
        end

I would start by changing these two lines to this and see if it fixes anything:

output: Process::Redirect::Inherit,
error: Process::Redirect::Inherit,
2 Likes

So it look like it fixed the problem, but now an another one occurred:



(ISM Chroot) root:/var/ism/softwares/ProgrammingLanguages-Main# ism software install xorg-server
ChCChhCheCcCkCiDone !

    Rustc /1.52.0/  { }
    Xorg-Libraries /1.20.13/  { }
    Js /78.13.0/  { }
    Polkit /0.119.0/  { Linux-Pam Elogind }
    Elogind /246.10.0/  { Openrc Linux-Pam Polkit }
    Xorg-Server /1.20.13/  { Elogind Libepoxy Wayland-Protocols Acpid }

6 new softwares will be install

Would you like to install these softwares ?[y/n]y

<< [1 / 6] Installing Rustc /1.52.0/

Showing last frame. Use --error-trace for full trace.

There was a problem expanding macro 'macro_140373396646912'

Code in .ISM.task.cr:25:1

 25 | {{ read_file("/usr/share/ism//ISM/Software.cr"
      ^
Called macro defined in .ISM.task.cr:25:1

 25 | {{ read_file("/usr/share/ism//ISM/Software.cr"

Which expanded to:

 > 551 | shell: true,
 > 552 | chdir: path,
 > 553 | env: environment)
         ^
Error: expected argument 'env' to 'Process.run' to be (Hash(String, Nil) | Hash(String, String | Nil) | Hash(String, String) | Nil), not Hash(String, Int32 | String)

Overloads are:
 - Process.run(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | ::Nil = nil)
 - Process.run(command : String, args = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Pipe, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | ::Nil = nil, &)

It’s strange, I never had this problem before with this call with Process.run

I found where the last problem was coming from, just put the number between quotes.

Thanks a lot !

2 Likes

Sorry but I come back again, because now when I use this way to inherit, a new problem occur,it’s when under the process arguments, I try to access to an external value (with dollar).

Look:

* Checking Glibc
* Extracting Glibc
* Patching Glibc
* Preparing Glibc
* Configuring Glibc
checking build system type... Invalid configuration `$(../scripts/config.guess)': machine `$(../scripts/config.guess)-unknown' not recognized
configure: error: /bin/sh ../scripts/config.sub $(../scripts/config.guess) failed
[!] Failed to run --prefix=/usr --host=x86_64-unknow-linux-gnu --build=$(../scripts/config.guess) --enable-kernel=3.2 --with-headers=/mnt/ism//usr/include libc_cv_slibdir=/usr/lib in /mnt/ism/sources/ProgrammingTools-Main/Glibc/2.34.0/glibc-2.34//build with given environment

Problem occur from this call:

configureSource([   "--prefix=/usr",
                                "--host=#{Ism.settings.chrootTarget}",
                                "--build=$(../scripts/config.guess)",
                                "--enable-kernel=3.2",
                                "--with-headers=#{Ism.settings.rootPath}/usr/include",
                                "libc_cv_slibdir=/usr/lib"],
                                buildDirectoryPath)

This is the function implementation:

def configureSource(arguments = Array(String).new, path = String.new, configureDirectory = String.new, environment = Hash(String, String).new)
            if @buildDirectory
                configureCommand = "../#{configureDirectory}/configure"
            else
                configureCommand = "./#{configureDirectory}/configure"
            end

            process = runSystemCommand([configureCommand]+arguments, path, environment)

            if !process.success?
                Ism.notifyOfRunSystemCommandError(arguments, path, environment)
                Ism.exitProgram
            end
        end

I never had this error before I change :inherit to Process::Redirect::Inherit.

But I am not sure it’s the problem as well, I changed recently my implementation, I think I made bad something, I am lost a bit

This was the previous implementation:

def configureSource(arguments : Array(String), path = String.new, configureDirectory = String.new, environment = Hash(String, String).new)
            if @buildDirectory
                configureCommand = "../#{configureDirectory}/configure "
            else
                configureCommand = "./#{configureDirectory}/configure "
            end

            configureCommand += arguments.join(" ")
            environmentCommand = (environment.map { |key| key.join("=") }).join(" ")

            if Ism.settings.installByChroot
                chrootConfigureCommand = <<-CODE
                #!/bin/bash
                cd #{path} && #{environmentCommand} #{configureCommand}
                CODE

                process = runChrootTasks(chrootConfigureCommand)
            else
                process = Process.run(  configureCommand,
                                        output: :inherit,
                                        error: :inherit,
                                        shell: true,
                                        chdir: path,
                                        env: environment)
            end

            if !process.success?
                Ism.notifyOfConfigureError(path)
                Ism.exitProgram
            end
        end

Nobody have an idea ? I revert the implementation of my configure function in my code, but I am annoyed to don’t understand why it doesn’t work

What is wrong ?

What’s your current implementation of runSystemCommand? Same as above?

This one:

def runSystemCommand(arguments = Array(String).new, path = Ism.settings.installByChroot ? "/" : Ism.settings.rootPath, environment = Hash(String, String).new) : Process::Status
            environmentCommand = (environment.map { |key| key.join("=") }).join(" ")

            if Ism.settings.installByChroot
                chrootCommand = <<-CODE
                #!/bin/bash
                cd #{path} && #{environmentCommand} #{arguments.join(" ")}
                CODE

                process = runChrootTasks(chrootCommand)
            else
                process = Process.run(  arguments[0],
                                        args: arguments[1..arguments.size-1],
                                        output: Process::Redirect::Inherit,
                                        error: Process::Redirect::Inherit,
                                        shell: true,
                                        chdir: path,
                                        env: environment)
            end

            return process
        end

I reduced this a bit to:

module Playground
  def self.runCommand(arguments = [] of String, path = ".", env = {} of String => String)
    Process.run(arguments[0],
                args: arguments[1..],
                output: Process::Redirect::Inherit,
                error: Process::Redirect::Inherit,
                shell: false,
                chdir: path,
                env: env) # Remove env: env and it works
  end

  def self.main
    cmd = "./run-me"
    args = ["--foo", "42"]
    runCommand([cmd] + args)
  end
end

puts Playground.main.success?

I think your environment may not be correct. If I remove that and just use my inherited environment, it works fine. I also had to change shell to false.

run-me is just this:

puts ARGV

I tried all you recommend me, but nothing change, the same bug persist. I think the bug come from somewhere else.

Very strange this bug