edc / bass

Make Bash utilities usable in Fish shell
MIT License
2.2k stars 70 forks source link

`$1` is set in contrast to bash #89

Open hellow554 opened 3 years ago

hellow554 commented 3 years ago

a.sh:

echo $1

bash -c 'source a.sh'

bass source a.sh

source a.sh

This confuses some scripts which might accept an optional argument (in my case it's the poky script from yocto)

hellow554 commented 3 years ago

Funny enough, when I type

fish ~/.local.share/omf.pkg/bass/functions/bass.fish source a.sh the output is empty as well like bash would do. That's something beyond my paygrade ;)

edc commented 3 years ago

This is very interesting. I looked into it, and this seems hard to fix because we intentionally set $1 etc to mimic running the script:

$ cat a.sh
echo $1
$ bass ./a.sh abc
abc
hellow554 commented 3 years ago

wontfix is a disappointing label :(

The difference is that your command is bass ./a.sh and mine is bass source a.sh. So you could distinguish it.

hellow554 commented 3 years ago

The difference is that your command is bass ./a.sh and mine is bass source a.sh. So you could distinguish it.

ping @edc

skycaptain commented 3 years ago

I was facing the same issue today. I was just about commiting a fish version of the oe-init-build-env and oe-setup-builddir scripts to their mailing list, before a came across this project, which seems more reasonable to me, as rewriting bash scripts for fish can be tenacious and expensive.

Anyway, I had a look at the sources, especially at this part:

    command = 'eval $1 && ({}; alias) >&{}'.format(
        env_reader,
        pipe_w
    )
    args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])]

@edc Could you please explain what passing 'bass' as a parameter to bash here does?

I guess changing these lines to the following would solve the issue for us:

    command = 'eval $0 && ({}; alias) >&{}'.format(
        env_reader,
        pipe_w
    )
    args = [BASH, '-c', command, ' '.join(sys.argv[1:])]
zavorka commented 3 years ago

@skycaptain

@edc Could you please explain what passing 'bass' as a parameter to bash here does?

I guess changing these lines to the following would solve the issue for us:

    command = 'eval $0 && ({}; alias) >&{}'.format(
        env_reader,
        pipe_w
    )
    args = [BASH, '-c', command, ' '.join(sys.argv[1:])]

Scripts that access the value of $0 expect to find a path to an interpreter or a path to themselves, a space-delimited list of words will thus likely be something they are not prepared to handle.

skycaptain commented 3 years ago

Thanks @zavorka. I can confirm that your PR is working with the openembedded init script.

edc commented 3 years ago

According to the -c section of bash manual:

Read and execute commands from the first non-option argument command_string, then exit. If there are arguments after the command_string, the first argument is assigned to $0 and any remaining arguments are assigned to the positional parameters. The assignment to $0 sets the name of the shell, which is used in warning and error messages.

I think [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])] is the appropriate way to invoke it, though we should probably replace bass with something more appropriate because clearly it is not just "used in warning and error messages".