2010-03-24 19 views
5

j'ai une application qui exécute l'une commande comme ci-dessous:Comment rediriger la sortie loin de/dev/null

<command> <switches> >& /dev/null

Je peux configurer <command>, mais je n'ai aucun contrôle sur <switches>. Toutes les sorties générées par cette commande vont à /dev/null. Je veux que la sortie soit visible à l'écran ou redirigée vers un fichier journal.

J'ai essayé d'utiliser freopen() et des fonctions connexes pour rouvrir /dev/null dans un autre fichier, mais je n'ai pas réussi à le faire fonctionner.

Avez-vous d'autres idées? Est-ce possible?

Merci pour votre temps.

PS: Je travaille sur Linux.

+0

Qu'est-ce que cela a à voir avec Perl? –

+0

Sauf si vous pouvez changer la commande dans le script, je pense que vous n'avez pas de chance. Une fois qu'il a été redirigé vers null, vous ne pouvez plus le récupérer car tous les descripteurs de fichiers que vous pourriez partager avec lui (stdin, stdout, stderr) ont disparu. – tvanfosson

+0

Vous avez donc le contrôle sur la commande, mais pas sur la redirection? Si oui, je dirais que e-t172 a raison, ou du moins aussi bien que vous allez l'obtenir: http://stackoverflow.com/questions/2507569/how-to-redirect-output-away-from -dev-null/2507624 # 2507624 Si non, s'il vous plaît mettre à jour pour clarifier. –

Répondre

4

Étant donné que vous pouvez modifier la commande que vous exécutez, vous pouvez utiliser un simple script shell comme encapsuleur pour rediriger la sortie vers un fichier.

#!/bin/bash 
"[email protected]" >> logfile 

Si vous enregistrez dans votre chemin que capture_output.sh vous pouvez ajouter capture_output.sh au début de votre commande pour ajouter la sortie de votre programme à logfile.

7

Terrible Hack:

utiliser un éditeur de texte en mode binaire ouvrir l'application, trouver '/ dev/null /' et le remplacer par une chaîne de la même longueur

e.g '~/tmp/log' 
  • faire une première sauvegarde
  • Attention
  • très
  • carefull ai-je mentionné la sauvegarde?
+0

Clarification: ouvrir l'exécutable binaire avec l'éditeur de texte Quelque part dans le charabia du truc binaire il devrait y avoir "/ dev/null" qui est ce que vous remplacez comme – Ricket

+0

@lexu: Je l'avais fait plus tôt, j'ai remplacé/dev/null par une chaîne d'espaces de longueur égale Cela fonctionne, mais pour chaque version de l'application, le piratage de l'exécutable est fastidieux ... penser à écrire un programme qui fait du piratage de redirection et appelle le . Ce sera un effort ponctuel. – Gowtham

+1

+1 pour la liste d'accompagnement. –

2

Ajoutez # à la fin de votre commande afin qu'elle devienne <command> # >& /dev/null, en commentant ainsi la partie non désirée.

+0

@ e-t172: Bonne idée. J'ai oublié de mentionner le . La commande est appelée comme '> &/dev/null' – Gowtham

1

Pouvez-vous créer un alias pour cette commande? Si c'est le cas, aliasz-le à une autre commande qui renvoie la sortie dans un fichier.

0

EDIT: Ce n'est pas une bonne idée et certainement pas la peine d'essayer, sauf si vous savez ce que cela peut casser. Cela fonctionne pour moi, peut travailler pour vous aussi.

Ok, c'est un très mauvais hack et probablement pas la peine de le faire. En supposant qu'aucune des autres commandes ne fonctionne, vous n'avez simplement pas accès à l'application binaire/(qui contient la commande avec /dev/null) et vous ne pouvez pas rediriger la sortie vers un autre fichier (en remplaçant /dev/null).

Ensuite, vous pouvez supprimer/dev/null ($> rm /dev/null) et créer votre propre fichier à sa place (de préférence avec un lien symbolique) où toutes les données peuvent être dirigées. Lorsque vous avez terminé, vous pouvez créer le répertoire/dev/null en utilisant une nouvelle fois la commande suivante:

$> mknod -m 666 /dev/null c 1 3

