nushell / nushell

A new type of shell
https://www.nushell.sh/
MIT License
30.92k stars 1.58k forks source link

Msys2 & POSIX compatibility layer #11983

Open helmesjo opened 4 months ago

helmesjo commented 4 months ago

Question

In my setup I previously used msys2 + fish (latter installed through the bundled package manager pacman). This works fine and it behaves as-if in a unix-like environment (paths are unix, bash scripts execute as expected etc). nushell however (with my limited understanding on the matter), even though launched inside an msys2 environment, still behaves as if I'm running on windows (eg. ./script.sh fails, I have to explicitly spell out bash ./script.sh or set default program for .sh, and all paths are windows paths).

Example:

# script.sh:

#!/usr/bin/env bash
echo "hello"
# inside Msys2 UCRT64

$ fish -c "pwd"
/c/Users/fho

$ nu -c "pwd"
C:\Users\fho

# uses shebang, runs with bash 
$ fish -c "./script.sh"
hello

# does not use shebang, runs with whatever is set as default for .sh in windows 
$ nu -c "./script.sh"

Again, I haven't played around with this before and know very little to none about the intrinsic of Msys2.

Additional context and details

Installed with winget install Nushell.Nushell, but also tried with cargo install nu inside an msys2 shell (with cargo set to the x86_64-pc-windows-gnu toolchain).

helmesjo commented 4 months ago

Possibly (partially) related: #7044

fdncred commented 4 months ago

This seems correct/as designed to me. Nushell knows nothing about shebangs and is not posix compatible.

helmesjo commented 4 months ago

Yep, that's true. Though:

POSIX-compliance. Nu intentionally optimizes for a pleasant experience over matching how commandline programs work in a POSIX-compliant way. It's important to be able to interop between Nu commands and external commands, but maintaining strict compatibility is a non-goal.

So while no effort is put into maintain strict compatibility, I read it as suggesting some things are expected to work (not saying my case falls under that, but it could possibly do).

Now, without any real knowledge of how the POSIX compatibility layer operates in msys2 (I'm guessing it just highjacks winapi calls), it does seem that nushell internally handles paths in a very explicit/hard-coded manner. See the following example, where nushell appears to automagically prefix my passed path with C:/ for no apparent reason:

# inside Msys2 UCRT64 with nushell

# built-in ls
$ ls /c/tmp
Error: nu::shell::directory_not_found

  × Directory not found
   ╭─[entry #3:1:1]
 1 │ ls /c/tmp
   ·    ───┬──
   ·       ╰── directory not found
   ╰────
  help: C:/c/tmp does not exist

$ ls C:/tmp
╭───┬──────────────┬──────┬──────┬────────────────╮
│ # │     name     │ type │ size │    modified    │
├───┼──────────────┼──────┼──────┼────────────────┤
│ 0 │ C:\tmp\hello │ dir  │  0 B │ 10 minutes ago │
╰───┴──────────────┴──────┴──────┴────────────────╯

# external ls
$ ^ls /c/tmp
hello

# external dir even works
$ ^dir /c/tmp
hello

So while nushell doesn't maintain POSIX compatibility, it rather seems to be the case (AFAICT) that it internally makes assumptions & does some additional path-handling that I guess just shouldn't be done (IMO it should just take the path as it was passed and not try to modify it).

fdncred commented 4 months ago

I understand what you're saying but you installed the windows version of nushell and it's behaving like a windows version of nushell with drive:\path functionality. The only way to change that right now is to install a non-windows version of nushell. I'm not sure if msys2 would accept that or not.

helmesjo commented 4 months ago

According to Chat GPT:

The POSIX compatibility layer in MSYS2 provides equivalents for many common WINAPI functions. Some of the WINAPI functions that are commonly considered part of the POSIX API in MSYS2 include:

  1. File I/O Functions:

    • CreateFile, OpenFileopen
    • ReadFile, WriteFileread, write
    • CloseHandleclose
    • GetFileSizestat (to get file size information)
  2. Directory Functions:

    • FindFirstFile, FindNextFileopendir, readdir
    • CreateDirectory, RemoveDirectorymkdir, rmdir
  3. Process and Thread Functions:

    • CreateProcessfork, exec
    • WaitForSingleObject, WaitForMultipleObjectswaitpid
    • CreateThreadpthread_create
  4. Synchronization Functions:

    • CreateEvent, SetEvent, WaitForSingleObject → POSIX pthreads or semaphores
  5. Environment Functions:

    • GetEnvironmentVariablegetenv
    • SetEnvironmentVariablesetenv
  6. Miscellaneous Functions:

    • Sleepusleep
    • GetTickCount, GetSystemTimeclock_gettime

These are just some examples, and there are many more WINAPI functions and their POSIX equivalents available in the MSYS2 environment.

Given that this is correct, nushell should just operate as normal and "everything should just work".

helmesjo commented 4 months ago

I understand what you're saying but you installed the windows version of nushell and it's behaving like a windows version of nushell with drive:\path functionality. The only way to change that right now is to install a non-windows version of nushell. I'm not sure if msys2 would accept that or not.

I agree, my suggestion was rather that it might be the case that nushell internally does some explicit handling that could be considered redundant and removing it could potentionally allow it to function correctly under both environments. But I'm not expecting someone to dive into this, was rather wondering if anyone had knowledge of this.

I can have a look, but any directions are appreciated. :)

fdncred commented 4 months ago

You're the first person I know of to bring this topic up. So, I don't think anyone I know has looked into it. Feel free to dig around and see what you can find. We'd probably accept a PR if it makes this work and doesn't break anything else and isn't too intrusive.