Search code examples
shellwindows-subsystem-for-linuxfish

fish executing file with relative path


I'm having an issue where I can't run fish x.fish or fish ./x.fish, but I can run fish (pwd)/x.fish, AKA using an absolute path to my file instead of a relative one or with .. I haven't had this issue in previous installations, but my setup is a bit different this time so I'd appreciate any advice.

Version: fish --version = fish, version 3.3.1.

Setup: installed fish as shell in Windows 11 WSL, and set it as default shell.

My script named main.fish:

echo "in main.fish script"

running in the main.fish's parent directory:

fish main.fish = main.fish: No such file or directory

fish /main.fish = ./main.fish: No such file or directory

fish (pwd)/main.fish = in main.fish script

What is stopping me from running a fish file with a relative path? Maybe unrelated, setting the file to executable and running ./main.fish and adding #! /usr/bin/fish results in ./main.fish: No such file or directory.

![enter image description here

I'm stumped. Reiterating, any help would be appreciated.

EDIT:

I ran strace fish.main, and it's large but ends with

openat(AT_FDCWD, "main.fish", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
openat(AT_FDCWD, "/usr/share/locale/C.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/C.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale/C/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/C.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/C.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/share/locale-langpack/C/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(0x88, 0x4), ...}) = 0
write(3, "main.fish: No such file or direc"..., 37main.fish: No such file or directory
) = 37
close(3)                                = 0
getpid()                                = 11251
getpgrp()                               = 11248
ioctl(0, TIOCGPGRP, [11248])            = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
exit_group(127)                         = ?
+++ exited with 127 +++

Solution

  • This was answered in https://github.com/fish-shell/fish-shell/issues/9040.

    Fish always reads its configuration, even non-interactively.

    That means if you have a cd ~ in config.fish, then running

    fish ./x.fish
    

    will start fish, which will cd to the home directory, and then attempt to run "x.fish" in the home directory.

    The solution is to guard that cd ~ with status is-interactive:

    if status is-interactive
        cd ~
    end
    

    (or remove it entirely)