Comment créer un fichier nommé comme un argument de ligne de commande?


29

Je me demandais comment créer un fichier nommé comme indicateur, par exemple, si je voulais créer un dossier nommé -a, quelles commandes feraient l'affaire?

J'ai essayé mkdir '-a', mkdir \-aet aucun n'a fonctionné. Je suis sur Ubuntu.


13
Les réponses ici sont toutes excellentes, mais je ne vois pas de raison non troll de vouloir faire ça ...
evilsoup

@evilsoup Certaines personnes aiment préfixer les dossiers afin qu'ils restent en haut d'une liste triée par ordre alphanumérique. Mais c'est la seule raison à laquelle je peux penser, pour être honnête.
slhck

@slhck Je connais au moins un cours de montage vidéo où ils encouragent les étudiants à ajouter des espaces vides aux répertoires de leurs projets afin qu'ils apparaissent en haut sur les iMac communaux. C'était moche et a conduit à une escalade hilarante, mais au moins ce ne serait pas potentiellement une rupture du système ...
evilsoup

3
C'est surtout ici pour l'intérêt académique.
MYV

5
Bande dessinée obligatoire: beesbuzz.biz/d/20110224.php
moelleux

Réponses:


49

Appelez la commande comme ceci:

mkdir -- -a

Les --moyens que les options se terminent après, de sorte que le -aest interprété littéralement et non comme une option mkdir. Vous trouverez cette syntaxe non seulement dans mkdir, mais dans tout utilitaire compatible POSIX à l'exception de echoet test. De la spécification :

L'argument - doit être accepté comme un délimiteur indiquant la fin des options. Tous les arguments suivants doivent être traités comme des opérandes, même s'ils commencent par le caractère «-». L'argument - ne doit pas être utilisé comme option ou comme opérande.

L'utilisation --comme sauvegarde est recommandée pour presque toutes les actions où vous traitez des noms de fichiers et voulez vous assurer qu'ils ne cassent pas la commande, par exemple lorsque vous déplacez des fichiers dans une boucle, vous pouvez appeler ce qui suit, de sorte qu'un fichier appelé -in'est pas ' t (in?) correctement analysé en option:

mv -- "$f" new-"$f"

L'inconvénient de cette approche est précisément qu'elle met fin au traitement des options. Pour un exemple simple de mkdir, cela fait des merveilles; si vous avez réellement besoin d'une option pour suivre le nom du fichier sur la ligne de commande, cela ne fonctionnera pas du tout.
un CVn

1
Bien sûr, il y a un inconvénient à tout. Dans les cas où vous traitez avec des noms de fichiers entrecoupés d'options, la solution d'Amos serait la seule alternative saine à laquelle je peux penser, mais cela dépend vraiment de la façon dont l'outil analyse les options.
slhck

1
Étant donné que l'OP parle de créer un fichier avec un nom "comme un argument de ligne de commande" (supposons que cela signifie un nom commençant par un trait d'union), je ne pense pas que ce soit une hypothèse totalement déraisonnable. Prenons cc -o -myfile -Wall -myfile.cun exemple légèrement artificiel. Tout éditeur digne de ce nom devrait être capable d'enregistrer dans un fichier nommé -myfile.csi vous le lui demandez, mais le compilateur C ne fera probablement pas ce que vous voulez quand on lui donnera une telle liste d'options.
un CVn

1
@Maksim Par exemple, les commandes qui nécessitent une option pour définir un nom de fichier d'entrée ou de sortie, comme la cccommande que Michael a donnée ci-dessus, qui a la -opossibilité de spécifier le fichier de sortie.
slhck

1
L'exemple de boucle est la raison pour laquelle vous devriez toujours utiliser quelque chose comme for f in ./*; do...plutôt quefor f in *; do...
evilsoup

21

La manière la plus simple qui devrait fonctionner avec n'importe quel programme raisonnable est d'utiliser un nom de chemin relatif devant le -, par exemple mkdir ./-a, créera un répertoire appelé -adans le répertoire de travail courant.

L'exemple le plus courant d'utiliser cette "astuce" est lorsque vous souhaitez supprimer un fichier qui commence par un tiret, afin que vous puissiez le faire rm ./-a.


3
Bien sûr, cela ne fonctionne que si vous travaillez avec des chemins de fichier, et non avec des options de ligne de commande arbitraires qui sont analysées en tant que chaînes. Mais sinon, le préfixe ./est toujours une bonne idée - imaginez que vous avez créé un fichier appelé -rfpuis que vous avez appelé rm *.
slhck

1
@slhck Pour beaucoup de gens qui pourraient ressembler à une blague. Mais j'ai vu suffisamment de cas où ce genre de chose a effacé (une partie d'un) serveur. Vous ne pouvez pas suffisamment avertir les gens des dangers des fichiers commençant par un tiret. Un endroit où j'ai travaillé l'a même eu comme règle officielle: ne jamais créer un fichier dont le nom commence par "-f" ou "-r".
Tonny

1
Celui-ci devrait être la réponse: c'est le seul moyen portable ( --n'est pas compris par toutes les commandes, juste quelques-unes)
Olivier Dulac

@OlivierDulac Je pensais que --c'était un truc bash, donc ça devrait marcher pour tous les programmes?
gsingh2011

@ gsingh2011 non, le code qui décide si "-" est considéré comme un marqueur "fin de fanions" habite dans l'application et c'est à chaque application de décider si elle le traite de cette façon.
Amos Shapira

4

La raison pour laquelle mkdir '-a', ou mkdir \-ane fonctionne pas, est parce que ces deux méthodes (en utilisant des guillemets ou des barres obliques inverses) sont utilisées pour empêcher votre shell (probablement bash) de leur donner une signification particulière. Comme -acela ne signifie de toute façon rien de spécial pour le shell, ceux-ci n'ont aucun effet sur la façon dont il est transmis mkdir.

En ce qui le mkdirconcerne, il reçoit une liste d'arguments du shell, et il ne peut pas dire si vous les avez mis entre guillemets ou non, ou s'il y a eu une barre oblique inverse. Il ne voit qu'un seul argument -a. C'est pourquoi vous avez besoin du --comme expliqué dans les autres réponses.


-3

En plus de la réponse de "slhck", il existe une autre astuce qui fonctionne parfois:

Mettez le nom de fichier en question dans 2 ensembles de qoutes (différentes) comme "'-a'"ou '"-a"'.

Que cela fonctionne ou non dépend du programme, mais c'est un dernier recours si le programme ne prend pas en charge la --fonction POSIX .
La méthode POSIX est toujours préférée car elle est fiable à 100%.


"La méthode POSIX est toujours préférée car elle est fiable à 100%." Utiliser --pour terminer le traitement des options suppose également que vous n'avez pas besoin d'options pour suivre le nom du fichier, ce qui n'est pas toujours le cas.
un CVn

@ MichaelKjörling Bien sûr ... Mais je suppose que ce serait évident.
Tonny

4
Cela va créer un fichier appelé '-a'ou "-a", au moins sur les systèmes de type BSD
nohillside

4
Pouvez - vous citer un OS / shell où cela fait le travail?
nohillside

1
si cela fonctionnait, il semblerait que vous auriez un problème assez important avec les fichiers dont les noms sont entourés de guillemets.
muhmuhten
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.