どのように私は、ノード内のシェルコマンドの文字列をエスケープするのですか?
-
21-09-2019 - |
質問
は nodejs には、外部コマンドを実行する唯一の方法は、sys.exec(CMD)を介して行われます。私は、外部コマンドを呼び出すと、標準入力を経由してそれにデータを提供したいと思います。それは私が今これを行うために持っている唯一の方法がある表示されますので、nodejsではまだ、そこに(のみのexecにし、その標準+エラー出力を受信)コマンドを開き、そこにデータをプッシュするための方法であることが表示されません。
:単一の文字列コマンドなどを経由してvar dangerStr = "bad stuff here";
sys.exec("echo '" + dangerStr + "' | somecommand");
このような質問への回答のほとんどは、Pythonのような他の言語からnodejs(GoogleのV8 JavaScriptエンジンを使用する)またはネイティブの機能で私のために仕事をしないか、正規表現に焦点を当ててきます。
私はそれが上記のような幹部の文字列を構成しても安全だようdangerStrを脱出したいと思います。それが助け場合は、dangerStrは、JSONデータが含まれています。
解決
process.createChildProcess
を(ドキュメントを)返します。あり、外部コマンドに記述する方法でありますwrite
メソッドを持つオブジェクト。あなたはチャンクで出力を読み取るためにイベントハンドラが必要になりますので、それは、stdoutとstderrをバッファリングしていないためcreateChildProcess
は、便利であるかのようではありません。
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')+'"';
};
あなたは簡単な解決策が必要な場合は、これを使用することができます:
function escapeShellArg (arg) {
return `'${arg.replace(/'/g, `'\\''`)}'`;
}
クリス・ヨンセンが述べたように、あなたの文字列は、単純に単一引用符をエスケープされますので。
echo 'John'\''s phone';
それが原因で強い引用するのbash
で動作し、また、そのように感じていますfish
で動作しますが、zsh
とsh
で仕事をしません。
あなたはbash
持っている場合は、あなたのsh
とzsh
か'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}
または何らかのエラーます。
コマンドの束を実行する方法の簡単なソリューションにより、は、次のとおりです。
require('child_process')
.spawn('sh', ['-c', [
'cd all/your/commands',
'ls here',
'echo "and even" > more'
].join('; ')]);
良い一日を!
あなたの のことはありませんのシェルパラメータに行き、未知の入力をエスケープするに頼る必要がありますを - 。ほとんど常に、ユーザーがサーバー上で任意のコードを実行することを可能にすることを考えていないこと
いくつかのエッジケースがあるでしょうノードは、コマンドを呼び出し、必要としない無エスケープして、個別に各引数を渡すをサポートしています。これはそれを行うための最も安全な方法です。
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}`);
});
ドキュメントがあるここを
あなたも、あなたがこのようにそれを行うことができます特殊文字(改行など)に対処する必要がある場合:
str = JSON.stringify(str)
.replace(/^"|"$/g,'') //remove JSON-string double quotes
.replace(/'/g, '\'"\'"\'') //escape single quotes the ugly bash way
これは、あなたがバッシュの強いクォートを経由して、単一の使用を前提としてい-quotes)と受信機は、JSONのCのようなエスケープを理解することができます。の