Lo intenté which cdy no dio una ruta, sino que devolvió el código de salida 1 (comprobado con echo $?). El coreutil en cdsí está funcionando, por lo que el ejecutable debería estar allí, ¿verdad? También ejecuté un findfor 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

typecomandocddebe ser un programa integrado: ¿Por qué el CD no es un programa? y este sobre por quétypees mejor quewhich: ¿Por qué no usar "which"? ¿Qué usar entonces?Respuestas:
El comando
cdno puede ser un ejecutableEn un shell,
cdse 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.
cdse 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 comandocddebe 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
cdlo 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
whichAhora, la respuesta a la pregunta del título es fácil:
el comando ejecutable
whichno puede decirnos que cd es un comando incorporado porque un comando ejecutable no sabe nada sobre los incorporados.Alternativa
type -aComo 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
cdes un shell incorporado.cdes 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
bashmanual :Supongo que se podría pensar en una arquitectura donde
cdno 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
cdprograma 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 elcdprograma de confianza o alguna otra cosa. Esa es una lata entera de gusanos.O podría tener un
cdprograma que haga que elchdirsistema 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:
echoytestechoytestson utilidades con mandato POSIX (/bin/echoy/bin/test). Sin embargo, casi todos los depósitos popular tiene una orden internaechoytest. Del mismo modo,killtambién está incorporado que está disponible como un programa. Otros incluyen:sleep(no tan común)timefalsetrueprintfSin 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 desarmaPATHmientras 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
dashorigen, 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→evalcommandevalcommandluego se usafindcommandpara determinar cuál es el comando. Si es una construcción, entonces :cmdentry.u.cmdes unstruct(struct builtincmd), uno de cuyos miembros es un puntero de función, con una firma típica demain:(int, char **). Laevalbltinfunción llama (dependiendo de si elevalcomando incorporado es el comando o no)evalcmdo 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
cdejecutable .Nota al margen:
Hay muchas publicaciones excelentes en Unix y Linux que se ocupan del comportamiento de shell. En particular:
cdcomando externo?fuente
cdtexto de ayuda conhelp cd(lo mismo para todos los comandos integrados de shell)helpes un bash incorporado (para zsh, esrun-help cd)cddebe ser un shell integrado ... sino que se basa en cómo funcionan las propiedades del proceso y su transferencia en UNIXcdcomo un shell incorporado es la única implementación sencilla. Ver la respuesta de Volker Siegel .No puede encontrar un ejecutable
cdporque no hay ninguno.cdes 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 eltypecomando junto conwhich.Por ejemplo, en el
lscomando Ubuntu con aliasls --color=auto.Y si implementa la función de prueba
hello:whichno muestra nada Perotype:En tu caso:
Esto significa que
cdes un caparazón incorporado , está dentrobash. Todos los componentes de bash descritosman bashen la sección SHELL BUILTIN Commandfuente
manwhich.which, usartype.