Read arguments with fish -c

This reads any additional positional arguments given to `fish -c` into
$argv.

We don't handle the first argument specially (as `$0`) as that's confusing and
doesn't seem very useful.

Fixes #2314.
This commit is contained in:
Fabian Homborg 2020-09-26 14:45:51 +02:00
parent 396d7e105f
commit fa0c9f90f8
3 changed files with 15 additions and 2 deletions

View file

@ -8,7 +8,7 @@ Synopsis
::
fish [OPTIONS] [-c command] [FILE [ARGUMENTS...]]
fish [OPTIONS] [-c command] [FILE] [ARGUMENTS...]
Description
-----------
@ -17,7 +17,7 @@ fish is a command-line shell written mainly with interactive use in mind. This p
The following options are available:
- ``-c`` or ``--command=COMMANDS`` evaluate the specified commands instead of reading from the commandline
- ``-c`` or ``--command=COMMANDS`` evaluate the specified commands instead of reading from the commandline, passing any additional positional arguments via :ref:`$argv <variables-argv>`. Note that, unlike other shells, the first argument is *not* the name of the program (``$0``), but simply the first normal argument.
- ``-C`` or ``--init-command=COMMANDS`` evaluate the specified commands after reading the configuration, before running the command specified by ``-c`` or reading interactive input

View file

@ -489,6 +489,14 @@ int main(int argc, char **argv) {
fish_xdm_login_hack_hack_hack_hack(&opts.batch_cmds, argc - my_optind,
argv + my_optind);
}
// Pass additional args as $argv.
// Note that we *don't* support setting argv[0]/$0, unlike e.g. bash.
wcstring_list_t list;
for (char **ptr = argv + my_optind; *ptr; ptr++) {
list.push_back(str2wcstring(*ptr));
}
parser.vars().set(L"argv", ENV_DEFAULT, std::move(list));
res = run_command_list(parser, &opts.batch_cmds, {});
parser.libdata().exit_current_script = false;
} else if (my_optind == argc) {

View file

@ -38,3 +38,8 @@ $fish -c 'if status --is-login ; echo login shell ; else ; echo not login shell
$fish -c 'if status --is-login ; echo login shell ; else ; echo not login shell ; end; if status --is-interactive ; echo interactive ; else ; echo not interactive ; end' -l
# CHECK: login shell
# CHECK: not interactive
$fish -c 'string escape $argv' 1 2 3
# CHECK: 1
# CHECK: 2
# CHECK: 3