Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] FAQ 3.31 revision (lack of bash/zsh interchangeability) (was: Re: disown -a)



Daniel Shahaf wrote on Wed, Mar 03, 2021 at 00:05:38 +0000:
> [...] https://github.com/zsh-users/zsh/blob/5ede2c55f144593c16498c3131a76e188114a9c6/Etc/FAQ.yo#L2056-L2102,
> the first and penultimate paragraphs.
⋮
> zsh is not a bug-for-bug reimplementation of bash.

This prompted me to revisit that FAQ entry.

Patch series attached.  I'm also attaching the resulting FAQ text with
the series applied.

Notable is that 0003 is an interim state that compiles, in the sense
that «make -C Etc» passes, but shouldn't be built and released.  The log
message explains why.  (It also features an xkcd reference.)

Feedback welcome.

Cheers,

Daniel

[[[
sect(Why does my bash script report an error when I run it under zsh?)
label(331)

  em(tl;dr:) bash is not the reference implementation of zsh, and zsh is not
  a bug-for-bug compatible reimplementation of bash.

  bash and zsh are different programming languages.  They are not
  interchangeable; programs written for either of these languages will,
  in general, not run under the other.  (The situation is similar with
  many other pairs of closely-related languages, such as Python 2 and
  Python 3; C and C++; and even C89 and C11.)

  When bash and zsh behave differently on the same input, whether zsh's
  behaviour is a bug does not depend on what bash does on the same
  input; rather, it depends on what zsh's user manual specifies.
  (By way of comparison, it's not a bug in Emacs that mytt(:q!) doesn't
  cause it to exit.)

  That being said, the bash and zsh languages do have a common subset, and it is
  feasible to write non-trivial pieces of code that would run under either of
  them, if one is sufficiently familiar with both of them.  However,
  a difference between bash's behaviour and zsh's does not imply that
  zsh has a bug.  The difference might be a bug in zsh, a bug in bash, or
  a bug in neither shell
  (see link(3.1)(31) for an example).

  The recommended way to deal with these differences depends on what kind
  of piece of code is in question: a myem(script) or a myem(plugin).
  
  For em(scripts) emdash() external commands that
  are located in tt($PATH), or located elsewhere and are executed by
  giving their path explicitly (as in mytt(ls), mytt(/etc/rc.d/sshd),
  and mytt(./configure)) emdash() the answer is simple:

  Don't run bash scripts under zsh.  If the scripts were written for
  bash, run them in bash.  There's absolutely no problem with having
  mytt(#!/usr/bin/env bash) scripts even if mytt(zsh) is your shell for
  interactive sessions.
  
  In fact, if you've recently changed to zsh, we myem(recommend) that
  you keep your scripts as mytt(#!/usr/bin/env bash), at least for
  a while: this would make the change more gradual and flatten your
  learning curve.  Once you're used to zsh, you can decide for each
  script whether to port it to zsh or keep it as-is.

  For myem(plugins) emdash() pieces of code
  executed within the shell itself, loaded via the mytt(.),
  mytt(source), or mytt(autoload) builtins, added to mytt(.zshrc), or
  pasted interactively at the shell prompt emdash() one may consider it
  worthwhile to invest the effort to make them runnable under either shell.
  However, as mentioned above, doing so requires one to be familiar with both
  shells, and either steer clear of their differences or handle them explicitly
  with conditional code (such as mytt(if test -n "$ZSH_VERSION")).

  In summary,
  if you'd like to run a bash script or plugin under zsh, you must port the script or plugin
  properly, reviewing it line by line for differences between the two
  languages and adjusting it accordingly, just like you would
  when translating a book from American English to British English.
]]]
From d4bbcc7708e2ef29225fc6191d3b3672277be68d Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Wed, 3 Mar 2021 00:17:53 +0000
Subject: [PATCH 1/4] FAQ: 3.31: Add a one-sentence summary

---
 Etc/FAQ.yo | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index 7aeddd89c..9831b027c 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -2056,6 +2056,9 @@ sect(Why doesn't the expansion mytt(*.{tex,aux,pdf}) do what I expect?)
 sect(Why does my bash script report an error when I run it under zsh?)
 label(331)
 
+  em(tl;dr:) bash is not the reference implementation of zsh, and zsh is not
+  a bug-for-bug compatible reimplementation of bash.
+
   bash and zsh are different programming languages.  They are not
   interchangeable; programs written for either of these languages will,
   in general, not run under the other.  (The situation is similar with
From cd0575d297b473a3acb1dc0f8c6408435d45b956 Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Wed, 3 Mar 2021 00:18:18 +0000
Subject: [PATCH 2/4] FAQ: 3.31: Tweak summary paragraph

---
 Etc/FAQ.yo | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index 9831b027c..f0a50489c 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -2099,9 +2099,10 @@ label(331)
   (By way of comparison, it's not a bug in Emacs that mytt(:q!) doesn't
   cause it to exit.)
 
-  If you'd like to run a bash script under zsh, you must port the script
+  In summary,
+  if you'd like to run a bash script or plugin under zsh, you must port the script or plugin
   properly, reviewing it line by line for differences between the two
-  languages and adjusting the script accordingly, just like you would
+  languages and adjusting it accordingly, just like you would
   when translating a book from American English to British English.
 
 
From b06b24dac90e02df9a72a234ce882b7e29c0c1ff Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Wed, 3 Mar 2021 00:18:24 +0000
Subject: [PATCH 3/4] FAQ: 3.31: Move two paragraphs unchanged, reordering them

Factored out from the next patch for readability of the diff.

The answer, as it stands in this commit, doesn't flow correctly.  In
order to keep the diffs small and easy to follow, this commit simply
adds a TODO to record this issue, a TODO which is fixed by the next
commit in this series (the child of this commit).  Thus, a request:

DEAR PEOPLE FROM THE FUTURE: Please don't create new branches off this
commit; create them off the parent commit or off the child commit
instead.  Thank you.
---
 Etc/FAQ.yo | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index f0a50489c..e444c0b77 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -2065,6 +2065,22 @@ label(331)
   many other pairs of closely-related languages, such as Python 2 and
   Python 3; C and C++; and even C89 and C11.)
 
+  When bash and zsh behave differently on the same input, whether zsh's
+  behaviour is a bug does not depend on what bash does on the same
+  input; rather, it depends on what zsh's user manual specifies.
+  (By way of comparison, it's not a bug in Emacs that mytt(:q!) doesn't
+  cause it to exit.)
+
+  Since the bash and zsh languages do have a common subset, it is
+  feasible to write non-trivial plugins that would run under either of
+  them, if one is sufficiently familiar with both of them.  However,
+  a difference between bash's behaviour and zsh's does not imply that
+  zsh has a bug.  It myem(might) be a bug in zsh, but it might also be
+  a bug in bash, or simply a difference that isn't a bug in either shell
+  (see link(3.1)(31) for an example).
+
+  COMMENT(TODO: Move here the paragraph about "That's the answer for..." and reverse it)
+
   So, don't run bash scripts under zsh.  If the scripts were written for
   bash, run them in bash.  There's absolutely no problem with having
   mytt(#!/usr/bin/env bash) scripts even if mytt(zsh) is your shell for
@@ -2076,6 +2092,7 @@ label(331)
   learning curve.  Once you're used to zsh, you can decide for each
   script whether to port it to zsh or keep it as-is.
 
+  COMMENT(TODO: That's the paragraph the comment above refers to)
   That's the answer for myem(scripts), i.e., for external commands that
   are located in tt($PATH), or located elsewhere and are executed by
   giving their path explicitly (as in mytt(ls), mytt(/etc/rc.d/sshd),
@@ -2085,20 +2102,6 @@ label(331)
   pasted interactively at the shell prompt emdash() the answer is
   different.
 
-  Since the bash and zsh languages do have a common subset, it is
-  feasible to write non-trivial plugins that would run under either of
-  them, if one is sufficiently familiar with both of them.  However,
-  a difference between bash's behaviour and zsh's does not imply that
-  zsh has a bug.  It myem(might) be a bug in zsh, but it might also be
-  a bug in bash, or simply a difference that isn't a bug in either shell
-  (see link(3.1)(31) for an example).
-
-  When bash and zsh behave differently on the same input, whether zsh's
-  behaviour is a bug does not depend on what bash does on the same
-  input; rather, it depends on what zsh's user manual specifies.
-  (By way of comparison, it's not a bug in Emacs that mytt(:q!) doesn't
-  cause it to exit.)
-
   In summary,
   if you'd like to run a bash script or plugin under zsh, you must port the script or plugin
   properly, reviewing it line by line for differences between the two
From 75500491625f69faaab45f5b3775720acfecdbbe Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Wed, 3 Mar 2021 00:34:11 +0000
Subject: [PATCH 4/4] FAQ: 3.31: Rearrange

---
 Etc/FAQ.yo | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
index e444c0b77..d899b61c4 100644
--- a/Etc/FAQ.yo
+++ b/Etc/FAQ.yo
@@ -2071,17 +2071,23 @@ label(331)
   (By way of comparison, it's not a bug in Emacs that mytt(:q!) doesn't
   cause it to exit.)
 
-  Since the bash and zsh languages do have a common subset, it is
-  feasible to write non-trivial plugins that would run under either of
+  That being said, the bash and zsh languages do have a common subset, and it is
+  feasible to write non-trivial pieces of code that would run under either of
   them, if one is sufficiently familiar with both of them.  However,
   a difference between bash's behaviour and zsh's does not imply that
-  zsh has a bug.  It myem(might) be a bug in zsh, but it might also be
-  a bug in bash, or simply a difference that isn't a bug in either shell
+  zsh has a bug.  The difference might be a bug in zsh, a bug in bash, or
+  a bug in neither shell
   (see link(3.1)(31) for an example).
 
-  COMMENT(TODO: Move here the paragraph about "That's the answer for..." and reverse it)
+  The recommended way to deal with these differences depends on what kind
+  of piece of code is in question: a myem(script) or a myem(plugin).
+  
+  For em(scripts) emdash() external commands that
+  are located in tt($PATH), or located elsewhere and are executed by
+  giving their path explicitly (as in mytt(ls), mytt(/etc/rc.d/sshd),
+  and mytt(./configure)) emdash() the answer is simple:
 
-  So, don't run bash scripts under zsh.  If the scripts were written for
+  Don't run bash scripts under zsh.  If the scripts were written for
   bash, run them in bash.  There's absolutely no problem with having
   mytt(#!/usr/bin/env bash) scripts even if mytt(zsh) is your shell for
   interactive sessions.
@@ -2092,15 +2098,14 @@ label(331)
   learning curve.  Once you're used to zsh, you can decide for each
   script whether to port it to zsh or keep it as-is.
 
-  COMMENT(TODO: That's the paragraph the comment above refers to)
-  That's the answer for myem(scripts), i.e., for external commands that
-  are located in tt($PATH), or located elsewhere and are executed by
-  giving their path explicitly (as in mytt(ls), mytt(/etc/rc.d/sshd),
-  and mytt(./configure)).  For myem(plugins) emdash() code that is
-  executed within the shell itself, that's loaded via the mytt(.),
+  For myem(plugins) emdash() pieces of code
+  executed within the shell itself, loaded via the mytt(.),
   mytt(source), or mytt(autoload) builtins, added to mytt(.zshrc), or
-  pasted interactively at the shell prompt emdash() the answer is
-  different.
+  pasted interactively at the shell prompt emdash() one may consider it
+  worthwhile to invest the effort to make them runnable under either shell.
+  However, as mentioned above, doing so requires one to be familiar with both
+  shells, and either steer clear of their differences or handle them explicitly
+  with conditional code (such as mytt(if test -n "$ZSH_VERSION")).
 
   In summary,
   if you'd like to run a bash script or plugin under zsh, you must port the script or plugin


Messages sorted by: Reverse Date, Date, Thread, Author