On Saturday, April 06, 2013 03:48:55 AM Dan Douglas wrote: > Bash (4.2.45) uniquely does interpret such escapes for [[, which makes me > think this test should say "no": > > x=\\x; if [[ x == $x ]]; then echo yes; else echo no; fi >
Here's more data. Some permutations of escaped and quoted literal and expanded quotes and escapes. ksh changed from matching dash's results to being like everything else, so now only bash and dash will match a literal escape adjacent to some escaped or quoted literal or non-literal escape. #!/usr/bin/env python3 import subprocess, itertools class Shell(list): def __init__(self, shell, cmds): self.shell = shell super().__init__([(x, self.__run(x)) for x in cmds]) def __iter__(self): while True: try: self[0][1].communicate() yield (lambda x: (x[0], x[1].returncode, self.shell))(self.pop(0)) except IndexError: raise StopIteration() def __run(self, cmd): return subprocess.Popen([self.shell, "-c", cmd]) def main(): template = r'x=\\; case \\x in {0}{1}x) :;; *) false; esac' tests = [template.format(*x) for x in itertools.product(['"${x}"', '${x}', r'"\\"', r'\\'], repeat=2)] shells = [Shell(x, tests) for x in ["bash", "dash", "ksh", "mksh", "zsh", "bb", "posh", "jsh"]] print(" " * 54, " ".join(x.shell for x in shells)) for row in zip(*shells): print("{0:55}{1}".format(row[0][0], "".join(str(test) + (" " * len(shell)) for x, test, shell in row))) if __name__ == "__main__": main() # bash dash ksh mksh zsh bb posh jsh (heirloom) # x=\\; case \\x in "${x}""${x}"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in "${x}"${x}x) :;; *) false; esac 0 0 1 1 1 1 1 1 # x=\\; case \\x in "${x}""\\"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in "${x}"\\x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in ${x}"${x}"x) :;; *) false; esac 1 0 1 1 1 1 1 1 # x=\\; case \\x in ${x}${x}x) :;; *) false; esac 0 0 1 1 1 1 1 1 # x=\\; case \\x in ${x}"\\"x) :;; *) false; esac 1 0 1 1 1 1 1 1 # x=\\; case \\x in ${x}\\x) :;; *) false; esac 1 0 1 1 1 1 1 1 # x=\\; case \\x in "\\""${x}"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in "\\"${x}x) :;; *) false; esac 0 0 1 1 1 1 1 1 # x=\\; case \\x in "\\""\\"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in "\\"\\x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in \\"${x}"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in \\${x}x) :;; *) false; esac 0 0 1 1 1 1 1 1 # x=\\; case \\x in \\"\\"x) :;; *) false; esac 1 1 1 1 1 1 1 1 # x=\\; case \\x in \\\\x) :;; *) false; esac 1 1 1 1 1 1 1 1 -- Dan Douglas