1
votes

Est-ce que python acceptera - (tiret) comme nom de fichier pour `open ()` pour écrire dans stdout?

Je travaille avec un script Python qui accepte un fichier comme argument. Il utilise open (outfile, "w") pour ouvrir et écrire dans ce fichier.

Une convention courante sous Linux est d'utiliser - (tiret) pour écrire dans stdout. C'est une convention courante mais pas standard ni partie d'un shell.

Puis-je passer - comme nom de fichier pour que Pythons open écrit dans stdout?


0 commentaires

4 Réponses :


-1
votes

Vous devriez tester pour en être sûr, mais selon la documentation Python:

open (fichier, mode = 'r', buffering = -1, encoding = None, errors = None, newline = None, closefd = True, opener = None)

file est un objet de type chemin donnant le chemin d'accès (absolu ou relatif dans le répertoire de travail courant) du fichier à ouvrir ou un descripteur de fichier entier du fichier à encapsuler. (Si un fichier descripteur est donné, il est fermé lorsque l'objet d'E / S renvoyé est fermé, sauf si closefd est défini sur False.)

Un objet de type chemin est un objet représentant un chemin d'accès au système de fichiers. UNE objet de type chemin est un objet str ou bytes représentant un chemin, ou un objet implémentant le protocole os.PathLike. Un objet qui prend en charge le protocole os.PathLike peut être converti en chaîne ou octets chemin du système de fichiers en appelant la fonction os.fspath (); os.fsdecode () et os.fsencode () peut être utilisé pour garantir un résultat str ou octets à la place, respectivement. Introduit par PEP 519.

Alors oui, ça devrait marcher.

Veuillez vous référer à https://docs.python.org/3/ library / functions.html # open et https: //docs.python.org/3/glossary.html#term-path-like-object pour plus d'informations.


5 commentaires

Je l'ai essayé et je me suis retrouvé avec un fichier nommé littéralement - (tiret) -rw-rw-r-- 1 groupe d'utilisateurs 232M 20 novembre 15:25 - . Je pense que sys.stdout est un objet semblable à un fichier, mais je ne pense pas pouvoir le passer comme argument.


Cela ne dit rien sur le fait qu'il soit pris en charge ou non. Il n'est pas pris en charge, car - n'est pas un nom de fichier valide.


Merci les gars pour l'explication, je n'en suis pas sûr aussi.


@MartijnPieters, ... hein? - est un nom de fichier parfaitement valide sous UNIX (évaluant à un fichier nommé - dans le répertoire courant, cependant, alors que l'OP demande s'ils peuvent utiliser ce nom pour obtenir un gérer sur stdout; afaict votre réponse est la seule correcte et sur le point ici, donc mon argument est uniquement avec le commentaire).


@CharlesDuffy oui, j'étais imprécis. Il s'agit d'un nom de fichier valide mais n'est pas destiné à être utilisé comme tel. C'est un nom symbiotique ici.



2
votes

Cela dépend de la manière dont vous récupérez les arguments de la ligne de commande. Avec les modules sys.argv, argparse ou OptionParser, oui c'est possible. Cela signifie que vous pouvez récupérer «-». Mais c'est à vous d'ouvrir stdout dans ce cas.


1 commentaires

Le script que j'ai utilise OptionParser docs.python.org/2 /library/optparse.html



-2
votes

Testé sous linux mint 19 (python 3.6) et il ne semble y avoir aucun problème. Les caractères à éviter dans les noms de fichiers sont cependant:

\ /: *? "<> |

Certains d'entre eux fonctionnent en fait sous Linux, mais pourquoi sacrifieriez-vous la portabilité?


4 commentaires

L'OP ne veut pas ouvrir un fichier dont le nom est un tiret, il veut ouvrir stdout (car de nombreux outils sous UNIX traitent un seul tiret comme une référence à la FD stdin ou stdout existante, selon que l'ouverture est ou écrivez). Le conseil sur les noms de fichiers est un non-sequitur complet.


J'ai relu le post de l'OP, et il est tout à fait clair qu'ils demandent si open ('-', 'w') ouvre stdout, pas s'il peut être utilisé pour ouvrir un fichier nommé - .


BTW, chaque caractère autre que / et le caractère NUL est valide dans les noms de fichiers sur les systèmes Unixlike conventionnels (et bien sûr / est valide en entier- chemins qualifiés, on pourrait donc dire avec précision que NUL est le seul caractère non valide dans les noms de fichiers sous UNIX). Ce n'est pas du tout le point, cependant, que l'OP ne posait aucune question sur les noms de fichiers valides, mais demandait s'ils avaient besoin d'un traitement spécial pour faire passer un - à leur script en tant que nom de fichier résolu en sys.stdin ou sys.stdout selon le cas; leurs commentaires sur d'autres réponses et leur choix de réponse acceptée le rendent encore plus clair.


@CharlesDuffy, c'était rapide. Désolé, j'avais supprimé mon commentaire précédent et ce n'est qu'après l'actualisation du navigateur que j'ai réalisé que vous aviez répondu.



2
votes

Non, la bibliothèque standard open () La fonction ne traduit pas le nom de fichier '-' en stdin ou stdout . C'est juste un nom de fichier ordinaire , donc open ("-", "w") écrira dans un fichier dans le répertoire de travail actuel nommé - code >.

Vous devez tester explicitement cette valeur et donc renvoyer sys.stdin ou sys.stdout (en fonction de ce que vous avez besoin de lire ou d'écrire) , au lieu d'ouvrir un fichier.

Par exemple la click bibliothèque d'interface de ligne de commande , qui prend en charge l'utilisation de - comme nom de fichier sur la commande ligne , teste explicitement un nom de fichier '-' dans leur open_stream () implémentation :

>>> inp = open(0)
>>> inp
<_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>
>>> inp.read(1)  # read 1 character from stdin, I entered 'a'
a
'a'
>>> outp = open(1, 'w')
>>> outp
<_io.TextIOWrapper name=1 mode='w' encoding='UTF-8'>
>>> outp.write("foo!")  # line buffered, no newline written so not visible yet
4
>>> outp.flush()  # flush the buffer
foo!>>>

open () code> accepte les descripteurs de fichiers , vous pouvez donc transmettre 0 pour l'entrée standard, ou 1 pour la sortie standard:

if filename == '-':
    if any(m in mode for m in ['w', 'a', 'x']):
        if 'b' in mode:
            return get_binary_stdout(), False
        return get_text_stdout(encoding=encoding, errors=errors), False
    if 'b' in mode:
        return get_binary_stdin(), False
    return get_text_stdin(encoding=encoding, errors=errors), False


0 commentaires