2016-10-13 3 views
0

J'ai un script qui prend un ou plusieurs fichiers comme arguments de ligne de commande et génère un tas de tracés. Je voudrais pouvoir utiliser ce script de façon à pouvoir trouver tous les fichiers pertinents et les rediriger vers le script. J'ai donc l'appel suivant:Comment éviter EOF Erreur lors de la redirection de plusieurs fichiers dans un script python

find $PWD/somedir/ -path '*_d0/final/*' -name 'somefile.gz' -print0|sort -z |xargs -0 python smth.py 

Jusqu'à présent, si bien ... La question est bien que je besoin d'entrée de l'utilisateur, en ce qui concerne les colonnes à utiliser (le script doit être flexible) et plus tard que nommer les chiffres de sortie.

C'est là où il casse, je reçois un EOFError: EOF when reading a line au premier appel input(). Je comprends que l'utilisation de tuyaux lie les stdin et stdout de différents programmes les uns aux autres et appelant ainsi input() à lire à partir de stdin plus tard dans le script ne fonctionne pas.

Comment naviguer dans cette zone? J'ai pensé à d'autres manières d'obtenir des informations de la part de l'utilisateur, comme avec un fichier de configuration soumis à l'exécution, mais je n'aime pas cette solution car c'est un peu un frein pour préparer les fichiers de configuration pour chaque exécution. Il devrait y avoir une façon plus simple de résoudre ce problème.

Suggestions?

+0

Que diriez-vous de stocker temporairement la sortie de pipe dans un fichier, puis d'exécuter votre script python comme une seconde commande, demandant à l'utilisateur de saisir et de lire les valeurs sélectives de la sortie stockée? –

+0

@FurhanS. pas sûr de ce que vous voulez dire, pouvez-vous élaborer un peu? – posdef

Répondre

0

Pouvez-vous le faire par étapes? Quelque chose comme ci-dessous:

Étape 1 - trouver les données et les stocker dans un fichier temporaire

find $PWD/somedir/ -path '*_d0/final/*' -name 'somefile.gz' -print0|sort -z >> output.out 

Étape 2 - Utilisez votre script python pour faire tout ce que vous désirez avec elle, en fonction de l'entrée utilisateur

python smth.py < output.out 

Dans votre script python, enregistrez les données de output.out dans un temp var, sur lequel vous devrez agir en fonction de l'entrée de l'utilisateur.

+0

Vous suggérez donc de créer un fichier contenant une liste de fichiers, qui est ensuite utilisé comme entrée pour le script python? Que fait le '' '? ne bloquera-t-il pas le stdin pour le script python? – posdef

+0

@posdef oui. Ecrire le contenu dans un fichier, si c'est une option. Remplacé << par

0

Dans mon système, xargs homme propose l'option -o spécifiquement pour que:

-o Rouvrez stdin/dev/TTY dans le processus de l'enfant avant d'exécuter la commande . Ceci est utile si vous voulez que xargs exécute une application interactive.

Cela signifie que vous devez simplement utiliser:

find $PWD/somedir/ -path '*_d0/final/*' -name 'somefile.gz' -print0|sort -z |xargs -0 -o python smth.py 
+0

Quelle version de xargs avez-vous? – posdef

+0

J'ai cette option sur mon mac mais pas sur le serveur distant que je ssh à .. C'est un peu bizarre puisque la version sur le serveur Ubuntu date de 2016 (GNU findutils 4.7.0) – posdef

0

Pour référence this answer donne un aperçu de la raison pour laquelle le problème se produit. En bref, xargs pointe par défaut le stdin à /dev/null, car il ne sait pas ce qu'il devrait être autrement. Bien qu'il existe une bonne façon de contourner ce problème sur BSD xargs (en fournissant -o drapeau), les boursiers à GNU findutils seem to think que echo foo bar | xargs sh -c 'emacs "[email protected]" < /dev/tty' emacs est une meilleure façon de le faire.

Dans ce cas, il finit par regarder quelque chose comme ceci:

find $PWD/somedir/ -path '*_d0/final/*' -name 'somefile.gz' -print0|sort -z |xargs -0 bash -c '</dev/tty python myscript.py "[email protected]"' ignoreme 

Il fonctionne, mais je devrais être en désaccord avec respect avec les devs de GNU findutils, il est une façon terriblement maladroite de contourner la question de la utilisateur final. J'espère toujours trouver une meilleure solution à ce problème.

Néanmoins, je fournirai cette réponse comme référence pour d'autres personnes susceptibles de rencontrer des problèmes similaires, au cas où cela s'avérerait être la meilleure solution.