J'essaie d' cd
accepter un nom de répertoire redirigé vers lui à partir d'une autre commande. Aucune de ces méthodes ne fonctionne:
$ echo $HOME | cd
$ echo $HOME | xargs cd
Cela fonctionne:
$ cd $(echo $HOME)
Pourquoi le premier ensemble de commandes ne fonctionne-t-il pas et y en a-t-il d'autres qui échouent également de cette façon?
shell
io-redirection
pipe
cd-command
Jhonathan
la source
la source
Réponses:
cd
n'est pas une commande externe - c'est une fonction intégrée au shell. Il s'exécute dans le contexte du shell actuel, et non, comme le font les commandes externes, dans un contexte fork / exec'd en tant que processus séparé.Votre troisième exemple fonctionne, car le shell développe la variable et la substitution de commande avant d'appeler le
cd
builtin, de sorte quecd
reçoit la valeur de${HOME}
comme argument.Les systèmes POSIX faire un binaire
cd
- sur ma machine FreeBSD, il est à/usr/bin/cd
, mais il ne fait pas ce que vous pensez. L'appel du binairecd
amène le shell à bifurquer / exécuter le binaire, ce qui change en effet son répertoire de travail au nom que vous passez. Cependant, dès qu'il le fait, le binaire se ferme et le processus forké / exécuté disparaît, vous ramenant à votre shell, qui se trouve toujours dans le répertoire dans lequel il se trouvait avant de commencer.la source
cd
commande externe ?cd
ne lit pas l'entrée standard. C'est pourquoi votre premier exemple ne fonctionne pas.xargs
a besoin d'un nom de commande, c'est-à-dire du nom d'un exécutable indépendant.cd
doit être une commande intégrée au shell et n'aurait aucun effet (autre que la vérification que vous pouvez passer à ce répertoire et les effets secondaires potentiels qu'il peut avoir comme pour les répertoires montables automatiquement) s'il s'agissait d'un exécutable. C'est pourquoi votre deuxième exemple ne fonctionne pas.la source
En plus de la bonne réponse existante, il convient également de mentionner qu'un tube bifurque un nouveau processus, qui a son propre répertoire de travail séparé. Par conséquent, essayer de le faire ne fonctionnera pas:
Ainsi, vous ne serez pas dans le dossier / après le retour du shell à partir de cette commande.
la source
a | b
, même sia
etb
sont intégrées, au moins une ne s'exécute pas dans le processus shell, mais il n'y a aucune garantie de laquelle il s'agit. Par exemple, dans AT&Tksh
,zsh
oubash -O lastpipe
,b
est exécuté dans le processus shell en cours, donc votre code vous amènerait à / là.En plus des bonnes réponses déjà données: Si vous exécutez bash et que vous voulez savoir ce qu'est une "commande" comme cd, vous pouvez utiliser type
ou pourquoi pas:
alors que par exemple le temps gnu est normalement déjà inclus dans votre distribution préférée:
Okey ok vous avez l'idée, alors qu'est-ce que c'est que le type?
Voici un extrait de manuel bash:
la source
Comme d'autres l'ont dit, cela ne fonctionnera pas car
cd
c'est une commande intégrée au shell, pas un programme externe, donc il n'a pas d'entrée standard dans laquelle vous pouvez diriger quoi que ce soit.Mais, même si cela fonctionnait, il ne ferait pas ce que vous souhaitez: un tuyau engendre un nouveau processus et redirige la sortie standard de la première commande vers l'entrée standard de la seconde, donc seul le nouveau processus changerait son fonctionnement actuel annuaire; cela ne pouvait en aucun cas affecter le premier processus.
la source
read
est généralement (toujours?) un shell intégré. Il est vrai quecd
ignore stdin, mais ce n'est pas dû au fait qu'il est intégré.Une autre option est les backticks, qui placent la sortie standard d'une commande comme argument de ligne de commande d'une deuxième commande, et sont plus portables que
$(...)
. Par exemple:ou plus généralement;
Notez que l'utilisation de backticks dépend du shell pour exécuter la commande et substituer la sortie sur la ligne de commande. La plupart des obus le supportent.
la source
$(...)
fonctionne. Je ne pense pas que ce soit un bon conseil de recommander plutôt les backticks, car ils ont des règles de citation beaucoup plus compliquées et sont généralement plus sujettes aux erreurs. (Voir §3.5.4 «Substitution de commande» dans le manuel de référence de Bash .)$(...)
sur un système mais pas sur un autre ??$(…)
. Les systèmes sans shell POSIX (c'est-à-dire avec un véritable shell Bourne) seraient extrêmement anciens. Même les systèmes où se/bin/sh
trouve un shell Bourne et dont vous avez besoin d'un autre chemin/usr/xpg4/bin/sh
pour obtenir un shell POSIX sont rares de nos jours. Recommander des backticks à quiconque n'administre pas professionnellement les anciennes boîtes Unix leur rend un mauvais service.