0

I came across this precommand modifier in man zshbuiltins which refers to man zshmisc. I tried searching for examples, but didn't find any.

Here's what my man zshmisc page shows:

PRECOMMAND MODIFIERS
   A simple command may be preceded by a precommand modifier, which  will  alter
   how  the  command is interpreted.  These modifiers are shell builtin commands
   with the exception of nocorrect which is a reserved word.

   -      The command is executed with a `-' prepended to its argv[0] string.

Here's what I tried:

prompt> - echo
cd: no such file or directory: /Users/bmiller286/Projects/bgovecholonestar-eventsvc

What's an example or two of how to use this precommand modifier?

EDIT: It looks like oh-my-zsh aliased - to be cd -, which explains why cd was complaining. So far, I've only seen one use case that supports this paradigm of prepending an - to argv[0]--and that's login shells.

The documentation (above) acts like this is a common paradigm not specific to login shells. So,

  1. Is this basically a login-shell only thing?
  2. If not, is this a common easter egg that many programs support?
  3. If I were wanting to do an internet search for programs that support it, what would I search for? (it's hard to search for - because many engines see it as a negative operator. Even searching for precommand modifiers turned up pretty much nothing for this thing)
Brandon
  • 101
  • 4
  • See also: [Changing argv\[0\] from the command line](https://unix.stackexchange.com/a/666850) – Stéphane Chazelas Sep 17 '21 at 19:16
  • @StéphaneChazelas, thank you for that reference. I tried running each of those examples (terminal commands) and none of them worked for me. When I tried executing `- ps -f` I received `cd: too many arguments`. Any thoughts? – Brandon Sep 17 '21 at 20:14
  • @StéphaneChazelas Also, when I ran `ARGV0="new value for ps's argv[0]" ps -f`, I didn't see `new value for ps's argv[0]` anywhere in the list. – Brandon Sep 17 '21 at 20:16
  • 1
    You might have an alias that overrides the `-` builtin. See what `type -- -` outputs – Stéphane Chazelas Sep 17 '21 at 20:17
  • Are you even sure you're running the `zsh` shell. What's the output of `echo "$ZSH_VERSION"; emulate`? – Stéphane Chazelas Sep 17 '21 at 20:18
  • @StéphaneChazelas Wow, you're right! I'm using oh-my-zsh. I wonder if that added it. I'll go see how to unalias it. – Brandon Sep 17 '21 at 20:19
  • @StéphaneChazelas I'm running version `5.7.1` as per the output of your command. – Brandon Sep 17 '21 at 20:20
  • @StéphaneChazelas when I run `unalias -` I get `unalias: not enough arguments`. I'm pretty sure I didn't have that problem with other aliases in the past. Do I have to do something special to unalias `-`? – Brandon Sep 17 '21 at 20:24
  • 1
    `-` is the end-of-option marker in zsh builtins like in the Bourne / Korn shells, and like `--` in POSIX utilities. So, you'd need `unalias - -` or `unalias -- -` (both `-` and `--` are supported as end-of-option marker in `zsh`, like in modern versions of ksh). – Stéphane Chazelas Sep 17 '21 at 20:25
  • @StéphaneChazelas Thank you. I also found a way: `unalias -m '\-'`. Now `- ps -f` runs without error, but doesn't display like it does on that first link. Maybe it's working and I can't connect the dots. – Brandon Sep 17 '21 at 20:39
  • What does `- ps -f` show? How about `- ps -o args`? What's your OS? Is it Unix-like? Do you possibly also have a `ps` function overriding the `ps` command? What does `type ps` give you? – Stéphane Chazelas Sep 17 '21 at 20:41
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/129733/discussion-between-brandon-and-stephane-chazelas). – Brandon Sep 17 '21 at 20:48

1 Answers1

2

This:

% cat > .bash_login
echo this is a login shell
% bash
bash$ exit
% - bash
this is a login shell
bash$

or in English: Some shells check their argv[0], and if there's a leading dash there, they go into "login shell" mode. Whatever that means for the various shells, probably changes to which startup files are read, at least. For Bash, see 6.1 Invoking Bash and 6.2 Bash Startup Files; for zsh, at least 5.1 Startup/Shutdown Files in the manual mentions login shells (but I can't find the part where it says how the shell determines if it's a login shell).

I suppose Zsh just gives a simple way to access that functionality, here, in case you'd need it. There might be other ways to do that too, at least Bash and Dash take the -l option to mean the same thing.

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
  • Do you perhaps have a good search string that I may use to find more information about this behavior? – Brandon Sep 17 '21 at 18:53
  • @Brandon, "login shell"? – ilkkachu Sep 17 '21 at 19:05
  • It does look like `- zsh` will open zsh in login shell mode. It looks like a handful of other programs also use the leading dash in ARGV[0] to signal it to do something special. This whole thing is new to me and I am finding it difficult to get my mind wrapped around this easter-egg-of-sorts behavior. Is there an abstract way to look at the - argv[0] paradigm? Perhaps a common feature name? Or is this one of those *nix things that got started back in 1970ish that is still supported but we can mostly forget about? – Brandon Sep 17 '21 at 21:33
  • @Brandon you keep sayin "Easter egg" as if this is some hidden joke from the devs. On the contrary, this is a well-known, widely prevalent way of starting login shells. Even fish with its upending of conventions [conforms to this](https://github.com/fish-shell/fish-shell/blob/b2f791b577e9041fbe28042771b80146849d37af/src/fish.cpp#L398). Of course *you* can forget about it, it's not as if you're writing a shell that you hope will become widely used, are you? – muru Sep 18 '21 at 02:55
  • 1
    @Brandon, well, it's a documented feature, so not really an Easter Egg, though I can see it might look like that. I don't know the real history here, but it might be something that "seemed a good idea at the time", and then got stuck. Like the thing about having `ls` hide all files that start with a dot, and not just `.` and `..`. Some programs do change their behaviour based on the name they're started with, e.g. Busybox (determines which utility to run), and zsh (compatibility modes). Maybe `grep`/`egrep` on some systems, too. But AFAIK the `-` thing is specific to login shells. – ilkkachu Sep 18 '21 at 12:12