Comment envoyer toutes les sorties à `logger` dans le shell POSIX?
10
Je voudrais enregistrer la sortie standard et l'erreur standard séparément lors de l' .xprofileutilisation logger. Dans Bash, je pense que cela ressemblerait à ceci:
Il n'y a pas d'équivalent POSIX. Vous pouvez uniquement effectuer une redirection avec exec, pas un fork. Une pipe nécessite une fourchette et la coque attend que l'enfant ait fini.
Une solution consiste à mettre tout votre code dans une fonction.
(Cela enregistre également toute erreur de l'instance stdout de l'enregistreur vers l'instance stderr. Vous pouvez éviter cela en mélangeant davantage les descripteurs de fichiers.)
Si vous souhaitez que le shell parent se termine même si les loggerprocessus sont toujours en cours d'exécution, placez-les &à la fin des loggerinvocations.
Cela apparaîtra dans syslog sous la forme de deux entrées (out & err) pour l'ensemble du script. L'exemple de la question aura une (ou deux) entrée par commande.
DarkHeart
@DarkHeart Je ne comprends pas votre commentaire. Le code dans la question et les deux solutions que je propose exécutent le même nombre d'instances loggeret transmettent la même entrée à chacune d'elles.
... qui fait à peu près la même chose, sauf qu'il permet mktempde sélectionner le nom de fichier pour vous. Cela fonctionne parce que la substitution de processus n'est en aucun cas magique et fonctionne de manière très similaire à la substitution de commandes . Au lieu de remplacer l'expansion avec la valeur de la commande exécuter en son sein comme une substitution de commande fait, la substitution de processus remplace par le nom d'un lien de système de fichiers où la sortie se trouve.
Bien que le shell POSIX ne fournisse pas de corollaire direct à une telle chose, l'émuler se fait très simplement. Tout ce que vous avez à faire est de créer un fichier, d'imprimer son nom dans la norme à partir d'une substitution de commande et, en arrière-plan, d'exécuter votre commande qui sortira dans ce fichier. Maintenant, vous pouvez simplement rediriger vers la valeur de cette expansion - exactement comme vous le faites avec la substitution de processus. Et donc le shell POSIX fournit tous les outils dont vous avez besoin bien sûr - tout ce qui est requis est que vous les utilisiez d'une manière qui vous convient.
Les deux versions ci-dessus garantissent qu'elles détruisent le lien du système de fichiers vers les canaux qu'elles créent / utilisent avant de les utiliser. Cela signifie qu'aucun nettoyage n'est requis après coup, et, plus important encore, leurs flux ne sont disponibles que pour les processus qui les ouvrent initialement - et donc leurs liens de système de fichiers ne peuvent pas être utilisés comme un moyen pour espionner / détourner votre activité de journalisation. Laisser leurs liens fs dans le système de fichiers est une faille de sécurité potentielle.
Une autre façon est de l'envelopper. Cela peut être fait à partir du script.
Cela permettrait essentiellement à votre script de s'appeler s'il ne l'a pas encore fait et de vous obtenir un répertoire de travail dans temp pour démarrer.
@ l0b0 - Je suis sur le point de mettre à jour un autre type de ce genre ... C'est un objectif plus général, et j'ai finalement réussi à lui donner la possibilité de gérer certaines options liées aux descripteurs / fichiers d' E / S.
mikeserv
@ l0b0 - si vous vouliez utiliser mktempet d' autres commandes non standard, il pourrait être: _log()( p=; mkfifo "${p:=$(mktemp -u)}"; printf %s "$p"; exec <&- >&- <>/dev/null >&0; { rm "$p"; logger --priority user."$1" --tag "${0##*/}"; } <"$p" &). Je l'ai écrit en utilisant un langage de commande entièrement portable de toutes les manières - à l'exception du vôtre. Ce basenamen'est pas non plus un utilitaire très utile. "${0##*/}"est à la fois plus robuste et plus rapide.
mikeserv
Je l'ai changé car je n'en ai besoin que pour travailler sur des plateformes modernes; la question principale était que .xprofiledoit être exécuté avec sh.
l0b0
1
@Wildcard - juste une minute et je vais essayer de trier la première partie de la question, mais la réponse à la seconde est oui: le cas de bord est un zshw / multios activé. En ce qui concerne la première partie: { this; can\'t; happen; before; } < this. Est ce que ça aide?
logger
et transmettent la même entrée à chacune d'elles.Substitution de commandes / processus POSIX
Vous devriez pouvoir l'utiliser comme:
Voici une version qui utilise la
mktemp
commande:... qui fait à peu près la même chose, sauf qu'il permet
mktemp
de sélectionner le nom de fichier pour vous. Cela fonctionne parce que la substitution de processus n'est en aucun cas magique et fonctionne de manière très similaire à la substitution de commandes . Au lieu de remplacer l'expansion avec la valeur de la commande exécuter en son sein comme une substitution de commande fait, la substitution de processus remplace par le nom d'un lien de système de fichiers où la sortie se trouve.Bien que le shell POSIX ne fournisse pas de corollaire direct à une telle chose, l'émuler se fait très simplement. Tout ce que vous avez à faire est de créer un fichier, d'imprimer son nom dans la norme à partir d'une substitution de commande et, en arrière-plan, d'exécuter votre commande qui sortira dans ce fichier. Maintenant, vous pouvez simplement rediriger vers la valeur de cette expansion - exactement comme vous le faites avec la substitution de processus. Et donc le shell POSIX fournit tous les outils dont vous avez besoin bien sûr - tout ce qui est requis est que vous les utilisiez d'une manière qui vous convient.
Les deux versions ci-dessus garantissent qu'elles détruisent le lien du système de fichiers vers les canaux qu'elles créent / utilisent avant de les utiliser. Cela signifie qu'aucun nettoyage n'est requis après coup, et, plus important encore, leurs flux ne sont disponibles que pour les processus qui les ouvrent initialement - et donc leurs liens de système de fichiers ne peuvent pas être utilisés comme un moyen pour espionner / détourner votre activité de journalisation. Laisser leurs liens fs dans le système de fichiers est une faille de sécurité potentielle.
Une autre façon est de l'envelopper. Cela peut être fait à partir du script.
Cela permettrait essentiellement à votre script de s'appeler s'il ne l'a pas encore fait et de vous obtenir un répertoire de travail dans temp pour démarrer.
la source
mktemp
et d' autres commandes non standard, il pourrait être:_log()( p=; mkfifo "${p:=$(mktemp -u)}"; printf %s "$p"; exec <&- >&- <>/dev/null >&0; { rm "$p"; logger --priority user."$1" --tag "${0##*/}"; } <"$p" &)
. Je l'ai écrit en utilisant un langage de commande entièrement portable de toutes les manières - à l'exception du vôtre. Cebasename
n'est pas non plus un utilitaire très utile."${0##*/}"
est à la fois plus robuste et plus rapide..xprofile
doit être exécuté avecsh
.zsh
w / multios activé. En ce qui concerne la première partie:{ this; can\'t; happen; before; } < this
. Est ce que ça aide?