Lo intenté which cd
y no dio una ruta, sino que devolvió el código de salida 1 (comprobado con echo $?
). El coreutil en cd
sí está funcionando, por lo que el ejecutable debería estar allí, ¿verdad? También ejecuté un find
for cd
, pero no se mostró ningún archivo ejecutable. ¿Cómo se implementa entonces?
Actualizar:
No sé si debería preguntar esto en otra publicación, pero como creo que es bueno aquí, estoy expandiendo (?) La publicación ... Entonces la respuesta fue bastante simple, no hay ejecutable para eso, porque es un builtin - ¡Pero he encontrado que algunos builtins (bash shell en Fedora) tienen los archivos ejecutables! Por lo tanto, supongo que no incluye ningún ejecutable. Tal vez una respuesta que explique qué son los builtins en realidad (¿comandos builtin?), Lo cual es el problema aquí, en lugar de centrarse más en cd
... Algunos buenos enlaces publicados anteriormente indican que los builtins no son programas ... entonces, ¿qué son? ¿Cómo trabajan? ¿Son solo funciones o hilos del shell?
fuente
type
comandocd
debe ser un programa integrado: ¿Por qué el CD no es un programa? y este sobre por quétype
es mejor quewhich
: ¿Por qué no usar "which"? ¿Qué usar entonces?Respuestas:
El comando
cd
no puede ser un ejecutableEn un shell,
cd
se usa para "ir a otro directorio", o más formalmente, para cambiar el directorio de trabajo actual (CWD). Es imposible implementar eso como un comando externo:El directorio pertenece a un proceso.
El directorio de trabajo actual es el directorio que se utiliza para interpretar rutas relativas para obtener una ruta completa que se puede usar para acceder a los archivos. Las rutas relativas se utilizan en muchos lugares, y la interpretación en un proceso no debe influir en otro proceso.
Por esta razón, cada proceso tiene su propio directorio de trabajo actual.
cd
se trata de cambiar el directorio de trabajo actual del proceso de shell, por ejemplobash
.Si se tratara de un comando externo, un ejecutable en la ruta, ejecutar ese ejecutable crearía un proceso con su propio directorio de trabajo, sin influir en el del shell actual. Incluso si el comando externo cambiara su directorio, ese cambio desaparecerá cuando el proceso externo salga.
Comandos incorporados de Shell
Por lo tanto, no tiene sentido ejecutar un comando externo para la tarea de
cd
. El comandocd
debe aplicar un cambio al proceso de shell actualmente en ejecución.Para hacer eso, es un "comando incorporado" del shell.
Los comandos incorporados son comandos que se comportan de manera similar a los comandos externos, pero se implementan en el shell (por
cd
lo que no forma parte de los coreutils). Esto permite que el comando cambie el estado del shell, en este caso para llamar achdir()
see (seeman 2 chdir
);Acerca de
which
Ahora, la respuesta a la pregunta del título es fácil:
el comando ejecutable
which
no puede decirnos que cd es un comando incorporado porque un comando ejecutable no sabe nada sobre los incorporados.Alternativa
type -a
Como alternativa a
which
, puede usartype -a
; Puede ver comandos ejecutables y componentes incorporados; Además, ve alias y funciones, también implementados en el shell:fuente
cd
es un shell incorporado.cd
es un shell incorporado ordenado por POSIX :Si bien esto no dice explícitamente que tiene que ser incorporado, la especificación continúa diciendo, en la descripción de
cd
:Del
bash
manual :Supongo que se podría pensar en una arquitectura donde
cd
no tiene que ser un edificio. Sin embargo, tienes que ver lo que implica un incorporado. Si escribe un código especial en el shell para hacer algo para un comando, se está acercando a tener un builtin incorporado. Cuanto más lo hagas, mejor será simplemente tener un incorporado.Por ejemplo, podría hacer que el shell tenga IPC para comunicarse con subprocesos, y habría un
cd
programa que verificaría la existencia del directorio y si tiene permiso para acceder y luego se comunica con el shell para indicarle que cambie su directorio. Sin embargo, deberá verificar si el proceso de comunicación con usted es un niño (o hacer un medio especial de comunicación solo con los niños, como un descriptor de archivo especial, memoria compartida, etc.), y si el proceso es realmente ejecutando elcd
programa de confianza o alguna otra cosa. Esa es una lata entera de gusanos.O podría tener un
cd
programa que haga que elchdir
sistema llame y comience un nuevo shell con todas las variables de entorno actuales aplicadas al nuevo shell, y luego mate su shell principal (de alguna manera) cuando termine. 1Peor aún, incluso podría tener un sistema en el que un proceso pueda alterar los entornos de otros procesos (creo que técnicamente puede hacerlo con depuradores). Sin embargo, dicho sistema sería muy, muy vulnerable.
Te encontrarás agregando más y más código para asegurar tales métodos, y es considerablemente más simple simplemente hacer que esté incorporado.
Que algo sea un ejecutable no evita que sea un archivo incorporado. Caso en punto:
echo
ytest
echo
ytest
son utilidades con mandato POSIX (/bin/echo
y/bin/test
). Sin embargo, casi todos los depósitos popular tiene una orden internaecho
ytest
. Del mismo modo,kill
también está incorporado que está disponible como un programa. Otros incluyen:sleep
(no tan común)time
false
true
printf
Sin embargo, hay algunos casos en que un comando no puede ser otra cosa que un builtin incorporado. Uno de esos es
cd
. Por lo general, si no se especifica la ruta completa y el nombre del comando coincide con el de un builtin incorporado, se llama a una función adecuada para ese comando. Dependiendo de la shell, el comportamiento del builtin y el del ejecutable puede diferir (esto es particularmente un problema paraecho
, que tiene comportamientos muy diferentes . Si desea estar seguro del comportamiento, es preferible llamar al ejecutable usando el ruta completa y establecer variables comoPOSIXLY_CORRECT
(incluso entonces no hay garantía real).Técnicamente, no hay nada que le impida proporcionar un sistema operativo que también sea un shell y que tenga todos los comandos como incorporado. Cerca de este extremo se encuentra el BusyBox monolítico . BusyBox es un binario único que (según el nombre con el que se llama) puede comportarse como cualquiera de los más de 240 programas , incluido un Shell de Almquist (
ash
). Si desarmaPATH
mientras ejecuta BusyBoxash
, los programas disponibles en BusyBox aún estarán accesibles para usted sin especificar aPATH
. Se acercan a ser construcciones de conchas, excepto que la concha en sí es una especie de construcción para BusyBox.Estudio de caso: The Debian Almquist Shell (
dash
)Si observa el
dash
origen, el hilo de ejecución es algo así (por supuesto, con funciones adicionales involucradas cuando se utilizan tuberías y otras cosas):main
→cmdloop
→evaltree
→evalcommand
evalcommand
luego se usafindcommand
para determinar cuál es el comando. Si es una construcción, entonces :cmdentry.u.cmd
es unstruct
(struct builtincmd
), uno de cuyos miembros es un puntero de función, con una firma típica demain
:(int, char **)
. Laevalbltin
función llama (dependiendo de si eleval
comando incorporado es el comando o no)evalcmd
o este puntero de función. Las funciones reales se definen en varios archivos de origen.echo
, por ejemplo, es :Todos los enlaces al código fuente en esta sección están basados en números de línea, por lo que pueden cambiar sin previo aviso.
1 Los sistemas POSIX tienen un
cd
ejecutable .Nota al margen:
Hay muchas publicaciones excelentes en Unix y Linux que se ocupan del comportamiento de shell. En particular:
cd
comando externo?fuente
cd
texto de ayuda conhelp cd
(lo mismo para todos los comandos integrados de shell)help
es un bash incorporado (para zsh, esrun-help cd
)cd
debe ser un shell integrado ... sino que se basa en cómo funcionan las propiedades del proceso y su transferencia en UNIXcd
como un shell incorporado es la única implementación sencilla. Ver la respuesta de Volker Siegel .No puede encontrar un ejecutable
cd
porque no hay ninguno.cd
es un comando interno de su shell (por ejemplobash
).fuente
de
man which
:Como podemos ver en la descripción de
which
, solo está comprobandoPATH
. Entonces, si implementó algunosbash function
, no le mostrará nada. Es mejor usar eltype
comando junto conwhich
.Por ejemplo, en el
ls
comando Ubuntu con aliasls --color=auto
.Y si implementa la función de prueba
hello
:which
no muestra nada Perotype
:En tu caso:
Esto significa que
cd
es un caparazón incorporado , está dentrobash
. Todos los componentes de bash descritosman bash
en la sección SHELL BUILTIN Commandfuente
manwhich
.which
, usartype
.