Par définition homme, cette commande obtient l'entrée d'un fichier.
$ command -r FILENAME
Supposons qu'il FILENAME
s'agit d'un fichier contenant une liste de noms de fichiers, tel qu'il a été généré à l'aide de ls > FILENAME
.
Comment puis-je, au lieu de cela, alimenter la commande avec le résultat de ls
directement? Dans ma tête, quelque chose comme ça devrait être possible:
$ ls | command -r
Mais ce n'est pas le cas, la sortie de ls
n'est pas accrochée comme argument. Production:
Usage: command -r FILENAME
error: -r option requires an argument
Comment puis-je obtenir l'effet souhaité?
Réponses:
Cela dépend de la commande. Certaines commandes qui lisent à partir d'un fichier s'attendent à ce que le fichier soit un fichier normal, dont la taille est connue à l'avance, et qui peut être lu à partir de n'importe quelle position et rembobiné. Ceci est peu probable si le contenu du fichier est une liste de noms de fichiers: alors la commande se contentera probablement d'un tube qu'elle lira juste séquentiellement du début à la fin. Il existe plusieurs façons d'alimenter des données via un canal vers une commande qui attend un nom de fichier.
De nombreuses commandes traitent
-
comme un nom spécial, ce qui signifie lire à partir d' une entrée standard plutôt que d'ouvrir un fichier. C'est une convention, pas une obligation.De nombreuses variantes Unix fournissent des fichiers spéciaux
/dev
qui désignent les descripteurs standard. S'il/dev/stdin
existe, l'ouvrir et le lire équivaut à lire à partir de l'entrée standard; de même/dev/fd/0
s'il existe.Si votre shell est ksh, bash ou zsh, vous pouvez faire en sorte que le shell s'occupe d'allouer un descripteur de fichier. Le principal avantage de cette méthode est qu'elle n'est pas liée à l'entrée standard, vous pouvez donc utiliser l'entrée standard pour autre chose et vous pouvez l'utiliser plusieurs fois.
Si la commande s'attend à ce que le nom ait une forme particulière (généralement une extension particulière), vous pouvez essayer de le tromper avec un lien symbolique.
Ou vous pouvez utiliser un tuyau nommé.
Notez que la génération d'une liste de fichiers avec
ls
est problématique car ellels
tend à modifier les noms de fichiers lorsqu'ils contiennent des caractères non imprimables.printf '%s\n' *
est plus fiable - il imprimera chaque octet littéralement dans les noms de fichiers. Les noms de fichiers contenant des retours à la ligne causeront toujours des problèmes, mais cela est inévitable si la commande attend une liste de noms de fichiers séparés par des retours à la ligne.la source
Ça devrait être:
Modifier: pour les noms avec des espaces vides:
la source
command
pense qu'il a tous les noms de fichiers dont il aura besoin en même temps sur la ligne de commande. Certaines versions de xargs donnerontcommand
quelques noms de fichiers (10, il me semble) à la fois. On dirait que GNU xargs donne tout à la fois.En fait, la seule solution fiable que je connaisse qui puisse gérer tous les noms de fichiers, y compris ceux qui contiennent une nouvelle ligne, est:
Le seul caractère non autorisé dans le nom de fichier dans ce cas est le caractère nul, qui n'est de toute façon pas autorisé dans les noms de fichiers.
la source
De nombreuses commandes acceptent
-
comme un "nom de fichier" qui signifie "utiliser l'entrée standard", mais cette convention est loin d'être universelle. Lisez la page de manuel.la source
Cela devrait fonctionner pour votre objectif:
ls | command -r /dev/stdin
la source