Juste pour être très clair, c'est une mauvaise bidouille et nécessite certainement racine autorisations au travail . Il y a de fortes chances que votre fichier redirigé contienne des données de nombreuses autres applications/binaires en cours d'exécution et utilise /dev/null comme récepteur.

+0

Juste pour ajouter, j'ai essayé ceci sur ma machine qui est une Fedora fonctionnant 2.6.30. Cette information est ainsi parce que le nombre majeur et mineur peut être différent pour mknod sur d'autres plates-formes/environnement. – Shrey

+0

Ce serait bien si "pourquoi-ma-réponse-a-été-votée-bas" est expliqué comme un commentaire. Je sais que c'est un hack (mentionné clairement) et c'est explicitement ce que l'affiche cherchait "... mais je n'ai aucun contrôle sur ...". – Shrey

+0

Supprimer/dev/null va au-delà d'être un hack. C'est une idée complètement brisée. Cela affecte tout le système (tout nouveau s'ouvre sur le chemin d'accès), pas seulement le script/programme ciblé. Il doit être "fixé" après que vous avez terminé. Et cela nécessite un accès root.La réponse ici n'est pas de "rediriger/dev/null" mais de rouvrir les descripteurs existants qui ont été ouverts depuis/dev/null. –

1

Le fichier de périphérique /dev/tty références terminal de contrôle de votre application - si cela n'a pas changé, cela devrait fonctionner:

freopen("/dev/tty", "w", stdout); 
freopen("/dev/tty", "w", stderr); 

Sinon, vous pouvez les rouvrir pour pointer vers un fichier journal:

freopen("/var/log/myapp.log", "a", stdout); 
freopen("/var/log/myapp.err", "a", stderr); 
2

Votre application exécute probablement un shell et lui transmet cette ligne de commande.

Vous devez lui faire exécuter un script écrit par vous. Ce script remplacera >/dev/null dans la ligne de commande avec >>/your/log et appellera le shell réel avec la ligne de commande modifiée.

La première étape consiste à changer le shell utilisé par l'application. Modification de la variable d'environnement SHELL devrait suffire, à savoir exécuter votre application comme

SHELL=/home/user/bin/myshell theApp 

Si cela ne fonctionne pas, essayez de relier momentanément /bin/sh à votre script.

myshell appellera la coquille d'origine, mais après motif-remplacement des paramètres:

#!/bin/bash 
sh ${1+"${@/\>\/dev\/null/>>\/your\/log}"} 

Quelque chose le long de ces lignes devrait fonctionner.

0

En perl, si vous voulez juste de rediriger STDOUT à quelque chose un peu plus utile, vous pouvez juste faire quelque chose comme:

open STDOUT, '>>', '/var/log/myscript.log'; 
open STDERR, '>>', '/var/log/myscript.err'; 

au début de votre script, et que vous rediriger pour le reste de votre script.

0

Le long des lignes de la réponse de e-T172, pouvez-vous définir le dernier commutateur (ou d'y ajouter du):

; echo 
1

Il ne peut pas rediriger exactement, mais il permet d'obtenir la sortie où il est être envoyé

strace -ewrite -p $PID

ce n'est pas cleen (montre des lignes comme: écriture (#,)), mais ça marche! (et est une seule ligne: D) Vous pourriez également ne pas aimer le fait, que les arguments sont abrégés. Pour contrôler ce paramètre use -s qui définit la longueur maximale des chaînes affichées.

Il capture tous les flux, donc vous pourriez vouloir filtrer d'une manière ou d'une autre.

Vous pouvez filtrer:

strace -ewrite -p $PID 2>&1 | grep "write(1"

montre que le descripteur 1 appels. 2> & 1 est de rediriger stderr vers stdout, car strace écrit sur stderr par défaut.

0

Si vous pouvez mettre quelque chose en ligne avant de passer les choses à/dev/null (je ne sais pas si vous avez une commande codée en dur), vous pouvez utiliser tee pour rediriger vers quelque chose de votre choix.

Exemple de Wikipedia qui permet l'escalade d'une commande:

echo "Body of file..." | sudo tee root_owned_file > /dev/null 

http://en.wikipedia.org/wiki/Tee_(command)