如何在节点中为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
,但在zsh
和sh
不起作用。
如果你有bash
你可以使用'bash -c \'' + escape('all-the-rest-escaped') + '\''
在sh
或zsh
运行你的脚本。
但实际上… 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也不需要。