74 votes

systemd - Donner à mon service des arguments multiples

Est-il possible de donner à mon service systemd plus d'un argument ?

Je voudrais exécuter un programme avec plusieurs arguments qui doivent être décidés par l'utilisateur final.

Par exemple ./program arg1 arg2

Pour lancer une application à argument unique, il faudrait quelque chose comme systemctl start arg1@program Dans la définition du service, j'ai ExecStart = /usr/bin/program i .

Gracias.

1 votes

On dirait que ce que vous voulez, c'est un fichier de configuration.

0 votes

J'ai besoin de le modifier en cours de route. Ai-je strictement besoin d'un fichier conf ?

0 votes

@peperunas vous n'avez pas besoin d'un fichier conf, voir ma réponse qui fonctionne sans aucun fichier supplémentaire.

62voto

DarkSheep Points 183

Si, vous le pouvez ! Définissez-les dans un fichier quelque part et ajoutez-les à EnvironmentFile dans votre service systemd. Par exemple, disons que le contenu de /etc/.progconf est :

ARG1=-o
ARG2=--verbose

Et votre fichier .service :

EnvironmentFile=/etc/.progconf
ExecStart = /usr/bin/prog $ARG1 $ARG2

Vous pouvez écrire dans ce fichier si vous avez besoin de les modifier en cours de route. Un service ne devrait pas changer ses options très souvent, envisagez peut-être un démarrage automatique ou un cron si vous avez besoin d'y parvenir.

Pour d'autres exemples, consultez le site : https://wiki.archlinux.org/index.php/Systemd/Services

0 votes

Heh, très pratique, je n'y ai pas pensé. Mais je suis d'accord : Les paramètres des services ne changent pas régulièrement, et leurs fichiers de configuration non plus.

0 votes

Si le fichier de service utilise des variables d'environnement, pouvez-vous dire VAR1=... VAR2=... systemctl start foobar.service pour passer les variables ?

0 votes

Oui, je crois que vous pouvez

41voto

nonagon Points 463

Je voulais faire la même chose, mais sans un fichier séparé pour chaque combinaison d'arguments. J'ai découvert que je pouvais passer un seul long argument avec des espaces, puis utiliser la fonction de division d'espace de la variable d'environnement de systemd pour séparer les arguments.

J'ai créé un service avec un nom de fichier argtest@.service ( notez le signe "at" à la fin, qui est requis lorsqu'un service prend des arguments. ).

[Unit]
Description=Test passing multiple arguments

[Service]
Environment="SCRIPT_ARGS=%I"
ExecStart=/tmp/test.py $SCRIPT_ARGS

Je l'exécute avec sudo systemctl start argtest@"arg1 arg2 arg3".service et il passe arg1 , arg2 y arg3 en tant qu'arguments de ligne de commande séparés pour test.py.

0 votes

"Notez la dernière esperluette" : Je ne trouve pas d'esperluette dans votre réponse. Pouvez-vous modifier votre réponse pour être plus clair sur ce point ?

0 votes

Oui, désolé pour ça !

0 votes

Je pense que le @ n'est nécessaire que lorsque vous utilisez le %I comme vous le faites. C'est une instance du service.

5voto

Geraldo Nascimento Points 1228

Le plus simple que j'ai trouvé est :

ExecStart=/bin/bash -c "\"/path/with spaces/to/app\" arg1 arg2 arg3 \"arg with space\""

Ça permet de garder tout ça sous contrôle.

Cela dit, j'ai constaté qu'au moins sur Ubuntu 18.04 LTS, je n'ai même pas besoin de faire cela, je peux faire ceci et cela fonctionne bien :

ExecStart="/path/with spaces/to/app" arg1 arg2 arg3 "arg with space"

$vars fonctionnent également comme des arguments avec ce modèle.

2voto

smac89 Points 190

Indiquez à vos utilisateurs qu'ils peuvent remplacer le service en créant un snippet de dépôt grâce à l'utilisation de la fonction edit option dans systemctl .

Tout d'abord, commencez par des valeurs par défaut raisonnables. Supposons que le ExecStart une partie de votre service déclare ce qui suit :

[Service]
ExecStart=./program arg1

Maintenant, tout utilisateur de ce service peut décider d'utiliser un ensemble différent d'arguments pour exécuter le programme. Il peut le faire en créant un snippet drop-in avec :

systemctl edit myservice.service

Dans le nouveau fichier, ils écrivent simplement ce qui suit pour remplacer l'option ExecStart :

[Service]
ExecStart=
ExecStart=./program arg1 arg2

L'avantage de cette méthode est que le résultat final n'implique pas la modification du service installé sur le système, ce qui peut entrer en conflit avec certains gestionnaires de paquets.

Et c'est tout !

Maintenant, il suffit de recharger systemd ( systemctl daemon-reload ) et redémarrer le service ( systemctl restart myservice.service ).

Lorsque le service redémarre, il charge toujours aussi les modifications de l'utilisateur.

J'espère que cela vous aidera.


Sources :

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X