1

In writing the question:

How to touch and cat file named -

I was trying to generalise to a case where a file named - was stored in a variable.

In zsh, I tried setting a variable to contain a single hyphen:

% var=-
% echo $var

% var='-'
% echo $var

% var=\-
% echo $var

%

Why don't these work?

Why is zsh different to bash in this regard?

How do I set $var to -?

Tom Hale
  • 30,455

1 Answers1

6

Again, as often, it's not the value actually in the variable, but how the variable is. The echo in this case. Zsh's echo takes the single dash as an end of options indicator, so it's removed. Online manual:

Note that for standards compliance a double dash does not terminate option processing; instead, it is printed directly. However, a single dash does terminate option processing, so the first dash, possibly following options, is not printed, but everything following it is printed as an argument. The single dash behaviour is different from other shells. For a more portable way of printing text, see printf, and for a more controllable way of printing text within zsh, see print.

So we have:

zsh% echo -

zsh% echo - -n
-n
zsh% var=-
zsh% printf "%s\n" "$var"
-

See also:

ilkkachu
  • 138,973
  • So this needs to be seen as a bug in zsh. – schily Sep 08 '18 at 15:18
  • 1
    @schily, sure, go ahead and report is as such. – ilkkachu Sep 08 '18 at 15:24
  • See also: https://www.zsh.org/mla/workers/2018/msg00202.html – Stéphane Chazelas Sep 09 '18 at 18:40
  • @schily : I wouldn't see it as a bug. The behaviour is exactly as documented in the zsh man page. Note that if you don't like this behaviour of the echo builtin in Zsh, you can always use, i.e., command echo $var instead of echo $var and your dash will be printed. – user1934428 Sep 10 '18 at 08:46
  • @user1934428, using the system's echo will not necessarily help. For instance, on GNU systems, you'll still have problems for values of $var like -n, --version, -Ene... In zsh, echo -E - $var, print -r -- $var and printf '%s\n' "$var" should be equivalent but only the latter one is portable to other Bourne-like shells which is why zsh and POSIX recommend to use printf here. Only zsh and yash echos are able to output arbitrary data. – Stéphane Chazelas Sep 10 '18 at 10:09
  • @StéphaneChazelas : Sorry to disagree in this point, but I tried it on Cygwin (which is, admittedly, not Linux, but at least the utilities are GNU based), and /bin/echo - outputs does output a dash. Right now, I also have access to some (somewhat older) Linux, and here too, it works. Could you cite a source which would explain why my approach wouldn't work? – user1934428 Sep 10 '18 at 16:02
  • @user1934428, yes, that echo - handling is specific to zsh (some old versions of pdksh output nothing on echo - but that was a bug then). I was pointing out that GNU echo (and most other echo implementations) have issues of their own, not on - but other values of $var like --version, -nene... So using another echo in general is not the best solution. – Stéphane Chazelas Sep 10 '18 at 16:07