Aller au contenu

Exécution du script Shell


Messages recommandés

Bonjour à tous,

Pour commencer, je suis débutant ! Merci de le prendre en considération.

Je doit créer un script qui sera exécuté automatiquement par le serveur dans le dossier /etc/init/le_script.sh
Son objectif, lancer le serveur nodeJS au démarrage/redémarrage du nas et également, vérifier si le serveur nodeJS n'a pas planté sinon, le script relance nodeJS. Cette vérification devra être faite toute les 60 sec.
Donc, j'ai lu plusieurs topic et tuto sur le langage Shell.
J'ai également découvert qu'il y a plusieurs versions et chacune hérite de la plupart des fonctionnalités de son ancêtre (voir image ci-dessous).

version-shell.png.0be655631c4d35934edee2

  • sh : Bourne Shell. L'ancêtre de tous les shells.
  • bash : Bourne Again Shell. Une amélioration du Bourne Shell, disponible par défaut sous Linux et Mac OS X.
  • ksh : Korn Shell. Un shell puissant assez présent sur les Unix propriétaires, mais aussi disponible en version libre, compatible avec bash.
  • csh : C Shell. Un shell utilisant une syntaxe proche du langage C.
  • tcsh : Tenex C Shell. Amélioration du C Shell.
  • zsh : Z Shell. Shell assez récent reprenant les meilleures idées de bash, ksh et tcsh.

J'exécute la commande suivante pour voir ma version : 

nas> echo $SHELL
/bin/ash

Donc ma version est la plus basic "sh".

Par la suite, je crée un fichier pour un test dans le dossier /etc/init/essai.sh

#!/bin/ash

# List folder web
ls -l /volume1/web/

Je rend le script exécutable :

nas> cd /etc/init/
nas> chmod +x essai.sh
nas> chmod 0755 essai.sh
nas> ls -l essai.sh
-rwxr-xr-x    1 root     root     71 Jan  1 16:12 essai.sh

Par la suite, je modifierais le PATH pour y adjoindre mon dossier avec mes scripts :

export PATH=$PATH:/home/steph/mes_scripts

J’exécute le script dans le répertoire courant et cela ne fonctionne pas  :

nas> ./essai.sh
-ash: ./essai.sh: not found

Si j'ai mis autant de détails c'est que j'ai plusieurs questions :

Pourquoi le script essai.sh n'a pas fonctionné ?

Je sais qu'il est possible d'installer un nouveau shell en tapant ceci :

apt-get install ksh

Mais je n'ai pas testé. Question : si j’exécute cette commande, le support Synology sera toujours fonctionnel ?

Par la suite, j'ai testé cette commande pour vérifier si je peux changé de Shell :

nas> chsh
-ash: chsh: not found

Pourquoi la commande chsh n'a pas fonctionné ?

Merci d'avance pour tous ceux qui voudront bien m'aider :smile:

Lien vers le commentaire
Partager sur d’autres sites

En pratique c'est la busybox qui te répond.

