Closed SpacewaIker closed 1 year ago
Works for me. That is, I have no difficulty running external commands (programs) from an Elvish shell on Windows 11; even using a relative path:
elvish> cd c:\msys64\opt\bin
elvish> ./authtest
2023/02/20 14:47:11 authtest.go:39: usage: [GOAUTH=CMD...] authtest.exe URL
Exception: ./authtest exited with 1
[tty 195]:1:1: ./authtest
What version of Elvish are you running (put $buildinfo
or elvish --version
)? You say "executing scripts like this used to work". What does the first line of that script look like? Does the interpreter it presumably references exist? Also, the error message is weird since it should say './gradlew' is not recognized
. Are you really at an Elvish prompt when you type that command?
@SpacewaIker, ping? Is this still an issue for you? If it is can you answer my questions from my previous comment? If this is no longer an issue for you it would be appreciated if you explained what the problem was and close this issue.
I have elvish version 0.19.0-dev.0.20230119103625-1a5873eea523+official
. The first line of the script is a sha-bang:
#!/bin/sh
Which I now realize probably doesn't work on Windows. After further testing, here's what I found:
With Powershell, running the ./gradlew
script works, as does the ./gradlew.bat
. I'm not sure if the sha-bang actually works or if it works only because Powershell has some aliases that makes it somewhat compatible with shell scripts.
With cmd, running ./gradlew
or ./gradlew.bat
does not work. And more interestingly, gives the error '.' is not recognized as an internal or external command, operable program or batch file.
, which is exactly the error given by elvish when I try to run the script. However, with cmd, I can run both scripts by removing the ./ (i.e., running gradlew
or gradlew.bat
works). I don't understand why running gradlew
works though, because cmd is definitely not compatible with shell scripts, and I don't think the sha-bang should work.
With elvish, running either ./gradlew
or ./gradlew.bat
also does not work. And it gives the same error as cmd did, with the added Exception: ./gradlew exited with 1 \ [tty xx]:1:1: ./gradlew --version
. But running the scripts without the ./ does not work either, as elvish is trying to run an executable with this name, and gives the error Exception: exec: "gradlew": cannot run executable found relative to current directory \ [tty xx]:1:1: gradlew --version
.
I also tried writing a simple shell script for testing:
#!/bin/sh
echo "hello world"
But this one gives weird results: Powershell and cmd want to open the file in a new program (with a windows dialog) when executing the script, while elvish gives the error Exception fork/exec .test/sh: %1 is not a valid Win32 application. \ [tty xx]:1:1: ./test.sh
.
So honestly, I'm not sure what's going on. It seems like elvish is trying to run scripts through windows cmd, which is failing because of the leading ./, which is required to elvish to execute the file as a script. But as I said, I didn't have this problem before, and scripts were executing as expected. Not sure what changed on my computer since then...
With Powershell, running the ./gradlew script works, as does the ./gradlew.bat
I'm pretty sure that when you type ./gradlew
Powershell is actually running your "bat" file, not the UNIX script. Did you actually modify the UNIX script to do something distinct from the bat file that would enable you to verify it was actually executed?
And more interestingly, gives the error '.' is not recognized as an internal or external command, operable program or batch file., which is exactly the error given by elvish when I try to run the script.
No, it is not. This is what I see when I attempt to run a shell script with a shebang line on Windows 11:
elvish> cat x
#!/bin/bash
echo done
elvish> ./x
Exception: exec: "./x": file does not exist
So honestly, I'm not sure what's going on.
I understand what is happening on my system but do not understand what is happening on your system. Scripts with shebang lines do not work on Windows 11. At least not with Elvish. That's because on UNIX systems the shebang line is interpreted by the OS kernel. Elvish simply tells the OS kernel to execute the script and the kernel reads the first line, recognizes the shebang, and turns the execution request into /bin/sh ./gradlew
. The Windows kernel does not recognize shebang lines. Shells like Bash provided by the MSYS2 project have special support for shebang lines (not to mention mapping paths like /bin/sh to c:\msys64\usr\bin\sh.exe).
I have a framework that I use for automating the building and unit testing of projects like Elvish on various virtual machines I run locally. Including a Windows 11 VM. For the Windows 11 system I explicitly execute statements like bash sync-home
rather than just sync-home
precisely because scripts with shebang lines do not work on Windows 11 when run from Elvish.
Also, Google for "windows script shebang" and you will find a lot of discussion about this topic. If your script has an explicit extension (e.g., .py
or .sh
) then you can configure Windows to recognize a "file association" between the extension and the interpreter to run when the file is executed. But that, obviously, doesn't work for a script without an explicit type extension.
Yes, it does seem like running ./gradlew
actually runs the batch file. I tried deleting the content of the UNIX script, and the command still worked. However, deleting the contents of the batch file makes the ./gradlew
command not do anything.
As for the rest, firstly I appreciate the explanations, I'm not very knowledgeable about this kind of stuff and I like to learn more. Secondly, I tried downloading elvish v0.18.0, and the behaviour was different. With this version, running ./gradlew --version
does not work either, and gives the same error message (which seems to come from cmd). However, I can run the script successfully by treating it like a command: gradlew --version
. And this does not work if I'm in another directory, so it really is using the script, and not a command called gradlew that's on the PATH. And here too, it seems that it's the batch file that's being used, even if it's the UNIX script that's being called.
I do see something about executables on windows in the release notes for version 0.19.0, but it's listed as a bug fix and is related to command completion, so I'm not sure why the above works on version 0.18.0 but not 0.19.0.
Is it possible that this is a bug that was introduced in version 0.19.0? Maybe the way that the scripts are run by elvish is different and broke things on windows? Probably not, since you said you didn't have any issues running scripts from windows, but maybe I misunderstood. In any case, I can switch to version 0.18.0 for the time being and I'll see if the issue persists when version 0.20.0 comes out. I'd be happy to look into this issue further but as I said, I don't know much about shells and all of this stuff, and I don't know Go either...
@SpacewaIker Presumably .\gradlew
still works?
The behavior you observed between 0.18.0 and 0.19.0 is likely caused by a Go standard library change (https://tip.golang.org/doc/go1.19#os-exec-path). When Elvish was compiled with an older version of Go compiler, it respected .
in PATH
, and thus supported gradlew
. The Go standard library change causes .
to be ignored.
That .\gradelew
but ./gradlew
doesn't seems to be a Go bug. I'll file one.
you said you didn't have any issues running scripts from windows
My apologies, I did not mean to leave that impression. I was showing how I don't have any issues running programs (i.e., binary executables) using a relative path like ./ls
. I then went on to explain that scripts do not work, using an implicit PATH lookup, relative path, or absolute path, because Windows does not support shebang lines. Elvish does, however, implicitly search for executables with a .bat
or .exe
extension. So when you type gradlew
it is finding, and running gradlew.bat
. And that works because of the association between the bat
extension and the cmd
shell.
@xiaq Yes actually! I hadn't thought of using .\
... And thank you for the explanation on the Go standard library change.
@krader1961 I see, thanks for the clarification.
So since .\
works, and the fact that ./
doesn't is because of Windows and/or Go, and not Elvish, then I suppose this issue can be closed! However, I do wonder: would it be possible to add something in my config file to make is so that when I type ./script
, .\script
is executed instead? And would this impact performance (for instance if it needs to check every command with regex before executing it)?
I can't think of a good reason why ./
shouldn't be supported, so it makes sense for Elvish to "fix" this quirk by rewriting /
to \
in relative command paths.
This is something that PowerShell seems to do anyway, ./foo
works there when you have a foo.bat
in the working directory.
I'm trying to execute a
gradlew
file in a java project like soThe command/file part is highlighted in green, seemingly indicating that elvish knows what I'm talking about. However, when I execute this, I get:
I'm fairly sure that when I first installed elvish, executing scripts like this worked, but now it doesn't anymore. I honestly don't know what could cause this issue, which is why my description is so vague. Has anyone else had this issue? Should I just try to reinstall elvish? Thanks!