neko icon indicating copy to clipboard operation
neko copied to clipboard

sys.io.Process calling `bash -c ${cmd}` doesn't pass environment to bash in neko2.3.0 win64 from cygwin environment

Open nodiex-cloud opened this issue 5 years ago • 2 comments

Please consider the following code:

import sys.io.Process;
class Main {
	static function main():Void {
		trace(execb("env"));
	}
	public static function exec(cmd:String):String {
		var args:Array<String>=cmd.split(" ");
		cmd=args.shift();
		return exec_ar(cmd,args);
	}
	public static function execb(cmd:String):String {
		//return exec_ar("bash_runner",[cmd]);
		return exec_ar("bash",["-c",cmd],true);
	}
	public static function exec_ar(cmd:String,args:Array<String>,is_bash:Bool=false):String {
		var p:Process=new Process(cmd,args);
		var r:String=p.stdout.readAll().toString();
		p.exitCode();
		if(is_bash) {
			cmd=args[1];
		}
		return r;
	}
}

I rely on execb throughout my code to execute commands because executing commands with exec is tricky. Complex commands are impossible to pass directly to Process. In previous (2.0.0 and possibly higher than 2.3.0), the bash process recieved all of the environment variables that were present in the shell that tora was started in and were equivalent to exec("env"). Now calling execb("env") only gets some basic envs.

Please revert this behavior, it very important to be able to maintain environment variables throughout the entire execution scope. This fundamentally breaks executive control of the machine. It becomes unwieldy to implement any sort of machine or cloud management with Haxe.

nodiex-cloud avatar Sep 18 '20 03:09 nodiex-cloud

Apparently this only occurs on windows (running tora from cygwin):

I have been able to get around this with a bash_runner.bat:

@echo off
bash -c %1
import sys.io.Process;
class Main {
	static function main():Void {
		//trace(exec("env"));
		trace(env_var("LOGS_DIR"));
		trace(execb("env"));
	}	
	public static function env_var(name:String):String {
		//return execb("printf $"+name);
		return execb('echo -n $(echo "$'+name+'")');
	}
	public static function exec(cmd:String):String {
		var args:Array<String>=cmd.split(" ");
		cmd=args.shift();
		return exec_ar(cmd,args);
	}
	public static function execb(cmd:String):String {
		if(Sys.getEnv("OS_NAME")=="win") {
			trace("bash_runner.bat");
			return exec_ar("bash_runner.bat",[cmd]);
		} else {
			return exec_ar("bash",["-c",cmd],true);
		}
	}
	public static function exec_ar(cmd:String,args:Array<String>,is_bash:Bool=false):String {
		var p:Process=new Process(cmd,args);
		var r:String=p.stdout.readAll().toString();
		p.exitCode();
		if(is_bash) {
			cmd=args[1];
		}
		return r;
	}
}

nodiex-cloud avatar Sep 18 '20 04:09 nodiex-cloud

Transferred to the Neko repository.

RealyUniqueName avatar Sep 18 '20 16:09 RealyUniqueName

I did some investigating, and I was unable to reproduce this. The only odd thing I observed is that running sys.io.Process("bash", [...]) will run the WSL bash.exe (i.e. C:\Windows\System32\bash.exe) instead of cygwin bash. With WSL bash, it is indeed missing all the environment variables, but this is just how WSL bash works. This is the case on all platforms, and it isn't specific to Neko. Running from a .bat file is somehow avoids the WSL bash being prioritised.

To take WSL out of the picture, I renamed cygwin's bash.exe to bash-test.exe and the variables are consistent when running directly through bash-test -c "env" or in a .bat script. So this is not a problem with Neko.

tobil4sk avatar Mar 27 '23 22:03 tobil4sk