Ton problème peut venir de plusieurs choses, l'erreur la plus courante c'est de créer son script sous Windows (il ajoute des caractères de contrôle afin d'être moins compatible avec le reste du monde mais de le rester avec DOS). Si tu es sous Windows, tu peux utiliser notepad++ en spécifiant bien le format d'encodage (UTF-8 sans BOM)

Sinon vi ça marche très bien (surtout pour un script qui devrait faire moins de 10 lignes à la fin)

Pour le reste, ça marche très bien
 

nas> cd /tmp
nas> vi test.sh
...
nas> cat test.sh
#!/bin/ash

echo `pwd`
date
exit 0


nas> ./test.sh
/tmp
Fri Jan  1 20:48:10 CET 2016
Il y a 3 heures, StephWe a dit :

export PATH=$PATH:/home/steph/mes_scripts

export c'est du bash

Il y a 3 heures, StephWe a dit :

apt-get install ksh

ça ne marchera pas, ce n'est pas une debian, si tu veux installer des paquets, le plus simple est d'utiliser ça : https://synocommunity.com/packages

ps : bonne année

Lien vers le commentaire
Partager sur d’autres sites

Il y a 18 heures, StephWe a dit :

Par la suite, je crée un fichier pour un test dans le dossier /etc/init/essai.sh


#!/bin/ash

# List folder web
ls -l /volume1/web/

Je rend le script exécutable :


nas> cd /etc/init/
nas> chmod +x essai.sh
nas> chmod 0755 essai.sh
nas> ls -l essai.sh
-rwxr-xr-x    1 root     root     71 Jan  1 16:12 essai.sh

Tout d'abord, si tu veux vraiment que ton script soit lancé à chaque démarrage de ton NAS et qu'il se soit pas supprimé à chauqe upgrade du NAS, il vaut mieux le mettre dans le répertoire suivant (si ma mémoire est bonne): "/usr/local/etc/rc.d/" et lui donner un nom de la forme "S99Monscript.sh" avec comme structure :

#!/bin/sh
PATH=/home/steph/mes_scripts:/bin:/usr/bin:/usr/syno/bin   # on peu ajouter /sbin,/usr/sbin et /usr/syno/sbin si necessaire

case $1 in
start)
        # faire quelque chose pour le demarrage
        exit 0
        ;;
stop)
        # faire quelque chose pour l'arrêt        
        exit 0
        ;;
restart)
        # faire quelque chose pour le restart
        exit 0
        ;;
*)
        /bin/echo "usage: $0 { start | stop | restart }" >&2
        exit 1
        ;;
esac

Ensuite, il n'est pas forcément nécessaire de modifier le PATH pour y adjoindre ton dossier avec tes scripts, il est préférable d'appeler tes scripts avec le chemin complet plutôt, par exemple si ton script "essai.sh" se trouve dans ton répertoire "/home/steph/mes_scripts", utilise la ligne

/home/steph/mes_scripts/essai.sh

ou encore

cd /home/steph/mes_scripts/
./essai.sh

EDIT: ajout du path dans le début du script suite à la remarque de CoulRaoul ;-)

Modifié par loli71
Lien vers le commentaire
Partager sur d’autres sites

il y a 6 minutes, loli71 a dit :

il n'est pas forcément nécessaire de modifier le PATH pour y adjoindre ton dossier avec tes scripts, il est préférable d'appeler tes scripts avec le chemin complet plutôt,

Pour ma part, je préconise de *toujours* spécifier le PATH *dans* le script, au début, ce qui le ferait ressembler à 

#! /bin/ash 

PATH=/home/steph/mes_scripts:/bin:/usr/bin:/usr/syno/bin   # on peu ajouter /sbin,/usr/sbin et /usr/syno/sbin si necessaire

Dans les cas ou le script est susceptible d'être invoqué dans différents contextes (au boot, manuellement, en cron, etc ...) , on évite ainsi des éventuels effects de bords d'un PATH hérité de l'appellant farfelu, incomplet et/ou remplaçant des commandes système.

Lien vers le commentaire
Partager sur d’autres sites

Ton problème peut venir de plusieurs choses, l'erreur la plus courante c'est de créer son script sous Windows (il ajoute des caractères de contrôle afin d'être moins compatible avec le reste du monde mais de le rester avec DOS). Si tu es sous Windows, tu peux utiliser notepad++ en spécifiant bien le format d'encodage (UTF-8 sans BOM)

Oui, je suis sous Windows mais j'avais bien utilisé Notepad++ et sauver en UTF-8 sans BOM. Dans le passé, un administrateur m'avait parlé que Windows générait sur la première ligne un caractère genre retour à la ligne qui ne plaisait pas à Linux :) Comme tu me l'as conseillé, j'ai utilisé vi pour générer un nouveau fichier et cela à fonctionné du premier coup :) Je peux même le rééditer et sauver avec Notepad++.

Tout d'abord, si tu veux vraiment que ton script soit lancé à chaque démarrage de ton NAS et qu'il se soit pas supprimé à chauqe upgrade du NAS, il vaut mieux le mettre dans le répertoire suivant (si ma mémoire est bonne): "/usr/local/etc/rc.d/" et lui donner un nom de la forme "S99Monscript.sh" avec comme structure :

