Support bash $’ANSI-C quoted strings’ in child_process.exec

  • Version: v14.14.0
  • Platform: Linux myhostname 5.8.0-44-generic #50-Ubuntu SMP Tue Feb 9 06:29:41 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

What steps will reproduce the bug?

const exec = require('child_process').exec;

exec("printf '%%s' $'hello'", (error, stdout, stderr) => console.log(JSON.stringify(stdout)));

How often does it reproduce? Is there a required condition?

Always?

What is the expected behavior?

$ printf '%%s' $'hello'
hello$ 

(there’s no newline when using printf, that’s why the $ is at the end instead of on the next line)

What do you see instead?

$ node /tmp/above_code_snippet.js
"$hello"
$

Additional information

ANSI strings in bash are documented here https://www.gnu.org/software/bash/manual/bash.html#ANSI_002dC-Quoting and work like this:

$ echo $'some\\ntext'
some\ntext
$ echo 'some\\ntext'
some\\ntext

See also yargs/yargs-parser#346

1 possible answer(s) on “Support bash $’ANSI-C quoted strings’ in child_process.exec

  1. I might be wrong but I think this feature is a bashism, not part of the standard POSIX shell. Note that the default shell is /bin/sh on Unix-like systems (see documentation), so you might want to specify a different one (probably the result of command -v bash).

    import { exec } from 'child_process';
    
    exec('command -v bash', (err, stdout) =>
      exec(
        "printf '%%s' $'hello'",
        { shell: stdout.trim() },
        (error, stdout, stderr) => console.log(JSON.stringify(stdout))
      )
    );

    Anyway, I don’t think this is a Node.js bug, exec is passing the string given straight to the shell, so there’s nothing we can do here. Generally one would prefer to stick to POSIX-compliant shell code to ensure the code works everywhere, but if you are not concerned about distributability my suggested code should do just fine.