Properly escape JSON for use with bash

2019-09-20 09:06发布

问题:

I have this node.js script:

const cp = require('child_process');
const json = JSON.stringify(['foo','bar']);

const k = cp.spawn('bash');

const cmd = `
  export foo=${json}
`;

k.stdin.end(`
    ${cmd}
    echo "foo is: $foo"; exit 0;
`);


k.stdout.pipe(process.stdout);
k.stderr.pipe(process.stderr);

I get this output to stdout:

foo is: '[foo,bar]'

and am trying to get this instead:

foo is: ["foo","bar"]

it looks like this phenomena is what's happening, but I can't figure out why:

Why JSON strings transform with bash shell

does anyone know what's happening in my script and how to get the JSON string to remain JSON as it travels through bash?

回答1:

If you want bash to keep a string unchanged, you need to use single quotes.

Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

This code generates the desired output:

const cp = require('child_process');
const json = JSON.stringify(['foo','bar']);

const k = cp.spawn('bash');

// NOTE single quotes around '${json}':
const cmd = `
  export foo='${json}' 
`;

k.stdin.end(`
    ${cmd}
    echo "foo is: $foo"; exit 0;
`);


k.stdout.pipe(process.stdout);
k.stderr.pipe(process.stderr);


回答2:

Put single quotes around the JSON.

const cmd = `
  export foo='${json}'
`;

But if there are any single quotes in the JSON they need to be outside of the quotes that delimit the JSON, and inside a set of double quotes instead. So you should first do:

json = json.replace(/'/g, "'\"'\"'");


标签: json bash shell