Super, comme ça je vais dans la bonne direction et cela me fait une base de script pour démarrer :smile:

Pour ma part, je préconise de *toujours* spécifier le PATH *dans* le script, au début

En rapport avec le PATH, si on l'ajoute dans le fichier, c'est uniquement parce-qu'il est possible d'inclure le fichier dans un autre fichier comme en PHP avec :

include 'fichier.php';

J'essai de comprendre l'utilité. Au départ, je croyais qu'il était utile de redéfinir le PATH. Comme ça, en ligne de commande, je ne devait plus retrouver le bon dossier (cd /) et également, si j'étais dans le bon dossier, ne plus taper "./" mais directement le nom du fichier depuis n'importe où dans la racine. Peux-tu m'en dire plus ? :smile:

Modifié par StephWe
Lien vers le commentaire
Partager sur d’autres sites

Le PATH ce n'est ni plus, ni moins que la listes des dossiers dans lesquels le système (ou le shell) va chercher un truc dont on n'a pas précisé l'emplacement => dit autrement, c'est le chemin par défaut.

Par exemple la commande ls est dans /bin

  • si ton PATH inclus /bin, tu peux saisir ls depuis n'importe où, ça fonctionne
  • si ton PATH n'inclus pas /bin, ça ne marchera pas (et en passant tu auras d'autres soucis bien plus graves) car le shell ne saura pas où est cette commande
  • si ton PATH inclus un dossier qui contient une commande nommée ls ET que ce dossier est listé AVANT /bin, alors c'est ta commande qui sera utilisée par défaut

Un include c'est autre chose, ça dit juste : inclus le contenu de ce fichier

Lien vers le commentaire
Partager sur d’autres sites

En effet, je comprend mieux l'importance du PATH. Ce sont les répertoires dans lesquels le shell cherche la commande et la recherche se fait dans l'ordre des répertoires contenus dans la variable PATH. On peut également avoir depuis les sources une version plus récente de la commande dont l'exécutable se trouve dans un autre dossier. Alors il faut utiliser le chemin absolu et l'adjoindre au départ du PATH.

Mais le PATH peut également inclure des répertoires dans les quels se trouve des fichiers à exécuter. Pour par exemple écrire un script qui sera exécuté via d'autres scripts (au boot, manuellement, en cron, etc ...) comme disait CoolRaoul.

C'est génial :smile: merci pour toutes ces précisions.

Lien vers le commentaire
Partager sur d’autres sites

Il y a 4 heures, StephWe a dit :

je suis sous Windows mais j'avais bien utilisé Notepad++ et sauver en UTF-8 sans BOM. Dans le passé, un administrateur m'avait parlé que Windows générait sur la première ligne un caractère genre retour à la ligne qui ne plaisait pas à Linux :) Comme tu me l'as conseillé, j'ai utilisé vi pour générer un nouveau fichier et cela à fonctionné du premier coup :) 

Avec Notepad++ c'est cette option qui gère les saut de lignes:Qw8PZSZ.png

L'encodage c'est autre chose, ça concerne la façon dont sont  enregistrés et interprétés les caractères accentués et autres.

Les sauts de lines, dans le monde Unix, sont constitués d'un simple octet de valeur décimale 10 (Newline). Dans le monde DOS puis Windows on a pris l'habitude d'utiliser une séquence de deux octets, "retour chariot" (Carriage return, valeur 13) suivi de ce même newline.

Quant au "premier caractère" dont tu parle c'est le BOM, qui sert à indiquer à Windows le codage UTF-8.

Citation

Je peux même le rééditer et sauver avec Notepad++.

C'est parce que Notepad++ tient compte du format des marques de fin de ligne quand il lit un fichier et le conserve lors de son enregistrement.

Lien vers le commentaire
Partager sur d’autres sites

Re : Merci CoolRaoul, en effet. Mais je ne savais pas que l'on pouvait pré-configurer les sauts de ligne pour Unix directement dans Notepas++.

J'ai installé le packet nodeJS, et j'ai créé un script avec le contenu suivant pour le serveur nodeJS :

