如何在节点中为shell命令转义string?

在nodejs中 ,执行外部命令的唯一方法是通过sys.exec(cmd)。 我想调用一个外部命令,并通过stdin给它的数据。 在nodejs中,似乎还没有一种方法可以打开一个命令,然后将数据推送给它(只能执行并接收其标准的+错误输出),所以看起来目前我必须做的唯一方法是通过一个单一的string命令,如:

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

对这样的问题的大多数答案都集中在nodejs(它使用Google的V8 Javascript引擎)或Python等其他语言的本地特性对我不起作用的正则expression式。

我想逃避dangerStr,以便安全地编写像上面那样的execstring。 如果有帮助,dangerStr将包含JSON数据。

有一种写入外部命令的方法: process.createChildProcess ( documentation )用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."); 

这是我使用的:

 var escapeShell = function(cmd) { return '"'+cmd.replace(/(["\s'$`\\])/g,'\\$1')+'"'; }; 

如果你需要简单的解决scheme,可以使用这个:

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

所以你的string将会像Chris Johnsen所说的那样简单地用单引号转义。

 echo 'John'\''s phone'; 

由于强烈的引用 ,它在bash起作用,感觉它也适用于fish ,但在zshsh不起作用。

如果你有bash你可以使用'bash -c \'' + escape('all-the-rest-escaped') + '\''shzsh运行你的脚本。

但实际上… 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('; ')]); 

祝你今天愉快!

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

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

这假设你使用Bash的强引号通过单引号),接收者可以理解JSON的类C转义。

Sylvain的答案的一个变种:

 var escapeShell = function(string) { // Sanitise all space (newlines etc.) to a single space string.replace(/\s+/g, " "); // Optionally remove leading and trailing space string.replace(/^\s+|\s+$/g, " "); // Quote with single quotes, escaping backslashes and single quotes return "'" + string.replace(/(['\\])/g, '\\$1') + "'"; }; 

在不需要用单引号string转义的前提下(正如Alex指出的那样),而其他引用types也不需要。