Estoy tratando de cd
aceptar un nombre de directorio redirigido a él desde otro comando. Ninguno de estos métodos funciona:
$ echo $HOME | cd
$ echo $HOME | xargs cd
Esto funciona:
$ cd $(echo $HOME)
¿Por qué el primer conjunto de comandos no funciona, y hay otros que también fallan de esta manera?
shell
io-redirection
pipe
cd-command
Jhonathan
fuente
fuente
Respuestas:
cd
no es un comando externo, es una función interna de shell. Se ejecuta en el contexto del shell actual, y no, como lo hacen los comandos externos, en un contexto fork / exec'd como un proceso separado.Su tercer ejemplo funciona, porque el shell expande la variable y la sustitución del comando antes de llamar al
cd
builtin, de modo quecd
recibe el valor de${HOME}
como argumento.Los sistemas POSIX hacer tener un binario
cd
- en mi máquina FreeBSD, está en/usr/bin/cd
, pero no hace lo que usted piensa. Llamar al binariocd
hace que el shell bifurque / ejecute el binario, lo que de hecho cambia su directorio de trabajo al nombre que pasa. Sin embargo, tan pronto como lo hace, el binario se cierra y el proceso bifurcado / ejecutado desaparece, regresando a su shell, que todavía está en el directorio en el que estaba antes de comenzar.fuente
cd
comando externo ?cd
no lee la entrada estándar. Es por eso que tu primer ejemplo no funciona.xargs
necesita un nombre de comando, es decir, un nombre de un ejecutable independiente.cd
debe ser un comando integrado de shell y no tendría ningún efecto (aparte de verificar que puede cambiar a ese directorio y los posibles efectos secundarios que podría tener para los directorios automontables) si fuera un ejecutable. Es por eso que su segundo ejemplo no funciona.fuente
Además de la buena respuesta existente, también vale la pena mencionar que una tubería bifurca un nuevo proceso, que tiene su propio directorio de trabajo separado. Por lo tanto, tratar de hacer esto no funcionará:
Por lo tanto, no estará en la carpeta / después de que el shell regrese de este comando.
fuente
a | b
, incluso sia
yb
están builtin, al menos uno, entonces no se ejecuta en el proceso de shell, pero no hay garantía de lo que de cuál se trata. Por ejemplo, en AT&Tksh
,zsh
obash -O lastpipe
,b
se ejecuta en el proceso de shell actual, por lo que su código lo llevaría a / allí.Además de las respuestas correctas ya dadas: si ejecuta bash y desea saber qué es un "comando" como cd , puede usar type
o por qué no:
mientras que, por ejemplo, el tiempo de GNU normalmente ya está incluido en su distribución favorita:
Okey okey tienes la idea, entonces, ¿qué diablos es el tipo?
Aquí hay un fragmento de manual de bash:
fuente
Como han dicho otros, no funcionará porque
cd
es un comando integrado de shell, no un programa externo, por lo que no tiene ninguna entrada estándar en la que pueda canalizar nada.Pero, incluso si funcionara, no haría lo que desea: una tubería genera un nuevo proceso y redirige la salida estándar del primer comando a la entrada estándar del segundo, por lo que solo el nuevo proceso cambiaría su funcionamiento actual directorio; Esto no podría afectar el primer proceso de ninguna manera.
fuente
read
es generalmente (¿siempre?) Es cierto quecd
ignora el stdin, pero esto no se debe a que sea un incorporado.Otra opción son los backticks, que colocan la salida estándar de un comando como argumento de línea de comando de un segundo comando, y son más portátiles que
$(...)
. Por ejemplo:o más generalmente;
Tenga en cuenta que el uso de backticks depende del shell para ejecutar el comando y sustituir la salida en la línea de comando. La mayoría de los proyectiles lo soportan.
fuente
$(...)
funciona. No creo que sea un buen consejo recomendar backticks, ya que tienen reglas de cotización mucho más complicadas y generalmente son más propensas a errores. (Ver § 3.5.4 "Sustitución de comandos" en el Manual de referencia de Bash .)$(...)
en un sistema pero no en otro?$(…)
. Los sistemas sin un shell POSIX (es decir, con un shell Bourne genuino) serían extremadamente antiguos. Incluso los sistemas donde/bin/sh
hay un shell Bourne y necesita otra ruta, como/usr/xpg4/bin/sh
obtener un shell POSIX, son raros hoy en día. Recomendar backticks a cualquiera que no administre profesionalmente unix boxen antiguo les está perjudicando.