var http = require('http');
http.createServer(function (req, res) {
	res.writeHead(200, {'Content-Type': 'text/plain'});
	res.end('Hello World\n');
}).listen(1337, '192.168.1.250');
console.log('Server running at http://192.168.1.250:1337/');

Via la console, j'ai bien un retour positif : 

nas> node /volume1/web/nodeJS_server-xxx-xxx/server.js
Server running at http://192.168.1.250:1337/

Via le port 1337 (http://192.168.1.250:1337) sur le navigateur j'ai également un retour positif :

Hello World

Jusqu'ici tout vas bien. Pour évité de réinventer la roue, j'ai fait quelques recherche sur un éventuel script pour gérer le lancement de nodeJS et j'ai trouvé ceci https://github.com/chovy/node-startup/blob/master/init.d/node-app

Donc, j'ai créé et copié/collé le contenu dans le fichier /usr/local/etc/rc.d/s0001_manage-nodeJS.sh et également créé les sous-dossiers et fichier /pid et /log/server.log. Il ne faut pas créer le fichier server.pid car il stop le script avec le message d'erreur suivant :

nas> ./s0001_manage-nodeJS.sh start
ps: invalid option -- 'a'
BusyBox v1.16.1 (2015-11-12 18:01:52 CST) multi-call binary.

Usage: ps

Report process status

Options:
        w       Wide output

Node app stopped, but pid file exists

J'ai modifié les variables suivante dans le fichier /usr/local/etc/rc.d/s0001_manage-nodeJS.sh :

#!/bin/sh

USER="root"
NODE_ENV="production"
PORT="1337"
APP_DIR="/volume1/web/nodeJS_server-xxx-xxx"
NODE_APP="server.js"
CONFIG_DIR="$APP_DIR"
PID_DIR="$APP_DIR/pid"
PID_FILE="$PID_DIR/server.pid"
LOG_DIR="$APP_DIR/log"
LOG_FILE="$LOG_DIR/server.log"
NODE_EXEC=$(which node)

###############

J'ai rendu le fichier exécutable :

nas> cd /usr/local/etc/rc.d/
nas> chmod +x s0001_manage-nodeJS.sh
nas> chmod 0755 s0001_manage-nodeJS.sh
nas> ls -l s0001_manage-nodeJS.sh
-rwxr-xr-x    1 root     root      3278 Jan  2 15:54 /usr/local/etc/rc.d/s0001_manage-nodeJS.sh

J'ai lancé le script manuellement pour vérifier si il fonctionne. Voici les erreurs que j'ai en retour :

nas> ./s0001_manage-nodeJS.sh start
Starting node app ...
./s0001_manage-nodeJS.sh: line 170: sudo: not found
cat: can't open '/volume1/web/nodeJS_server-xxx-xxx/pid/server.pid': No such file or directory
Node app started with pid

Pourquoi ne trouve-t-il pas la commande sudo ?

Modifié par StephWe
Lien vers le commentaire
Partager sur d’autres sites

Il y a 2 heures, StephWe a dit :

Pourquoi ne trouve-t-il pas la commande sudo ?

Tout simplement parce qu'elle n'existe pas sous DSM? :neutral:

DSM, bien qu'assez complet, est un Linux limité par endroit. Faut pas compter (et tu l'a déjà vu avec apt-get) que tout ce qui marche sur une distrib complète type Debian, Fedora ou autre fonctionne "out of the box" sur Syno.

Essaie de remplacer

sudo -i -u $USER

par

su - $USER -c /bin/ash

Ca devrait le faire

Citation

Pour évité de réinventer la roue, j'ai fait quelques recherche sur un éventuel script pour gérer le lancement de nodeJS et j'ai trouvé ceci 

Parfois il vaut mieux réinventer la roue, c'est comme ça qu'on apprend et au final on comprend mieux.

 

**EDIT**

Au passage, vu que dans le script USER = "root", aussi bien le "sudo" que le "su" sont parfaitement inutiles ici.

La ligne:

echo "cd $APP_DIR && PORT=$PORT NODE_ENV=$NODE_ENV NODE_CONFIG_DIR=$CONFIG_DIR $NODE_EXEC $APP_DIR/$NODE_APP 1>$LOG_FILE 2>&1 & echo \$! > $PID_FILE" | sudo -i -u $USER

devrait pouvoir être remplacée par les deux lignes ci dessous:

cd $APP_DIR && PORT=$PORT NODE_ENV=$NODE_ENV NODE_CONFIG_DIR=$CONFIG_DIR $NODE_EXEC $APP_DIR/$NODE_APP 1>$LOG_FILE 2>&1 </dev/null& 
echo $! > $PID_FILE

**EDIT #2**

Même ci c'est sans grande importance ici, je constate que l'auteur du script écrit ses messages d'info dans stdout (sortie standard) au lieu de stderr (sortie d'erreur) ce qui est une pratique déconseillée.

La plupart des occurences de "echo" (à l'exception de celui de la fonction "get_pid") devrait être remplacées par "echo >&2"  

Modifié par CoolRaoul
grammaire
Lien vers le commentaire
Partager sur d’autres sites

Citation

Parfois il vaut mieux réinventer la roue, c'est comme ça qu'on apprend et au final on comprend mieux.

Tu as raison, mon expression était mal placé. Elle s'utilise uniquement si l'on maîtrise le sujet (la syntaxe). Mais il y a plusieurs façons d’apprendre. Il est également possible de plonger la tête la première directement dans le code (C'est une expression qui convient le mieux pour ce que je veux expliquer :biggrin:). A chaque fois que je rencontre un soucis inconnu, une définition très complète s'offre à moi avec d'autres choses en parallèles qui n'étaient pas forcement liés et qui m'ouvre l'esprit. De plus, j'ai gagné du temps dans l'optimisation de la syntaxe. La personne qui a développé ce script m'offre une vision plus large pour en créer d'autres :smile:  Si je parle de cette façon, c'est parce-que je suis développeur et j'ai une logique qui me permet de réfléchir de cette façon. Enfin, je crois :mrgreen:.

J'ai fait la modification est cela a fonctionné. Je dois encore y compléter un plantage volontaire du serveur nodeJS et qu'il se relance automatiquement. Merci pour ton aide précieuse.

Citation

L'utilitaire su (pour "switch user" ou "substitute user") permet de prendre l'identité d'un autre utilisateur et su avec son option -c peut également être utilisé pour lancer GUI (graphical user interface) un programme. Par exemple, il peut être utilisé pour démarrer Nautilus (un gestionnaire de fichiers graphique) avec un accès root.

"su" et "sudo" pour obtenir des droits "root".

 

:surprised:

J'avais pas vu ta dernière intervention. Je fais les modif.

Lien vers le commentaire
Partager sur d’autres sites

Re : j'ai un message d'erreur à la ligne 13

nas> node /usr/local/etc/rc.d/s0001_manage-nodeJS.sh start
/usr/local/etc/rc.d/s0001_manage-nodeJS.sh:13
NODE_EXEC=$(which node)
                  ^^^^
SyntaxError: Unexpected identifier
    at exports.runInThisContext (vm.js:73:16)
    at Module._compile (module.js:443:25)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

 

Lien vers le commentaire
Partager sur d’autres sites

Oui, en effet mais l'erreur ne vient pas de là et ni de la modification du script. J'avais redémarrer le serveur et par la suite, le navigateur m'affichait une erreur 404. Alors j'ai lancé manuellement par la console et j'ai fait une erreur :mrgreen:

La vrai erreur est que si le serveur (nas) redémarre, le fichier server.pid pose problème au démarrage du serveur nodeJS. A mon avis, le développeur a ajouté une condition inutile dans le script. J'ai regardé le script de plus prêt et à la ligne 83, la variable $FORCE_OP doit être égale à true alors qu'à la ligne 34, elle est initialisée à false par défaut. J'ai réglé le problème en initialisant la variable à true. Désolé pour le retour négatif :confused:.

 

Modifié par StephWe
Lien vers le commentaire
Partager sur d’autres sites

Dans les commentaires, il annonce ceci :

# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6

Ce que je ne comprend pas, donc, comment sont initialisées les variables $1 et $2 à la ligne 136 et 150
J'imagine qu'à la ligne 33, il y a un genre un array ou object. Peux-tu m'expliquer cette ligne stp :geek: ?

Modifié par StephWe
Lien vers le commentaire
Partager sur d’autres sites

Ces 2 lignes sont liées au LSB

Pas de rapport direct avec le reste du script

Il existe plusieurs variables "spéciales", les plus utiles sont :

  • $0 à ... : les arguments passés à la commande (donc $0 c'est la commande elle même, $1 c'est le premier argument, $2, le deuxième, ...)
  • $? : le code de sortie de la dernière commande
  • $$ : le pid du script lui même
  • $! : le pid de la dernière commande (lancée en tache de fond)
  • il en existe d'autres, moins utilisées : $@ $# $- $_  $*

Par contre, sauf erreur de ma part, tu souhaitais faire script qui surveille l'état du daemon nodsJS, là tu es entrain de faire un script de démarrage et d’arrêt, les mécaniques sont différentes

Lien vers le commentaire
Partager sur d’autres sites

En effet, je devrais peut-être créer un cron vers un autre script qui toutes les 60 sec., vérifie si le serveur nodeJS est lancé.
Et donc, je préserve le script actuel tel qu'il est. Et je le relance dans le cas ou le serveur est hs.

Tu as peut-être une autre idée (plus optimisé ou plus simple) pour créer le script qui surveille l'état du daemon nodeJS ?

Modifié par StephWe
Lien vers le commentaire
Partager sur d’autres sites

Tu peux tout faire un script qui gère le start au boot, le stop lors de l’arrêt et le restart en cron, mais dans ce cas il faut bien l'écrire en factorisant ton code et en utilisant les code d'erreur.

Ton script doit avoir au minimum les fonctions suivantes :

  • START : lancer nodeJS et noter son PID
  • STATUS : vérifier qu'un process avec ce PID existe (donc que nodeJS et lancé)
  • STOP : couper nodeJS en tuant proprement le process (via le PID encore une fois)
  • TEST : tester si un process noeJS existe avec un autre PID
    • s'il existe, vérifier que ce n'est pas un enfant
    • prendre une décision (kill, création du PID ou ne rien faire) en fonction du résultat

Avec ces 4 fonctions, tu peux faire tout ce que tu demandes, par exemple restart sera juste une suite d'appels :

  • STATUS
    • si up => STOP puis START
    • sinon => START

Après à toi d'ajouter tous les tests que tu considère comme nécessaires (écoute sur le bon port, utilisateurs connectés, ...)

Par contre je ne suis pas pour relancer un programme toutes les minutes s'il se plante, car s'il s'est planté, c'est surement pour une bonne raison, donc il faut mettre des limites (par exemple vérifier depuis combien de temps il est planté)

 

Lien vers le commentaire
Partager sur d’autres sites

Oui, en effet. J'ai une seule erreur sur mes testes, c'est quand je vérifie le statut :

nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh status
ps: invalid option -- 'a'
BusyBox v1.16.1 (2015-11-12 18:01:52 CST) multi-call binary.

Usage: ps

Report process status

Options:
        w       Wide output

Cela vient du ps aux :

is_running() {
    PID=$(get_pid)
    ! [ -z "$(ps aux | awk '{print $2}' | grep "^$PID$")" ]
}

Je crois que ps n'est pas utilisé dans cette version du Shell. Tu as une idée ?
Je voudrais également ajouter dans cette vérification, si le port est ouvert.

Lien vers le commentaire
Partager sur d’autres sites

Par contre je ne suis pas pour relancer un programme toutes les minutes s'il se plante, car s'il s'est planté, c'est surement pour une bonne raison, donc il faut mettre des limites (par exemple vérifier depuis combien de temps il est planté)

La seule façon pour le serveur de planter est de ne pas initialiser une variable correctement, une erreur de syntaxe du code js ou (le pire), une lenteur dans l’exécution du script car même si le JavaScript est exécuté en lecture ligne par ligne (procédurale) la ligne 2 peut-être plus lente et la ligne 3 n'attend pas et le bug se produit (variable non initialé ou vide). Si le serveur nodeJS se plante, je le saurais coté client car la connexion au port sera fermé. Je m'enverrais un email directement et les clients auront un message avec un compte à rebours vers la reprise du serveur. Les clients connectés seront sauvés dans la db. Cette une sécurité que je met en place car le javascript est instable. Je sauve les données d'un array avec un json_encode (PHP) coté serveur qui devient un String dans un champ de la table et je recrée les array et object sans problème. Il faut impérativement que le serveur continue à tourner et que je règle le problème en parallèle.

Lien vers le commentaire
Partager sur d’autres sites

Il y a 1 heure, StephWe a dit :

Je crois que ps n'est pas utilisé dans cette version du Shell. Tu as une idée ?

J'ai surtout une question, tes commandes, tu les tests avant de les mettre dans ton script ? :mrgreen:

ps fonctionne très bien, par contre les options peuvent différer d'une version à l'autre, le ps de Mac (un freebsd) n'est le même que celui d'une debian qui est différent de celui d'un AiX qui est différent de celui de la busybox des syno (il existe plusieurs busybox)

Plein de programmes (tous en pratique) ont des différences de syntaxe selon les OS et les versions

C'est aussi pour ça qu'il faut s'appuyer sur les mécanisme standard et portables quand c'est possible (le PID est un exemple, même sous Windows les programmes ont un PID)

Par exemple, plutôt que de lister tous les programmes (ps), puis de faire un filtre dans un autre langage (awk) avant de faire une recherche texte (grep), il est préférable, plus simple et plus fiable d'utiliser la commande standard : pidof

Il y a 2 heures, StephWe a dit :

Je voudrais également ajouter dans cette vérification, si le port est ouvert.

pour savoir si le port est en écoute (ouvert c'est coté firewall) : netstat -h (=> netstat -lntp)

pour savoir s'il y a du monde dessus : netstat -antp

Il y a 1 heure, StephWe a dit :

La seule façon pour le serveur de planter est

j'aime le "la seule façon" suivi de 3 façons :lol: (et il y a en a plein d'autres des façon)

Je te donne un exemple : admettons que nodeJS bouffe une ressource (cpu/ram/io/net/...) à 100% suite à une erreur de code ou a un bug dans le compilateur ou a une attaque ...

  • le kernel va essayer de libérer des ressources (gestion de priorité), mais arrivé à un certain point, certains process vont crasher d'eux même
  • si tu relance nodeJS en boucle, tu risque d'accentuer le problème et pour finir tu ne pourras plus te connecter au nas pour débogguer car il sera trop chargé ou que ssh sera mort
  • si par contre tu limite à 2 ou 3 crash par heure (au hasard), ou que tu mets un mécanisme d'amortissement (tempo, failsafe, ...) tu pourras intervenir
  • l'autre avantage, c'est pour tes utilisateurs, au lieu d'avoir un programme qui crash toutes les 10min ou à chaque clique sur un bouton buggué, ils ont un gentil message d'indisponibilité temporaire, en terme d'image c'est mieux et ça te laisse du temps pour regarder le problème en détails

Sur certains serveurs que je gère, quand un crash ou un problème sérieux est détecté et persite suite à un restart du programme, les serveurs basculent automatiquement dans un mode maintenance, j'ai créé 4 templates :

  • le mode rien à foutre : page d'erreur générique
  • le mode de base : un message plus formelle indiquant qu'un problème est survenu blablabla
  • le mode debug (pour les appli qui ont peu d'utilisateurs) : un petit formulaire leur permettant d'indiquer ce qu'ils faisaient au moment du crash
  • le mode business critical : on propose aux utilisateurs d'être prévenus (sms, mail, ...) dès que l'appli refonctionne

(note à moi même : il faudrait que je fasse ça au taf aussi :rolleyes:)

Lien vers le commentaire
Partager sur d’autres sites

Salut :smile:, pour vérifié le statut, voici ce que j'ai fait en utilisant les commandes pitof et netstat :

is_running() {
    PID=$(get_pid)
	[ -z "$(pidof node | awk '{print $2}' | grep "^$PID$" && netstat -an | egrep ".*:1337" | awk '{print $2}' | grep "^$PID$")" ]
}

Donc, lancé manuellement via la console cela donne :

nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh stop
Stopping node app ...
Killing process 17292
Removing pid file
Node app stopped
nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh status
Node app stopped
nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh start
Starting node app ...
Node app started with pid 17391
nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh status
Node app running with pid 17391

Penses-tu que la fonction is_running peut être optimisé ou c'est bon comme cela ?

Également, pour les testes. J'ai lancé le daemon nodsJS manuellement et si je quitte la console, le serveur nodeJS ne fonctionne plus. Sais-tu comment faire pour lancer le daemon nodsJS manuellement et quitté la console sans que le serveur nodeJS soit hors-service ? Je voudrais une solution pour éviter de redémarrer le nas :mrgreen:.

Citation

Je te donne un exemple : admettons que nodeJS bouffe une ressource (cpu/ram/io/net/...) à 100% suite à une erreur de code ou a un bug dans le compilateur ou a une attaque ...

Vu comme ça, en effet :confused:. Sur un premier temps, je relance le serveur comme prévu. Comme ça, cela me permet de créer mon premier cron :geek: Par la suite, une fois que j'ai créé l'appli web, je ferais comme tu m'as dit car évidement, je ne voudrais pas me retrouver dans une des situations que tu as cités.

Lien vers le commentaire
Partager sur d’autres sites

Il y a 3 heures, StephWe a dit :

Penses-tu que la fonction is_running peut être optimisé ou c'est bon comme cela ?

c'est surtout que ton test est faux, si le process est lancé, même sans écouter il sera à TRUE

pour le netstat, pourquoi faire -an, il n'y a que le TCP (-t) en écoute (-l) qui t’intéresse, là tu liste tout

Il y a 3 heures, StephWe a dit :

Également, pour les testes. J'ai lancé le daemon nodsJS manuellement et si je quitte la console, le serveur nodeJS ne fonctionne plus. Sais-tu comment faire pour lancer le daemon nodsJS manuellement et quitté la console sans que le serveur nodeJS soit hors-service ?

SIGHUP et trap (je te laisse chercher)

sinon lance le avec le planificateur de tache de DSM

Lien vers le commentaire
Partager sur d’autres sites

J'ai été obligé de garder "-an" car "-l" prend trop de temps à charger dans la fonction is_running et le retour n'est jamais correct. 
Donc, j'ai réécrit la commande netstat et j'affiche uniquement le String (6ème colonne) si le résultat est égal à 'LISTEN' et si le port 1337 est ouvert dans la liste :

nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh stop
Stopping node app ...
Killing process 11291
Removing pid file
Node app stopped
nas> netstat -an | egrep ".*:1337" | awk -F' ' '{print $6}' | grep "^LISTEN$"
nas> /usr/local/etc/rc.d/s0001_manage-nodeJS.sh start
Starting node app ...
Node app started with pid 12763
nas> netstat -an | egrep ".*:1337" | awk -F' ' '{print $6}' | grep "^LISTEN$"
LISTEN
nas>

J'ai également réécrit la commande pidof et j'affiche uniquement le pid si il est égale au pid demandé dans le grep :

nas> pidof node
12763
nas> pidof node | grep "12763"
12763

Donc, dans la fonction is_running (je n'ai pas oublié le not "!" au départ de la condition ) : Quand penses-tu ?

is_running() {
    PID=$(get_pid)
    ! [ -z "$(pidof node | grep "^$PID$" && netstat -an | egrep ".*:1337" | awk -F' ' '{print $6}' | grep "^LISTEN$")" ]
}
Citation

SIGHUP et trap (je te laisse chercher)

J'ai rien trouvé qui pouvait me mettre sur la piste. Tu peux m'en dire plus ? 

Lien vers le commentaire
Partager sur d’autres sites

Rejoindre la conversation

Vous pouvez publier maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous maintenant pour publier avec votre compte.

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer.