سؤال

في Nodejs, ، الطريقة الوحيدة لتنفيذ الأوامر الخارجية هي عبر sys.exec (CMD). أرغب في الاتصال بأمر خارجي وإعطائه بيانات عبر stdin. في Nodejs ، لا يبدو أن هناك وسيلة لفتح أمر ثم دفع البيانات إليه (فقط إلى Exec وتلقي مخرجات الخطأ المعيارية+) ، لذلك يبدو أن الطريقة الوحيدة التي يجب علي القيام بها الآن هي عبر أمر سلسلة واحدة مثل:

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

ركزت معظم الإجابات على أسئلة كهذه على إما Regex والتي لا تعمل بالنسبة لي في NodeJS (التي تستخدم محرك Google V8 JavaScript) أو ميزات أصلية من لغات أخرى مثل Python.

أرغب في الهروب من Dancerstr بحيث يكون من الآمن تكوين سلسلة exec مثل تلك أعلاه. إذا كان ذلك يساعد ، فسوف يحتوي Dancerstr على بيانات JSON.

هل كانت مفيدة؟

المحلول

هناك طريقة للكتابة إلى أمر خارجي: 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.");

نصائح أخرى

هذا ما أستخدمه:

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}

أو بعض الخطأ.

ألق نظرة على 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('; ')]);

أتمنى لك نهارا سعيد!

أنت ينبغي مطلقا الاعتماد على الهروب من المدخلات غير المعروفة الذهاب إلى معلمة shell - سيكون هناك دائمًا بعض الحالات التي لم تفكر فيها والتي تتيح للمستخدم تنفيذ التعليمات البرمجية التعسفية على الخادم الخاص بك.

تمتلك العقدة دعمًا لاستدعاء الأمر وتمرير كل وسيطة بشكل منفصل ، دون الحاجة إلى الهروب. هذه هي الطريقة الأكثر أمانًا للقيام بذلك:

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 CHAPE CHAPER.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top