La facilité avec laquelle un langage de programmation s'utilise dépend en grande partie de sa capacité à développer des programmes en ligne de commande.

Comme l'un des outils de développement les plus populaires aujourd'hui, savoir utiliser Node.js pour développer des programmes en ligne de commande est une compétence que les développeurs web devraient maîtriser.

Node.js 命令行程序开发教程

Récemment, le blog Npm a publié une série d'articlesqui, je pense, sont très bien écrits. Ci-dessous se trouve un tutoriel que j'ai développé à partir de ceux-ci ; il devrait s'agir de la meilleure solution disponible actuellement.

1. Scripts exécutables

Commençons par le cas le plus simple.

Tout d'abord, écrivez un script exécutable appelé hello en JavaScript.

#!/usr/bin/env node
console.log('hello world');

Ensuite, modifiez les permissions de hello.

$ chmod 755 hello

Maintenant, hello peut être exécuté.

$ ./hello
hello world

Si vous voulez supprimer le préfixe de chemin avant hello, vous pouvez ajouter le chemin de hello à la variable d'environnement PATH. Cependant, une meilleure approche consiste à créer un package.json dans le répertoire courant avec le contenu suivant.

{
  "name": "hello",
  "bin": {
    "hello": "hello"
  }
}

Ensuite, exécutez la commande npm link.

$ npm link

Maintenant, lorsque vous exécutez hello à nouveau, vous n'avez pas besoin de saisir le chemin.

$ hello
hello world

2. Syntaxe de base des arguments de ligne de commande

Les arguments de ligne de commande peuvent être obtenus à l'aide de la variable système process.argv.

#!/usr/bin/env node
console.log('hello ', process.argv[2]);

Lors de l'exécution, ajoutez simplement les arguments directement après le fichier de script.

$ ./hello tom
hello tom

3. Création de processus

Les scripts peuvent créer des processus enfants via le module child_process pour exécuter des commandes système Unix.

#!/usr/bin/env node
var name = process.argv[2];
var exec = require('child_process').exec;

var child = exec('echo hello ' + name, function(err, stdout, stderr) {
  if (err) throw err;
  console.log(stdout);
});

L'utilisation est la suivante.

$ ./hello tom
hello tom

4. Le module shelljs

shelljsCe module réencapsule child_process, ce qui rend plus pratique l'appel des commandes système. Il doit être installé avant utilisation.

npm install --save shelljs

Ensuite, réécrivez le script.

#!/usr/bin/env node
var name = process.argv[2];
var shell = require("shelljs");

shell.exec("echo hello " + name);

Le code ci-dessus utilise le mode local de shelljs, qui exécute des commandes shell via la méthode exec. Il existe également un mode global qui permet d'écrire directement des commandes shell dans le script.

require('shelljs/global');

if (!which('git')) {
  echo('Sorry, this script requires git');
  exit(1);
}

mkdir('-p', 'out/Release');
cp('-R', 'stuff/*', 'out/Release');

cd('lib');
ls('*.js').forEach(function(file) {
  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
  sed('-i', /.*REMOVE_THIS_LINE.*/n/, '', file);
  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*/n/, cat('macro.js'), file);
});
cd('..');

if (exec('git commit -am "Auto-commit"').code !== 0) {
  echo('Error: Git commit failed');
  exit(1);
}

5. Le module yargs

shelljs ne résout que la façon d'appeler des commandes shell, tandis que le module yargs traite la façon de gérer les arguments de ligne de commande. Il doit également être installé.

$ npm install --save yargs

Le module yargs fournit un objet argv pour lire les arguments de ligne de commande. Veuillez consulter le hello réécrit.

#!/usr/bin/env node
var argv = require('yargs').argv;

console.log('hello ', argv.name);

Lors de son utilisation, l'une ou l'autre des deux utilisations suivantes fonctionne.

$ hello --name=tom
hello tom

$ hello --name tom
hello tom

Si vous remplacez argv.name par argv.n, vous pouvez utiliser la forme courte d'un paramètre à une lettre.

$ hello -n tom
hello tom

Vous pouvez utiliser la méthode alias pour spécifier que name est un alias de n.

#!/usr/bin/env node
var argv = require('yargs')
  .alias('n', 'name')
  .argv;

console.log('hello ', argv.n);

De cette façon, les paramètres courts et longs peuvent tous deux être utilisés.

$ hello -n tom
hello tom
$ hello --name tom
hello tom

L'objet argv possède une propriété underscore (_) qui récupère les arguments qui ne commencent pas par un tiret.

#!/usr/bin/env node
var argv = require('yargs').argv;

console.log('hello ', argv.n);
console.log(argv._);

L'utilisation est la suivante.

$ hello A -n tom B C
hello  tom
[ 'A', 'B', 'C' ]

