2017-09-16 7 views
0

je voudrais exécuter la commande suivante à l'aide Spawn nodejs sur un système Debian: /usr/bin/apt-get upgrade -s | tail -1 | cut -f1 -d' ' Je veux utiliser spawn et non exec à cause de l'utilisation future de racine uniquement les commandes et Je ne veux pas permettre un accès shell complet (je vais mettre à jour le fichier visudo avec des commandes correctes) Voici mon codeSpawn dans nodejs pour une commande unix avec des espaces dans les paramètres

const apt = spawn('/usr/bin/apt-get', ['upgrade', '-s']); 
    const tail = spawn('tail', ['-1']); 
    const cut = spawn('cut', ['-f1', '-d" "']); 

    apt.stdout.on('data', (data) => { 
    tail.stdin.write(data); 
    }); 

    tail.stdout.on('data', (data) => { 
    cut.stdin.write(data); 
    }); 

    cut.stdout.on('data', (data) => { 
    console.log(data.toString()); 
    }); 


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

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

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

    apt.on('close', (code) => { 
    if (code !== 0) { 
     console.log("apt process exited with code ${code}"); 
    } 
    }); 

    tail.on('close', (code) => { 
    if (code !== 0) { 
     console.log("tail process exited with code ${code}"); 
    } 
    }); 

    cut.on('close', (code) => { 
    if (code !== 0) { 
     console.log("cut process exited with code ${code}"); 
    } 
    }); 

    res.status(200).json(''); 

une fois exécuté j'ai une erreur à cause du paramètre « -d » « » ce n'est pas reconnu. J'essaie fuyais l'espace avec un double \ ou diviser le paramètre dans les deux, mais encore des erreurs

Répondre

1

Il devrait juste être:

const cut = spawn('cut', ['-f1', '-d ']); 

Pas des guillemets doubles ou antislash échappe - ceux qui sont à l'usage de la coquille, pas cut, et il n'y a pas de coquille ici. Cela rend la manipulation de noms de fichiers inconnus (pour vos prochains cas d'utilisation) particulièrement facile: lorsque vos chaînes sont passées en arguments (pour un logiciel qui ne les utilise pas, mon code eval -equivalent plus tard), vous n'avez pas besoin pour citer, échapper, assainir, ou autrement les modifier avant qu'ils puissent être passés en tant que données.

(c'est-à-dire - quand vous dites à votre shell cut -f1 -d" ", la syscall réelle qu'il invoque pour commencer ce processus cut, dans la syntaxe C, ressemble execve("/usr/bin/cut", {"cut", "-f1", "-d ", NULL}, environ), les citations étaient syntaxiques, consommés par la coquille quand il les a utilisés pour prendre la décision que l'espace après le -d devrait faire partie du même argument littéral).

+0

Merci Charles! Cela a fonctionné et j'ai aussi compris pourquoi ;-) J'ai manqué le shell besoin Un autre point: cela signifie que pour une commande comme '/ bin/grep -P '^ \ d + upgraded''i devrait l'écrire comme' spawn ('grep', ['-P', '"^ \\ d +', 'mis à jour"']) '? –

+1

''^ \ d + upgraded'' est analysé par le shell en une seule chaîne (c'est l'un des effets des guillemets simples syntaxiques), donc ce serait' spawn (' grep ', [' -P ','^\\ d + mis à jour ']) 'pour écrire cette même chaîne unique en JavaScript. –

+0

Pour commencer, comprendre comment cela fonctionne sur le shell peut être http://mywiki.wooledge.org/Quotes ou http://wiki.bash-hackers.org/syntax/quoting, et http: // mywiki.wooledge.org/BashParser –