如何在节点中为shell命令转义字符串?

javascript shell escaping node.js v8

23285 观看

5回复

1857 作者的声誉

nodejs中,执行外部命令的唯一方法是通过sys.exec(cmd)。我想调用外部命令并通过stdin给它数据。在nodejs中,似乎还没有办法打开命令然后将数据推送到它(仅执行并接收其标准+错误输出),所以看来我现在必须这样做的唯一方法是通过单个字符串命令,例如:

var dangerStr = "bad stuff here";
sys.exec("echo '" + dangerStr + "' | somecommand");

像这样的问题的大多数答案都集中在nodegs(使用谷歌的V8 Javascript引擎)或其他语言(如Python)的本机功能的正则表达式。

我想逃避dangerStr,以便像上面那样组成一个exec字符串是安全的。如果有帮助,dangerStr将包含JSON数据。

作者: Maciek 的来源 发布者: 2009 年 11 月 22 日

回应 (5)


-1

82096 作者的声誉

决定

有写入到外部命令的方式:process.createChildProcess文档)返回与一个对象write的方法。createChildProcess虽然不是很方便,因为它不会缓冲stdout和stderr,所以你需要事件处理程序来读取块中的输出。

var stdout = "", stderr = "";
var child = process.createChildProcess("someCommand");

child.addListener("output", function (data) {
    if (data !== null) {
        stdout += data;
    }
});
child.addListener("error", function (data) {
    if (data !== null) {
        stderr += data;
    }
});
child.addListener("exit", function (code) {
    if (code === 0) {
        sys.puts(stdout);
    }
    else {
        // error
    }
});

child.write("This goes to someCommand's stdin.");
作者: Matthew Crumley 发布者: 22.11.2009 09:51

36

385 作者的声誉

这是我使用的:

var escapeShell = function(cmd) {
  return '"'+cmd.replace(/(["\s'$`\\])/g,'\\$1')+'"';
};
作者: Sylvain Zimmer 发布者: 07.10.2011 09:37

14

558 作者的声誉

如果您需要简单的解决方案,您可以使用:

function escapeShellArg (arg) {
    return `'${arg.replace(/'/g, `'\\''`)}'`;
}

因此,克里斯·约翰森提到,你的字符串只会被单引号转义。

echo 'John'\''s phone';

它的工作原理bash是因为强烈的报价,感觉像它也适用于fish,但不会在工作zshsh

如果您有bash可以运行脚本shzsh与之一起运行脚本'bash -c \'' + escape('all-the-rest-escaped') + '\''

但实际上...... node.js会为你逃避所有需要的角色:

var child = require('child_process')
  .spawn('echo', ['`echo 1`;"echo $SSH_TTY;\'\\0{0..5}']);

child.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});

child.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});

这段代码将执行:

echo '`echo 1`;"echo $SSH_TTY;'\''\\0{0..5}'

并将输出:

stdout: `echo 1`;"echo $SSH_TTY;\'\\0{0..5}

或者一些错误。

看看http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options

顺便说一句,运行一堆命令的简单方法是:

require('child_process')
  .spawn('sh', ['-c', [
    'cd all/your/commands',
    'ls here',
    'echo "and even" > more'
  ].join('; ')]);

祝你今天愉快!

作者: Alex Yaroshevich 发布者: 03.04.2014 03:08

-2

67 作者的声誉

如果你还需要处理特殊字符(换行符等),你可以这样做:

str = JSON.stringify(str)
    .replace(/^"|"$/g,'') //remove JSON-string double quotes
    .replace(/'/g, '\'"\'"\'') //escape single quotes the ugly bash way

这假设您通过单引号使用Bash的引号,并且接收器可以理解JSON的C类转义。

作者: MicMro 发布者: 04.02.2017 06:25

7

5344 作者的声誉

永远不应该依赖于转移到shell参数的未知输入 - 几乎总会有一些你没想到的边缘情况允许用户在你的服务器上执行任意代码。

Node支持调用命令并单独传递每个参数,不需要转义。这是最安全的方法:

const { spawn } = require('child_process');
// Note that the arguments are in an array, not using string interpolation
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

文档在这里

作者: Will Richardson 发布者: 19.05.2018 11:50
32x32