6. Configuration des arguments de ligne de commande

Le module yargs fournit également 3 méthodes pour configurer les arguments de ligne de commande.

  • demand : s'il est obligatoire
  • default : valeur par défaut
  • describe : indication
#!/usr/bin/env node
var argv = require('yargs')
  .demand(['n'])
  .default({n: 'tom'})
  .describe({n: 'your name'})
  .argv;

console.log('hello ', argv.n);

Le code ci-dessus spécifie que le paramètre n ne peut pas être omis, a une valeur par défaut de tom et fournit une ligne de description.

La méthode options permet d'écrire toutes ces configurations dans un seul objet.

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .argv;

console.log('hello ', argv.n);

Parfois, certains paramètres n'ont pas besoin de valeur et agissent uniquement comme des commutateurs. Dans ce cas, vous pouvez utiliser la méthode boolean pour spécifier que ces paramètres renvoient des valeurs booléennes.

#!/usr/bin/env node
var argv = require('yargs')
  .boolean(['n'])
  .argv;

console.log('hello ', argv.n);

Dans le code ci-dessus, le paramètre n renvoie toujours une valeur booléenne. L'utilisation est la suivante.

$ hello
hello  false
$ hello -n
hello  true
$ hello -n tom
hello  true

La méthode boolean peut également être écrite comme une propriété dans l'objet options.

#!/usr/bin/env node
var argv = require('yargs')
  .option('n', {
    boolean: true
  })
  .argv;

console.log('hello ', argv.n);

7. Informations d'aide

Le module yargs fournit les méthodes suivantes pour générer des informations d'aide.

  • usage: format d'utilisation
  • example: fournit des exemples
  • help: affiche les informations d'aide
  • epilog: apparaît à la fin des informations d'aide
#!/usr/bin/env node
var argv = require('yargs')
  .option('f', {
    alias : 'name',
    demand: true,
    default: 'tom',
    describe: 'your name',
    type: 'string'
  })
  .usage('Usage: hello [options]')
  .example('hello -n tom', 'say hello to Tom')
  .help('h')
  .alias('h', 'help')
  .epilog('copyright 2015')
  .argv;

console.log('hello ', argv.n);

Le résultat de l'exécution est le suivant.

$ hello -h

Usage: hello [options]

Options:
  -f, --name  your name [string] [required] [default: "tom"]
  -h, --help  Show help [boolean]

Examples:
  hello -n tom  say hello to Tom

copyright 2015

8. Sous-commandes

Le module yargs permet également de définir des sous-commandes de style Git via la méthode command.

#!/usr/bin/env node
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {
    console.log("Good Morning");
  })
  .command("evening", "good evening", function (yargs) {
    console.log("Good Evening");
  })
  .argv;

console.log('hello ', argv.n);

L'utilisation est la suivante.

$ hello morning -n tom
Good Morning
hello tom

Vous pouvez combiner cette fonctionnalité avec le module shellojs.

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {
    echo("Good Morning");
  })
  .command("evening", "good evening", function (yargs) {
    echo("Good Evening");
  })
  .argv;

console.log('hello ', argv.n);

Chaque sous-commande a souvent ses propres arguments, vous devez donc les spécifier séparément dans la fonction de rappel. Dans la fonction de rappel, vous devez d'abord utiliser la méthode reset pour réinitialiser l'objet yargs.

#!/usr/bin/env node
require('shelljs/global');
var argv = require('yargs')
  .command("morning", "good morning", function (yargs) {  
    echo("Good Morning");
    var argv = yargs.reset()
      .option("m", {
        alias: "message",
        description: "provide any sentence"
      })
      .help("h")
      .alias("h", "help")
      .argv;

    echo(argv.m);
  })
  .argv;

L'utilisation est la suivante.

$ hello morning -m "Are you hungry?"
Good Morning
Are you hungry?

9. Divers

(1) Valeur de retour

Selon la tradition Unix, un programme renvoie 0 en cas de succès, sinon il renvoie 1.

if (err) {
  process.exit(1);
} else {
  process.exit(0);
}

(2) Redirection

Unix permet aux programmes de rediriger des données à l'aide de tubes.

$ ps aux | grep 'node'

Les scripts peuvent obtenir les données redirigées en écoutant l'événement data sur l'entrée standard.

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data) {
  process.stdout.write(data);
});

Voici comment l'utiliser :

$ echo 'foo' | ./hello
hello foo

(3) Signaux système

Le système d'exploitation peut envoyer des signaux aux processus en cours d'exécution, et l'objet process peut écouter les événements de signal.

process.on('SIGINT', function () {
  console.log('Got a SIGINT');
  process.exit(0);
});

La méthode pour envoyer des signaux est la suivante.

$ kill -s SIGINT [process_id]

Article original : http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html