La fragmentación del mercado de Unix ha tenido sus ventajas y desventajas. Las ventajas vinieron principalmente en los primeros días: la falta de estandarización y la proliferación entre académicos y profesionales técnicamente competentes contribuyeron a un <<mercado libre>> saludable para el software de Unix, en el que varios programas del mismo tipo (por ejemplo, shells, editores de texto, herramientas de administración del sistema) a menudo competían por popularidad. Los mejores programas generalmente se volvían más ampliamente utilizados, mientras que el software inferior tendía a desaparecer.

Pero a menudo no había un único programa <<mejor>> en una categoría dada, por lo que varios prevalecían. Esto llevó a la situación actual, donde la multiplicidad de software similar ha llevado a la confusión, la falta de compatibilidad y, lo más desafortunado de todo, a la incapacidad de Unix para capturar una parte tan grande del mercado como otras plataformas operativas. En particular, Unix se ha relegado a su posición actual como un sistema operativo muy popular para servidores, pero es una rareza en las computadoras de escritorio.

La categoría <<shell>> probablemente ha sufrido de esta manera más que cualquier otro tipo de software. Como dijimos en el \hyperref[sec:Prefacio]{Prefacio} y el \hyperref[sec:Chapter1]{Capítulo 1}, una de las fortalezas de Unix es que el shell es reemplazable y, por lo tanto, actualmente hay varios shells disponibles; las diferencias entre ellos a menudo no son tan grandes. Creemos que el shell Korn es uno de los mejores entre los shells más utilizados, pero otros shells ciertamente tienen sus seguidores leales, por lo que no es probable que caigan en el olvido. De hecho, parece que los shells, compatibles con Bourne o no, continúan proliferando.

Por lo tanto, sentimos que era necesario incluir información sobre shells similares al shell Korn. Este apéndice resume las diferencias entre el shell Korn y los siguientes shells:

\begin{itemize}
	\item El Shell de Bourne de System V Release 4, como una especie de referencia.
	\item La versión de 1988 del shell Korn.
	\item El Estándar del shell IEEE POSIX 1003.2, al que se adhieren el shell Korn y otros shells.
	\item El shell Desktop Korn (\emph{dtksh}), un shell Korn con mejoras para programación en el sistema X Window, como parte del Common Desktop Environment (CDE).
	\item El shell \emph{tksh}, una interesante combinación de \emph{ksh93} con Tcl/Tk.
	\item \emph{pdksh}, una versión de dominio público ampliamente utilizada del shell Korn.
	\item El shell \emph{bash}, otro shell mejorado de Bourne con algunas características del shell C y Korn.
	\item El shell Z, \emph{zsh}, otro shell mejorado de Bourne con algunas características de los shells C y Korn y muchas, muchas más características propias en plataformas de PC de escritorio.
	\item Similares al shell Korn en plataformas de PC de sobremesa 
\end{itemize}

\section{El Shell de Bourne}
El shell Korn es casi completamente compatible hacia atrás con el Shell de Bourne. La única característica significativa de este último que el shell Korn no admite es \^{} (acento circunflejo) como sinónimo del carácter pipe (|).\footnote{También hay algunas diferencias en cómo reaccionan los dos shells ante ciertas entradas extremadamente patológicas. Por lo general, el shell Korn procesa correctamente lo que hace que el Shell de Bourne <<se atragante>>.}
Esta es una característica arcaica que el Shell de Bourne incluye por su propia compatibilidad hacia atrás con shells anteriores. Ninguna versión moderna de Unix tiene código de shell que use \^{} como pipe.

Para describir las diferencias entre el Shell de Bourne y el Korn shell, revisaremos cada capítulo de este libro y enumeraremos las características discutidas en el capítulo que el Shell de Bourne no admite.

\begin{enumerate}
	\item \hyperref[sec:Chapter1]{Capítulo 1}
	\begin{itemize}
		\item Las formas \texttt{cd old new} y \texttt{cd -} del comando \emph{cd}.
		\item Expansión de tilde (\texttt{\~{}}).
		\item El Shell de Bourne siempre sigue el diseño físico de archivos, lo que afecta lo que sucede cuando haces \texttt{cd ..} fuera de algún lugar que era un enlace simbólico.
		\item Los comandos incorporados no tienen ayuda en línea.
		\item Algunas versiones antiguas del Shell de Bourne no admiten el comando \emph{jobs} y el control de trabajos, o pueden requerir ser invocadas como \emph{jsh} para habilitar las características de control de trabajos.
	\end{itemize}
	\item \hyperref[sec:Chapter2]{Capítulo 2}
	\begin{itemize}
		\item Todos (es decir, el Shell de Bourne no admite ninguna de las características de historial y edición discutidas en el \hyperref[sec:Chapter2]{Capítulo 2}).
	\end{itemize}
	\item \hyperref[sec:Chapter3]{Capítulo 3}
	\begin{enumerate}
		\item No se admiten alias.
		\item Las opciones \texttt{set -o} no funcionan. El Shell de Bourne admite las abreviaturas enumeradas en la tabla de <<Opciones>> en el \hyperref[sec:ApendiceB]{Apéndice B}, excepto \emph{-A, -b, -C, -m, -p} y \emph{-s}.
		\item No se admiten archivos de entorno; tampoco el comando \emph{print} (usa echo en su lugar). Las siguientes variables internas no se admiten:

\begin{table}[h]
	\center
	\begin{tabular}{|m{2.5cm}|m{2.5cm}|m{4cm}|m{2.5cm}|m{2.5cm}|} \\
		\hline
		.sh.edchar & .sh.version & HISTEDIT & LINENO & PS4 \\\hline
		.sh.edcol & COLUMNS & HISTFILE & LINES & PWD \\\hline
		.sh.edmode & EDITOR & HISTSIZE & OLDPWD & PWD \\\hline
		.sh.edtext & ENV & LANG & OPTARG & RANDOM \\\hline
		.sh.match & FCEDIT & LC\_ALL & OPTIND & SECONDS \\\hline
		.sh.name & FIGNORE & LC\_COLLATE & PPID & TMOUT \\\hline
		.sh.subscript & FPATH & LC\_CTYPE & PS3 & VISUAL \\\hline
		.sh.value & HISTCMD & LC\_NUMERIC & & \\\hline
	\end{tabular}
\end{table}

	\item Algunas de estas variables (por ejemplo, \texttt{EDITOR} y \texttt{VISUAL}) aún son utilizadas por otros programas, como \emph{mail} y noticias.
	\end{enumerate}
	\item \hyperref[sec:Chapter4]{Capítulo 4}
	\begin{itemize}
		\item No están disponibles los nombres de variables extendidas (aquellas con un punto en ellas), así como la asignación de variables compuestas y la concatenación de cadenas con el operador +=.
		\item No se admiten variables indirectas (referencias de nombres).
		\item No está disponible el comando \emph{whence}; usa type en su lugar.
		\item Los operadores variables de coincidencia de patrones (\%, \%\%, \#, \#\#, etc.) y los caracteres comodín avanzados (expresión regular) no están disponibles; usa el comando externo \emph{expr} en su lugar.
		\item No se admiten funciones cargadas automáticamente, y solo se pueden usar funciones de estilo POSIX (definidas utilizando la sintaxis \emph{name()}).
		\item La sintaxis de sustitución de comandos es diferente: utilice el antiguo \texttt{`command`} en lugar de \texttt{\$(command)}. (Algunos proveedores han mejorado sus shells Bourne para que admitan la notación \texttt{\$(comando)}, ya que está definida por el estándar POSIX). 
	\end{itemize}
	\item \hyperref[sec:Chapter5]{Capítulo 5}
	\begin{itemize}
		\item \texttt{return} solo se puede usar desde dentro de una función.
		\item Las pruebas condicionales utilizan la sintaxis antigua: \texttt{[ condición ]} o \texttt{test condición} en lugar de \texttt{[[ condición ]]}. Estas son realmente dos formas del mismo comando (consulta la página de manual de \emph{test(1)}).
		\item Los operadores lógicos \&\& y || son \texttt{-a} y \texttt{-o} en su lugar. Los operadores de prueba admitidos difieren de un sistema a otro.\footnote{En la Bourne Shell original de la Versión 7 (y en sistemas Unix de Berkeley hasta 4.3BSD), \emph{test} y \texttt{[ condición ]} eran en realidad comandos externos. (Eran enlaces duros entre sí en \emph{/bin}.) Sin embargo, se integraron en el Shell de Bourne en todos los sistemas desde System III (circa 1981).}
	\item La palabra clave ! para invertir el estado de salida de un comando no estaba en el Shell de Bourne de SVR4, aunque puede estar disponible en tu sistema, ya que es requerida por POSIX.
	\item No se admite la construcción \texttt{select}. Tampoco el bucle \texttt{for} aritmético, y no hay forma de pasar de un caso a otro dentro de una declaración \texttt{case}.
	\item No hay un equivalente para \texttt{TMOUT}.
	\end{itemize}
	\item \hyperref[sec:Chapter6]{Capítulo 6}
	\begin{itemize}
		\item El comando getopts del Shell de Bourne de SVR4 es similar, pero no idéntico, al de \emph{ksh}. No permite opciones que comienzan con un signo más, ni ninguna de las características avanzadas descritas en el \hyperref[sec:ApendiceB]{Apéndice B}.
		\item No se admite la aritmética: usa el comando externo \emph{expr} en lugar de la sintaxis \texttt{\$((...))}. Para condicionales numéricas, usa la antigua sintaxis de prueba de condición y los operadores relacionales \texttt{-lt, -eq}, etc., en lugar de \texttt{((...))}. No se admite \emph{let}.
		\item No se admiten variables de matriz y el comando \emph{typeset}.
	\end{itemize}
  	\item \hyperref[sec:Chapter7]{Capítulo 7}
  	\begin{itemize}
		\item No se admiten los siguientes redireccionadores de E/S\footnote{El operador \texttt{<>} estaba en el Shell de Bourne original de la Versión 7, pero no estaba documentado, ya que no siempre funcionaba correctamente en todos los sistemas Unix. No se debe depender de su disponibilidad para la programación de Shell de Bourne.}:
\begin{table}[h]
	\center
	\begin{tabular}{|m{1cm}|m{1cm}|m{1cm}|m{1cm}|m{1cm}|m{1cm}|m{1cm}|m{1cm}|} \\\hline
		\texttt{>|} & \texttt{<>} & \texttt{<<<} & \texttt{<\&p} & \texttt{>\&p} & \texttt{<\&n-} & \texttt{>\&n-} & \texttt{|\&} \\\hline
	\end{tabular}
\end{table}
	\item No se admite \emph{print} (usa \emph{echo} en su lugar). \emph{printf} generalmente está disponible como un comando externo.
	\item Ninguna de las opciones de \emph{read} es compatible, ni la capacidad de proporcionar un indicador con el nombre de la primera variable.
	\item El Shell de Bourne no hace interpretaciones especiales de rutas, como \texttt{/dev/fd/2} o \texttt{/dev/tcp/ftp.oreilly.com/ftp}.
	\item Los mecanismos de cotización \texttt{\$"..."} y \texttt{\$'...'} no están disponibles.
	\end{itemize}
	\item \hyperref[sec:Chapter8]{Capítulo 8}
	\begin{itemize}
		\item Se admite el control de trabajos, pero solo si el shell se invoca con la opción \texttt{-j} o como \emph{jsh}.
		\item La opción \texttt{-} a trap (restablecer trap al valor predeterminado para esa señal) no está disponible. En su lugar, la falta de un trap indica que se deben restablecer las trampas suministradas. \emph{trap} acepta solo números de señales, no nombres lógicos.
		\item No se admiten las corutinas.
		\item El comando \emph{wait} solo acepta identificadores de procesos.
	\end{itemize}
	\item \hyperref[sec:Chapter9]{Capítulo 9}
	\begin{itemize}
		\item Las señales ERR y DEBUG no están disponibles. La señal EXIT es compatible, como la señal 0.
		\item \texttt{set -n} tiene efecto incluso en shells interactivos.
		\item La salida de la traza con \texttt{set -x} no se puede personalizar (no hay variable \texttt{PS4}).
		\item Las funciones de disciplina no están disponibles.
	\end{itemize}
	\item \hyperref[sec:Chapter10]{Capítulo 10}
	\begin{itemize}
		\item No se admite el modo privilegiado (algunos shells Bourne lo tienen).
		\item Los comandos \emph{ulimit} y \emph{umask} no son tan capaces.
		\item No está disponible la trampa \texttt{KEYBD}.
	\end{itemize}
\end{enumerate}

\section{El Shell Korn de 1988}
Quizás el shell más evidente con el que comparar \emph{ksh93} sea \emph{ksh88}, la versión de 1988 del shell Korn. Esta sección describe brevemente aquellas características de \emph{ksh93} que son diferentes o inexistentes en \emph{ksh88}. Al igual que con la presentación para el shell Bourne, los temas se cubren en el mismo orden en que se presentan en el resto del libro.

\begin{enumerate}
	\item \hyperref[sec:Chapter1]{Capítulo 1}
	\begin{itemize}
		\item Las facilidades de ayuda integradas (como \emph{-?}, \emph{--man}, y así sucesivamente) no están disponibles.
		\item La sustitución de tilde no ocurre durante la expansión de variables (\texttt{\$\{var op word\}}).
	\end{itemize}
	\item \hyperref[sec:Chapter2]{Capítulo 2}
	\begin{itemize}
		\item CTRL-T funciona de manera diferente en el modo de edición emacs. En \emph{ksh88}, transpone los dos caracteres a la derecha del punto e mueve el punto hacia adelante en un carácter.
		\item En el modo emacs, ESC ESC, ESC *, y ESC = no funcionan en la primera palabra de una línea de comando, es decir, no hay una facilidad de autocompletado de comandos. El comando ESC \# siempre antepone un carácter \#. Nunca los elimina.
		\item De manera similar, en el modo \emph{vi}, los comandos *, \textbackslash{} y = no funcionan en la primera palabra de una línea de comando, y el comando \# siempre antepone un carácter \#. Nunca los elimina.
		\item Finalmente, no hay autocompletado de variables, el comando \emph{hist} se llama \emph{fc}, \texttt{FCEDIT} se usa en lugar de \texttt{HISTEDIT}, y la variable \texttt{HISTCMD} no está disponible.
	\end{itemize}
	\item \hyperref[sec:Chapter3]{Capítulo 3}
	\begin{itemize}
		\item El archivo \texttt{ENV} se carga para todos los shells, y \emph{ksh88} solo realiza la sustitución de variables en el valor de \texttt{\$ENV}.
		\item El seguimiento de alias se puede desactivar en \emph{ksh88}.
		\item La opción \texttt{-p} para alias no está presente en \emph{ksh88}, al igual que la opción \texttt{-a} para unalias.
		\item Las siguientes variables internas no son compatibles:
\begin{table}[h]
	\center
	\begin{tabular}{|m{2cm}|m{2cm}|m{2cm}|m{2cm}|} \\\hline
		.sh.edchar & .sh.match & .sh.version & LANG \\\hline
		.sh.edcol & .sh.name & FIGNORE & LC\_ALL \\\hline
		.sh.edmode & .sh.subscript & HISTCMD & LC\_COLLATE \\\hline
		.sh.edtext & .sh.value & HISTEDIT & LC\_CTYPE \\\hline
	\end{tabular}
\end{table}
	\end{itemize}
	\item \hyperref[sec:Chapter4]{Capítulo 4}
	\begin{itemize}
		\item En \emph{ksh88}, ambas sintaxis para definir funciones producen funciones con semántica de shell Korn. No puedes aplicar el comando dot a un nombre de función.
		\item El orden de búsqueda de comandos en \emph{ksh88} es palabras clave, aliases, todos los comandos internos, funciones, y luego comandos externos y scripts. El orden fue cambiado en \emph{ksh93} para cumplir con POSIX.
		\item En \emph{ksh88}, las funciones no definidas (\emph{autoloaded}) se buscan exclusivamente a lo largo de la lista en la variable \texttt{FPATH}, y \texttt{PATH} no está involucrado.
		\item La característica del archivo \emph{.paths} no está disponible.
		\item Muchas de las características de sustitución de variables descritas en el texto principal son nuevas en \emph{ksh93}. Solo las siguientes están disponibles en \emph{ksh88}: \texttt{\$\{name:-string\}, \$\{name:=string\}, \$\{name:?string\}, \$\{name:+string\}, \$\{name\#pattern\}, \$\{name\#\#pattern\}, \$\{name\%pattern\}, \$\{name\%\%pattern\}, \$\{\#name\}, \$\{\#name[*]\}}, y \texttt{\$\{\#name[@]\}}.
		\item Variables compuestas, namerefs y el operador += para agregar a una variable no están en \emph{ksh88}.
		\item La notación \textbackslash{}n en patrones no está disponible, al igual que la coincidencia no codiciosa, el uso de escapes de barra invertida en patrones, opciones en subpatrones, ni ninguna de las clases de caracteres [:...:].
		\item El array \texttt{.sh.match} no está disponible.
	\end{itemize}
	\item \hyperref[sec:Chapter5]{Capítulo 5}
	\begin{itemize}
		\item Los valores de salida en \emph{ksh88} solo llegan hasta 128. Los programas que mueren debido a una señal tienen un estado de salida de 128 más el número de señal.
		\item No hay un \emph{comando} built-in. Para reemplazar un built-in, debes usar una combinación incómoda de alias, funciones y citas.
		\item La opción \texttt{set -o pipefail} y la palabra clave ! para invertir el sentido de una prueba no están disponibles. En lugar del operador \texttt{==} para \texttt{[[...]]}, \emph{ksh88} usa \texttt{=}.
		\item El bucle \texttt{for} aritmético no está en \emph{ksh88}. El uso de \texttt{;\&} para pasar de un caso a otro existía en \emph{ksh88} pero no estaba documentada. La variable \texttt{TMOUT} existía en \emph{ksh88}, pero solo se aplicaba al shell en sí, no al bucle \texttt{select} o al comando \texttt{read}.
	\end{itemize}
	\item \hyperref[sec:Chapter6]{Capítulo 6}
	\begin{itemize}
		\item La versión de getopts de \emph{ksh88} no tenía la capacidad de especificar argumentos numéricos para opciones, ni una forma de especificar argumentos opcionales para opciones.
		\item La aritmética integrada solo admite enteros, y los operadores ++, --, ?: y coma no están disponibles. Las constantes numéricas de la forma \texttt{base\#número} solo pueden llegar hasta la base 36. No hay funciones aritméticas integradas.
		\item Solo existen arrays indexados, y el índice máximo es 1023.
	\end{itemize}
	\item \hyperref[sec:Chapter7]{Capítulo 7}
	\begin{itemize}
		\item No se admiten los siguientes redireccionadores de E/S:
		\begin{itemize}
			\item \texttt{<\&n-}
			\item \texttt{>\&n-}
			\item \texttt{<<<}
		\end{itemize}
	\item La red de TCP/IP está disponible a partir de \emph{ksh88e}, pero debes usar direcciones IP.
	\item \emph{ksh88} no tiene el comando \emph{printf}, ni las opciones \texttt{-A, -d, -n} y \texttt{-t} para \emph{read}. \texttt{TMOUT} no afecta a \emph{read}.
	\item La expansión de llaves y la sustitución de procesos son opciones de tiempo de compilación que generalmente no están disponibles en \emph{ksh88}.
	\item La traducción de locales con \texttt{\$"..."} y las cadenas ANSI C con \texttt{\$'...'} no están disponibles.
	\end{itemize}
	\item \hyperref[sec:Chapter8]{Capítulo 8}
	\begin{itemize}
		\item El comando \emph{disown} no está disponible, y tampoco las opciones \texttt{-n} y \texttt{-s} para \emph{kill}. \texttt{kill -l} solo se puede usar por sí mismo para enumerar las señales disponibles.
		\item \emph{true} y \emph{false} son alias predefinidos en lugar de comandos internos.
		\item Las funciones y los alias se exportan a los subprocesos del shell; esto no es cierto en \emph{ksh93}.
	\end{itemize}
	\item \hyperref[sec:Chapter9]{Capítulo 9}
	\begin{itemize}
		\item Las trampas para la señal falsa DEBUG se ejecutan \emph{después} de que se ejecuta cada comando, no antes.
		\item Las funciones de disciplina no están disponibles.
	\end{itemize}
	\item \hyperref[sec:Chapter10]{Capítulo 10}
	\begin{itemize}
		\item El comando \emph{umask} solo funciona con máscaras octales.
		\item No puedes personalizar los editores integrados; la señal falsa KEYBD no existe.
	\end{itemize}
\end{enumerate}

\section{El Estándar del Shell POSIX IEEE 1003.2}
Ha habido muchos intentos de estandarizar Unix. Los intentos monolíticos de dominación del mercado por parte de empresas de hardware, frágiles coaliciones industriales, fallas de marketing y otros esfuerzos por el estilo son parte de la historia, y también de la frustración.

Solo un esfuerzo de estandarización no ha estado vinculado a intereses comerciales: la Interfaz Portátil del Sistema Operativo, conocida como POSIX. Este esfuerzo comenzó en 1981 con el Comité de Normas de \texttt{/usr/group} (ahora UniForum), que produjo la Norma de \texttt{/usr/group} tres años después. La lista de contribuyentes creció. Con el tiempo, el esfuerzo por crear un estándar formal se trasladó bajo el paraguas del Instituto de Ingenieros Eléctricos y Electrónicos (IEEE) y la Organización Internacional de Normalización (ISO).

El primer estándar POSIX se publicó en 1988 y se revisó en 1996. Este, llamado Estándar IEEE 1003.1, abordaba problemas a nivel de llamadas al sistema. El Estándar IEEE 1003.2, que cubre el shell, programas de utilidad y problemas de interfaz de usuario, fue ratificado en septiembre de 1992 después de seis años de esfuerzo. En septiembre de 2001, se aprobó una revisión conjunta de ambos estándares. El nuevo estándar, que cubre todo el material de los dos documentos anteriores, se conoce como Estándar IEEE 1003.1-2001.

Los estándares POSIX nunca se pensaron como rígidos y absolutos. Los miembros del comité ciertamente no iban a poner armas en la cabeza de los implementadores del sistema operativo y obligarlos a adherirse. En cambio, los estándares están diseñados para ser lo suficientemente flexibles como para permitir tanto la coexistencia de software similar disponible, para que el código existente no esté en peligro de volverse obsoleto, como la adición de nuevas características, para que los proveedores tengan incentivos para innovar. En otras palabras, se supone que son el tipo de estándares de terceros que los proveedores podrían estar interesados en seguir.

Como resultado, la mayoría de los proveedores de Unix cumplen actualmente con ambos estándares. El shell Korn no es una excepción; se pretende que sea 100\% compatible con POSIX. Conviene estar familiarizado con lo que hay en el estándar si quieres escribir código que sea portable en diferentes sistemas.

La parte del shell del estándar describe utilidades que deben estar presentes en todos los sistemas y otras que son opcionales, según la naturaleza del sistema. Una de esas opciones es la opción de Utilidades de Portabilidad del Usuario, que define estándares para el uso interactivo del shell y utilidades interactivas como el editor vi. El estándar, de aproximadamente 2000 páginas, está disponible a través del IEEE; para obtener información, ponte en contacto con el IEEE:

\newpage

\begin{footnotesize}
\singlespace
IEEE Customer Service \\
445 Hoes Lane, PO Box 1331 \\
Piscataway, NJ 08855-1331 \\
(800) 678-IEEE (Estados Unidos y Canadá) \\
(732) 981-0060 (internacional/local) \\
(732) 981-9667 (fax)

customer.service@ieee.org \\
\url{http://www.standards.ieee.org/catalog/ordering.html}
\end{footnotesize}

Los miembros del comité tenían dos factores motivadores que considerar cuando diseñaron el estándar del shell. Por un lado, el diseño debía acomodar, tanto como fuera posible, el código del shell existente escrito bajo varios shells derivados de Bourne (Version 7, System V, BSD y Korn). Estos shells son diferentes de varias maneras extremadamente sutiles, la mayoría de las cuales tienen que ver con la forma en que ciertos elementos sintácticos interactúan entre sí.

Debe haber sido bastante difícil y tedioso especificar estas diferencias, sin mencionar llegar a compromisos entre ellas. Agrega los sesgos de algunos miembros del comité hacia shells particulares, y podrías entender por qué llevó seis años ratificar el primer estándar 1003.2 y otros cinco años para fusionar los dos estándares.

Por otro lado, el diseño del shell debía servir como estándar en el que basar futuras implementaciones de shell. Esto implicaba objetivos de simplicidad, claridad y precisión, objetivos que parecen especialmente esquivos en el contexto de los problemas mencionados anteriormente.

Los diseñadores encontraron una manera de aliviar este dilema: decidieron que el estándar debería incluir no solo las características incluidas en el shell, sino también aquellas explícitamente omitidas y aquellas incluidas pero con funcionalidad no especificada. La última categoría permite que algunas innovaciones de shells existentes <<se cuelen>> sin formar parte del estándar, mientras que listar las características omitidas ayuda a los programadores a determinar qué características en los scripts de shell existentes no serán portables a los shells futuros.

El estándar POSIX se basa principalmente en el shell Bourne de System V. Por lo tanto, debes asumir que las características del shell Korn que no están presentes en el shell Bourne tampoco están incluidas en el estándar POSIX.

Sin embargo, el shell Korn contribuyó con algunas de sus características al estándar POSIX, incluyendo:

\begin{itemize}
	\item Sintaxis \texttt{\$((...))} para expresiones aritméticas.
	\item Sintaxis \texttt{\$(...)} para sustitución de comandos, excepto que la abreviatura \texttt{\$(< filename)} para \texttt{\$(cat filename)} no está soportada.
	\item Expansión de tilde (originalmente derivada del shell C).
\end{itemize}

Las siguientes características del shell Korn se dejan <<no especificadas>> en el estándar, lo que significa que su sintaxis es aceptable pero su funcionalidad no está estandarizada:

\begin{itemize}
	\item Sintaxis \texttt{((...))} para condicionales aritméticos. Sin embargo, se incluyen los operadores de prueba aritmética introducidos en el \hyperref[sec:Chapter5]{Capítulo 5} (por ejemplo, \texttt{-eq, -lt}).
	\item La sintaxis \texttt{[[...]]} para \emph{pruebas} condicionales. Debe usarse el comando de \emph{prueba} externo o \texttt{[...]} en su lugar. La versión del shell Korn de la prueba cumple con POSIX cuando se usa con no más de tres argumentos. (También cumple con cuatro argumentos, si el primer argumento es !).
	\item La sintaxis para definir funciones que usa este libro. La otra sintaxis mostrada en el \hyperref[sec:Chapter4]{Capítulo 4} (\texttt{fname()} en lugar de \texttt{function fname}) se admite, con lo que describimos como <<semántica POSIX>>; ver más abajo.
	\item La estructura de control \texttt{select}.
	\item Solo se permiten números de señal si los números para ciertas señales clave (INT, TERM y algunas otras) son iguales que en las versiones históricas más importantes de Unix. En general, los scripts de shell deben usar nombres simbólicos para las señales.
\end{itemize}

El estándar POSIX admite funciones, pero la semántica es más débil que la de las funciones de estilo de \texttt{function} del shell Korn: las funciones no tienen trampas u opciones locales, y no es posible definir variables locales. (Por esta razón, \emph{ksh93} tiene dos sintaxis diferentes para definir funciones, con semánticas diferentes).

Se admiten bloques de código (\texttt{\{...;\}}). Para obtener máxima portabilidad, cuando desees llaves literales, debes entrecomillarlas (por razones demasiado complicadas para entrar aquí).

El estándar POSIX introdujo las siguientes características, que difieren del comportamiento tradicional del shell Bourne. \emph{ksh93} las admite todas:

\begin{itemize}
	\item Se cambió el orden de búsqueda de comandos para permitir que ciertos comandos integrados sean anulados por funciones, ya que los alias no están incluidos en el estándar. Los comandos integrados se dividen en dos conjuntos según su posición en el orden de búsqueda de comandos: algunos se procesan antes que las funciones, otros después. Específicamente, los comandos integrados \emph{break}, : (no hacer nada), \emph{continue}, . (dot), \emph{eval, exec, exit, export, readonly, return, set, shift, trap,} y \emph{unse}t tienen prioridad sobre las funciones.
	\item Un nuevo comando integrado, \emph{command}, te permite usar comandos integrados que no están en la lista anterior incluso si hay funciones con el mismo nombre. \footnote{Pero ten en cuenta que no es un comando integrado especial. Aquí se nota el diseño por comité.}
	\item Una nueva palabra clave, !, toma la negación lógica del estado de salida de un comando: si \emph{command} devuelve un estado de salida 0, \texttt{! command} devuelve 1; si \emph{comand} devuelve un valor no nulo, \texttt{! command} devuelve 0. ! se puede usar con \texttt{\&\&}, ||, y paréntesis (para subcadenas anidadas) para crear combinaciones lógicas de estados de salida en condicionales.
	\item El comando \texttt{unset -v} se utiliza en lugar de \texttt{unset} (sin una opción) para eliminar la definición de una variable. Esto proporciona una mejor coincidencia sintáctica con \texttt{unset -f}, para deshacer la definición de funciones.
\end{itemize}

Finalmente, debido a que el estándar POSIX está destinado a promover la portabilidad de scripts de shell, evita mencionar explícitamente características que solo se aplican al uso interactivo del shell, incluidos alias, modos de edición, teclas de control, y así sucesivamente. La opción de Utilidades de Portabilidad del Usuario cubre estos. También evita mencionar ciertos problemas clave de implementación: en particular, no hay requisito de que se use la multitarea para trabajos en segundo plano, subcadenas, etc. Esto se hizo para permitir la portabilidad a sistemas no multitarea como MS-DOS, de modo que, por ejemplo, el Toolkit MKS (ver más adelante en este apéndice) pueda ser compatible con POSIX.

\section{dtksh}
El Desk Top Korn Shell (\emph{dtksh}) es una parte estándar del \emph{Common Desktop Environment (CDE)}, disponible en sistemas Unix comerciales como Solaris, HP-UX y AIX. Está basado en una versión algo más antigua de \emph{ksh93}. Evolucionó a partir del programa anterior \emph{wksh}, el Windowing Korn shell, lanzado por Unix System Laboratories a fines de 1992. Es un Korn shell completo, compatible con la versión que describe este libro,\footnote{Las características enumeradas a lo largo del libro como introducidas en versiones <<recientes>> no estarán en \emph{dtksh}.}
y tiene extensiones para la programación de interfaces gráficas de usuario (GUI) en el entorno del sistema X Window. Se encuentra típicamente en \texttt{/usr/dt/bin/dtksh}.

\emph{dtksh} admite el Toolkit gráfico OSF/Motif al poner sus rutinas a disposición como comandos integrados. Esto permite a los programadores combinar la fortaleza del Korn shell como un entorno de programación de sistemas Unix con el poder y la abstracción del Toolkit. El resultado es un entorno unificado para el desarrollo rápido y sencillo de software basado en gráficos.

Existen varias herramientas de desarrollo de GUI que permiten construir interfaces de usuario con un editor basado en gráficos en lugar de con código de lenguaje de programación. Pero tales herramientas suelen ser enormes, costosas y complejas. \emph{dtksh}, por otro lado, es económico e insuperable en cuanto a su integración suave con Unix; ¡es la única herramienta de este tipo que puedes usar como tu shell de inicio de sesión! (Bueno, casi; consulta la siguiente sección). Es una opción definitiva para los programadores de sistemas que utilizan estaciones de trabajo basadas en X y necesitan una herramienta de prototipado rápido.

Para darte una idea del código \emph{dtksh}, aquí tienes un script que implementa el programa canónico <<Hola, mundo>> mostrando una pequeña ventana con un botón <<Aceptar>>. Es del artículo \emph{Graphical Desktop Korn Shell}, en el número de julio de 1998 de Linux Journal, escrito por George Kraft IV. (Ver \url{http://www.linuxjournal.com/article.php?sid=2643}.) Este código no debería tener sorpresas para los programadores de X y Motif:

\begin{lstlisting}[language=bash]
#!/usr/dt/bin/dtksh

XtInitialize TOPLEVEL dtHello DtHello "$@"
XmCreateMessageDialog HELLO $TOPLEVEL hello \
		dialogTitle:"DtHello" \
		messageString:"$(print "Hola\nMundo")"
XmMessageBoxGetChild HELP $HELLO \
		DIALOG_HELP_BUTTON
XtUnmanageChild $HELP
XmMessageBoxGetChild CANCEL $HELLO \
		DIALOG_CANCEL_BUTTON
XtUnmanageChild $CANCEL
XtAddCallback $HELLO okCallback exit
XtManageChild $HELLO
XtMainLoop
\end{lstlisting}

\url{http://www.cactus.org/~gk4/kraft/george/papers/dtksh/} es la presentación web del Sr. Kraft sobre \emph{dtksh}.

El siguiente libro está dedicado a \emph{dtksh}: \emph{Desktop KornShell Graphical Programming} de J. Stephen Pendergast, Jr., publicado por Addison-Wesley, 1995 (ISBN: 0-201-63375-2). Los ejemplos del libro están disponibles en línea en \url{ftp://ftp.aw.com/aw.prof.comp.series/pendergrast.examples.tar.Z}. También está disponible \url{ftp://ftp.aw.com/aw.prof.comp.series/pend.dtksh1}, un archivo de texto que proporciona una descripción general del libro. Lamentablemente, al momento de escribir esto, este libro está fuera de impresión.

\section{tksh}
En 1996, mientras era estudiante de posgrado en informática en la Universidad de Princeton, el Dr. Jeffrey L. Korn \footnote{Sí, el hijo de David Korn. Ahora trabaja en el mismo centro de investigación que su padre en AT\&T Laboratories, aunque en un área diferente.}
escribió \emph{tksh}. Esta es una integración de \emph{ksh93} con Tcl/Tk. La siguiente cita (de la página web de investigación del Dr. Korn) lo resume bien:

\emph{Tksh} es un lenguaje gráfico (similar a Visual Basic o Tcl/Tk) que utiliza KornShell (\emph{ksh93}) para la creación de scripts y Tk para la interfaz gráfica de usuario. Tksh está implementado como una extensión de \emph{ksh93} y permite que las bibliotecas de Tcl, como Tk, se ejecuten sobre \emph{ksh93} sin cambios. \emph{ksh93} es adecuado para la creación de scripts gráficos porque es compatible con \emph{sh}, lo que facilita tanto el aprendizaje como la extensión de scripts existentes para proporcionar una interfaz de usuario. Tksh también permite que los scripts de Tcl se ejecuten sin modificaciones, lo que hace posible combinar componentes escritos en Tcl o \emph{ksh93}.

La página de inicio de \emph{tksh} todavía está en Princeton: \url{http://www.cs.princeton.edu/\~{}jlk/tksh/}. Tiene enlaces a documentos y documentación que se pueden descargar e imprimir. Sin embargo, el enlace a los ejecutables de \emph{tksh} está desactualizado. El código fuente de \emph{tksh} está disponible en AT\&T Research como parte del paquete ast-open, que también contiene \emph{ksh93} y reimplementaciones de muchas otras herramientas de Unix. Consulta el \hyperref[sec:ApendiceC]{Apéndice C} para obtener más información.

El siguiente script de ejemplo, del artículo de USENIX sobre \emph{tksh}, se llama \emph{watchdir}:

\begin{lstlisting}[language=bash]
# Demo de Tksh
# Jeff Korn
#
# Este script realiza un seguimiento de los directorios visitados y muestra los archivos
# en el directorio actual. Puedes hacer doble clic en archivos y
# directorios. El script debe usarse de manera interactiva, así que para ejecutar:
#   $ tksh
#   $ . scripts/watchdir

function winsetup {
	pack $(frame .f)
	frame .f.dirname -relief raised -bd 1
	pack .f.dirname -side top -fill x
	pack $(frame .f.ls) $(frame .f.dirs) -side left
	label .f.dirname.label -text "Directorio actual: "
	label .f.dirname.pwd -textvariable PWD
	pack .f.dirname.label .f.dirname.pwd -side left

	scrollbar .f.ls.scroll -command ".f.ls.list yview"
	listbox .f.ls.list -yscroll ".f.ls.scroll set" -width 20 -setgrid 1
	pack $(label .f.ls.label -text "Contenido del directorio") -side top
	pack .f.ls.list .f.ls.scroll -side left -fill y -expand 1

	scrollbar .f.dirs.scroll -command ".f.dirs.list yview"
	listbox .f.dirs.list -yscroll ".f.dirs.scroll set" -width 20 -setgrid 1
	pack $(label .f.dirs.label -text "Directorios visitados") -side top
	pack .f.dirs.list .f.dirs.scroll -side left -fill y -expand 1
	bind .f.dirs.list "" 'cd $(selection get)'
	bind .f.ls.list "" 'tkfileselect $(selection get)'
}

function tkfileselect {
	[[ -d "$1" ]] && tkcd "$1"
	[[ -f "$1" ]] && ${EDITOR-${VISUAL-emacs}} "$1"
}

function tkcd {
	cd $1 > /dev/null || return
	.f.ls.list delete 0 end
	set -o markdirs
	.f.ls.list insert end .. *
	[[ ${VisitedDir["$PWD"]} == "" ]] && .f.dirs.list insert end "$PWD"
	VisitedDir["$PWD"]=1
}

typeset -A VisitedDir
winsetup > /dev/null
alias cd=tkcd
tkcd .
\end{lstlisting}

Lo interesante de \emph{tksh}, además de la interesante combinación de tecnologías complementarias, es que lleva la programación Tk al nivel del shell. La programación gráfica con Tk es mucho más elevada que con el kit de herramientas Motif; por lo tanto, la curva de aprendizaje es más fácil de superar y los scripts son más fáciles de leer y escribir.

\section{pdksh}
Muchos de los sistemas tipo Unix de código abierto, como GNU/Linux, vienen con el Public Domain Korn Shell, \emph{pdksh}. \emph{pdksh} está disponible como código fuente; comienza en su página de inicio: \url{http://www.cs.mun.ca/\~{}michael/pdksh/}. Incluye instrucciones para la construcción e instalación en varias plataformas Unix.

\emph{pdksh} fue originalmente escrito por Eric Gisin, quien lo basó en el clon de dominio público del shell Bourne de la Versión 7 creado por Charles Forsyth. Es en su mayoría compatible con el Korn shell de 1988 y POSIX, con algunas extensiones propias.

Su modo de edición en \emph{emacs} es en realidad más potente que el del Korn shell de 1988. Al igual que el editor Emacs completo, puedes personalizar las teclas que invocan comandos de edición (conocidos como \emph{key bindings} en la terminología de Emacs). Los comandos de edición tienen nombres completos que puedes asociar con teclas mediante el uso del comando \emph{bind}.

Por ejemplo, si quieres configurar CTRL-U para hacer lo mismo que CTRL-P (es decir, retroceder al comando anterior en el archivo de historial), podrías poner este comando en tu \emph{.profile}:

\begin{lstlisting}[language=bash]
bind '^U'=up-history
\end{lstlisting}

Incluso puedes configurar secuencias de escape de dos caracteres, que (por ejemplo) te permiten usar las teclas de flecha ANSI además de caracteres de control, y puedes definir \emph{macros}, es decir, abreviaturas para secuencias de comandos de edición.

Las características adicionales del Public Domain Korn Shell incluyen comodines de \emph{alternancia} (tomados del C shell) y notación de tilde definible por el usuario, en la que puedes configurar \~{} como una abreviatura para cualquier cosa, no solo nombres de usuario. También hay algunas diferencias sutiles en la evaluación de expresiones enteras y en la creación de alias.

\emph{pdksh} carece de las siguientes características de la versión oficial:

\begin{itemize}
	\item La variable integrada \texttt{LINES}.
	\item La señal falsa \texttt{DEBUG}.
	\item Las señales falsas \texttt{ERR} y \texttt{EXIT} dentro de funciones.
	\item Las funciones heredan la configuración de traps del script principal.
	\item Las clases de caracteres de expansión de archivos POSIX (\texttt{[[:alpha:]]}, etc.) no están disponibles.
	\item El comando \emph{read} y el bucle \emph{select} no utilizan los modos de edición de línea de comandos.
	\item El último comando de una canalización no se ejecuta en el shell principal. Por lo tanto, \texttt{echo hi | read x; print \$x} no funciona igual que en \emph{ksh}. (La mayoría de los shells de estilo Bourne funcionan de esta manera).
	\item La forma de opción \texttt{set -o} de \emph{ksh} es \texttt{set -X option} en \emph{pdksh}.
\end{itemize}

Aunque carece de la mayoría de las extensiones de \emph{ksh93}, \emph{pdksh} es una alternativa valiosa a los shells C y Bourne.

\section{bash}
\emph{bash} es probablemente el shell <<tercerizado>> más popular disponible para Unix y otros sistemas. En particular, es el shell predeterminado en sistemas GNU/Linux (también se incluye en el CD <<freeware>> con Solaris 8). Puedes obtenerlo desde Internet, a través de FTP anónimo en \url{ftp.gnu.org} en el directorio \texttt{/pub/gnu/bash}. También puedes pedirlo a su fabricante en la dirección que se indica aquí.

\begin{footnotesize}
\singlespace
The Free Software Foundation \\
59 Temple Place - Suite 330 \\
Boston, MA 02111-1307 \\
(617) 542-2652 \\ 
(617) 542-5942 (fax) \\
gnu@gnu.org \\
\url{http://www.gnu.org} \\
\end{footnotesize}

\emph{Bash} fue escrito por Brian Fox y Chet Ramey. Chet Ramey es el actual mantenedor. Su nombre está en línea con la predilección de la FSF por los juegos de palabras: significa Bourne-Again Shell. Aunque \emph{bash} está fácilmente disponible y no tienes que pagar por ello (además del costo de los medios, llamadas telefónicas, etc.), no es realmente un software de dominio público. Mientras que el software de dominio público no tiene restricciones de licencia, el software de la FSF sí las tiene. Pero esas restricciones son diametralmente opuestas a las de una licencia comercial:\footnote{En consecuencia, el documento que detalla estas restricciones se llama \emph{copyleft}.}
¡en lugar de acordar no distribuir el software más, acuerdas no impedir que se distribuya más! En otras palabras, disfrutas del uso ilimitado del software siempre y cuando aceptes no obstaculizar que otros hagan lo mismo. Richard Stallman, el fundador de la FSF, inventó este concepto intrigante y admirable.

Hoy en día, los ideales de los movimientos de Software Libre y Código Abierto, el proyecto GNU y la calidad del software GNU son bien conocidos. El sistema GNU más popular es GNU/Linux, que utiliza el núcleo Linux y las utilidades GNU para crear un entorno de computación completo, totalmente funcional y compatible con Unix y POSIX.

\emph{bash} es totalmente compatible con el estándar POSIX de 1992. Tiene varias de las características más importantes del Korn shell y las características del C shell que el Korn shell ha adoptado, incluyendo alias, funciones, notación de tilde, modos de edición emacs y vi, expresiones aritméticas, control de trabajos, etc.

La superposición de características entre \emph{bash} y el Korn shell ha aumentado en los últimos años. Incluye muchas características del \emph{ksh93}. Pero no es un clon exacto de \emph{ksh}. El FAQ de \emph{bash}, publicado mensualmente por Chet Ramey, enumera las siguientes diferencias entre \emph{bash} y \emph{ksh93}. Los elementos incluidos entre corchetes (\texttt{[...]}) están listados en este libro, pero no en el FAQ.

Lo siguiente, en \emph{ksh93}, no está disponible en \emph{bash} 2.05:

\begin{itemize}
	\item Arrays asociativos
	\item Aritmética y variables de punto flotante
	\item Funciones de la biblioteca matemática \texttt{\$\{!nombre[sub]\}} nombre de subíndice para arreglo asociativo
	\item \texttt{"."} está permitido en nombres de variables para crear un espacio de nombres jerárquico
	\item Sintaxis de asignación compuesta más extensa
	\item Funciones de disciplina
	\item Instrucciones integradas \emph{sleep} y \emph{getconf} (\emph{bash} tiene versiones cargables)
	\item \texttt{typeset -n} y variables \emph{nameref}
	\item La trampa KEYBD
	\item Las variables: \texttt{.sh.edchar, .sh.edmode, .sh.edcol, .sh.edtext, .sh.version, .sh.name, .sh.subscript, .sh.value, HISTEDIT} [La variable \texttt{.sh.match} también]
	\item Referencias posteriores en la coincidencia de patrones (\textbackslash{}N)
	\item El operador \& en listas de patrones para coincidencia
	\item \texttt{print -f} (bash usa \emph{printf})
	\item \emph{fc} ha sido renombrado a \emph{hist}
	\item El comando de punto (.) puede ejecutar funciones de shell
	\item Estados de salida entre 0 y 255
	\item La opción de asignación de variables +=
	\item \texttt{TMOU}T es el tiempo de espera predeterminado para \emph{read} y \emph{select}
	\item Redirecciones \texttt{<\&n-} y \texttt{>\&n-} (combinación de duplicar y cerrar) [Aquí-strings con \texttt{<<<}]
	\item Mezcla de \texttt{FPATH} y \texttt{PATH}
	\item \texttt{getopts -a}
	\item La opción de invocación \texttt{-R}
	\item La trampa \texttt{DEBUG} ahora se ejecuta antes de cada comando simple, en lugar de después
	\item Los modificadores \texttt{\%H, \%P, \%T} de \emph{printf}, y una base de salida para \texttt{\%d} [También \texttt{\%Z}.]
\end{itemize}

Lo siguiente, en \emph{ksh93}, está presente en \emph{bash} 2.05:

\begin{itemize}
	\item El comando \texttt{for ((...;...;...)) ; do list; done} para comandos aritméticos
	\item Los operadores aritméticos \texttt{?:, ++, --} y coma (\texttt{,})
	\item Las expansiones de variables de shell: \texttt{\$\{!param\}, \$\{param:offset[:len]\}, \$\{param/pat[/str]\}, \$\{!param*\}}
	\item Asignación compuesta de arreglos
	\item La palabra reservada !
	\item Instrucciones integradas cargables, pero \emph{ksh} usa \emph{builtin} mientras que \emph{bash} usa \emph{enable}
	\emph Las instrucciones integradas \emph{command}, \emph{builtin} y \emph{disown}
	\item La citación nueva \emph{\$'...'} y \emph{\$"..."}
	\item \texttt{FIGNORE} (pero \emph{bash} usa \texttt{GLOBIGNORE}), \texttt{HISTCMD}
	\item \texttt{set -o notify}, \texttt{set -C}
	\item Cambios en el comando integrado \emph{kill}
	\item \texttt{read -A} (\emph{bash} usa \texttt{read -a})
	\item \texttt{read -t/read -d}
	\item \texttt{trap -p}
	\item \texttt{exec -a/exec -c}
	\item El comando de punto (.) restaura los parámetros posicionales cuando se completa
	\item El comando test se ajusta a POSIX.
	\item \texttt{umask -S}
	\item \texttt{unalias -a}
	\item Sustitución de comandos y aritmética realizada en \texttt{PS1, PS4} y \texttt{ENV}
	\item Completado de nombres de comandos
	\item \texttt{ENV} procesado solo para shells interactivos
\end{itemize}

\emph{bash} tiene muchas características propias que lo convierten en un entorno muy potente y flexible. Aquí tienes algunas de las características destacadas:

\begin{itemize}
	\item Puedes poner escapes de barra invertida en la cadena de texto del indicador primario (\texttt{PS1}), en la que bash sustituye cosas como la fecha, hora, directorio de trabajo actual, nombre de la máquina, nombre de usuario, shell, etc.
	\item Los comandos integrados, \emph{command} y \emph{enable}, te brindan más control sobre los pasos que sigue \emph{bash} para buscar comandos, es decir, el equivalente de \emph{bash} a la lista de pasos de búsqueda de comandos en el \hyperref[sec:Chapter7]{Capítulo 7}.
	\item El modo de edición \emph{emacs} es personalizable, incluso más que su equivalente en \emph{pdksh}. Puedes usar el comando \emph{bind} para configurar tus propias preferencias de teclas, y hay varios comandos más disponibles, incluida la capacidad de deshacer tu último comando.
	\item También puedes volver a asignar teclas en el modo de edición \emph{vi}.
	\item \emph{pushd} y \emph{popd} están integrados, al igual que en el C shell.
	\item Los arreglos indexados pueden tener un tamaño ilimitado.
	\item Muchas opciones y variables nuevas te permiten personalizar tu entorno con una flexibilidad sin precedentes. Esto incluye \texttt{set -o posix} para una conformidad estricta con POSIX.
\end{itemize}

Nos sentimos obligados a decir que muchos usuarios prefieren \emph{bash} al Korn shell. Con la creciente popularidad de GNU/Linux y varios sistemas derivados de BSD, no está claro qué shell tiene una base de usuarios más grande. En cualquier caso, \emph{bash} es definitivamente una excelente elección. Recomendamos el libro \emph{Learning the bash Shell} de Cameron Newham y Bill Rosenblatt, publicado por O'Reilly \& Associates. (Está basado en la primera edición de este libro).

\section{zsh}
\emph{zsh} es un potente shell interactivo y lenguaje de secuencias de comandos con muchas características que se encuentran en \emph{ksh, bash} y \emph{tcsh}, así como varias características únicas. \emph{zsh} tiene la mayoría de las características de \emph{ksh88} pero pocas de \emph{ksh93}. Está disponible de forma gratuita y debería compilar y ejecutarse en prácticamente cualquier versión moderna de Unix. También hay versiones para otros sistemas operativos. La página principal de \emph{zsh} es \url{http://www.zsh.org}. La versión actual es 4.0.2.

En esta sección cubrimos:

\begin{itemize}
	\item Globbing extendido
	\item Completado
	\item Edición de línea de comandos
	\item Indicadores y temas de indicadores
	\item Diferencias entre \emph{zsh} y \emph{ksh}
\end{itemize}

\subsection{Globbing extendido}
Una característica muy útil es el operador glob recursivo \texttt{**}\footnote{El \emph{globbing} es un argot técnico para la expansión de comodines.}
. Por ejemplo, es sencillo construir una búsqueda recursiva con \emph{grep}:

\begin{lstlisting}[language=bash]
grep foo **/*.c
\end{lstlisting}

O para encontrar recursivamente todos los archivos o directorios llamados \emph{core}, prueba:

\begin{lstlisting}[language=bash]
print **/core
\end{lstlisting}

Otra característica útil son los \emph{calificadores de glob}. Hay muchos de ellos, por ejemplo, para imprimir solo archivos regulares en el directorio actual:

\begin{lstlisting}[language=bash]
print *(.)
\end{lstlisting}

o solo los directorios:

\begin{lstlisting}[language=bash]
print *(/)
\end{lstlisting}

Combinar estos con el operador glob recursivo puede ser útil. Podemos mejorar el ejemplo anterior de encontrar archivos \emph{core} limitando la búsqueda solo a archivos regulares:

\begin{lstlisting}[language=bash]
print **/core(.)
\end{lstlisting}

Otro calificador es U para objetos del sistema de archivos de los que eres propietario. Lo siguiente imprime todos los archivos que posees en \texttt{/tmp} y sus subdirectorios:

\begin{lstlisting}[language=bash]
print /tmp/**/*(U)
\end{lstlisting}

Los calificadores de glob también se pueden combinar. Por ejemplo, usando la palabra clave del archivo de socket = en combinación con U, es fácil encontrar archivos de socket en \texttt{/tmp} y sus subdirectorios que posees:

\begin{lstlisting}[language=bash]
print /tmp/**/*(U=)
\end{lstlisting}

También están disponibles calificadores de tamaño de archivo. Por ejemplo, para encontrar todos los archivos en tu directorio de inicio que tienen más de 10 megabytes de tamaño:

\begin{lstlisting}[language=bash]
print ~/**/*(Lm+10)
\end{lstlisting}

Y también hay calificadores de permisos de archivo. Por ejemplo, el calificador W selecciona objetos del sistema de archivos que son escribibles por el mundo. Puedes usarlo para encontrar todos los directorios en tu directorio de inicio y sus subdirectorios que te pertenecen y que son escribibles por el mundo:

\begin{lstlisting}[language=bash]
print ~/**/*(UW/)
\end{lstlisting}

Consulta \emph{zshexpn(1)} para obtener más información.

\subsection{Completado}
El sistema de completado de \emph{zsh} es extremadamente sofisticado. La idea principal es que cada vez que estás a punto de escribir algo en la línea de comandos, si presionas TAB, \emph{zsh} intentará completarlo. \emph{zsh} viene con muchos valores predeterminados para la completación y también es completamente personalizable.

Para obtener un conjunto completo de funciones de completado predeterminadas, ejecuta los siguientes comandos (normalmente en tu archivo de inicio \texttt{~/.zshrc}):

\begin{lstlisting}[language=bash]
autoload -U compinit
compinit
\end{lstlisting}

Ahora veamos algunos ejemplos. Representamos la tecla TAB en los ejemplos como \texttt{[TAB]}.

Primero, \emph{zsh} es inteligente al realizar completados. Por ejemplo, \texttt{cd[TAB]} solo expande directorios, eliminando así el ruido de la completación.

¿Alguna vez te has sentido frustrado porque no puedes recordar exactamente el nombre del comando del que deseas obtener más información, y \emph{man -k}\footnote{Esto realiza una búsqueda de palabras clave en una base de datos en línea extraída de las páginas del manual.}
no está configurado en tu sistema? Bueno, \emph{zsh} completará las páginas del manual disponibles para ti:

\begin{lstlisting}[language=bash]
g@sifl:pts/7% man zsh[TAB]
zsh           zshcompctl    zshcontrib    zshmodules     zshzftpsys 
zshall        zshcompsys    zshexpn       zshoptions     zshzle 
zshbuiltins   zshcompwid    zshmisc       zshparam
\end{lstlisting}

O tal vez quieras descubrir un nombre de proceso o PID que deseas matar:

\begin{lstlisting}[language=bash]
g@sifl:pts/2% kill [TAB]
9652    pts/2      00:00:00  zsh 
9653    pts/2      00:00:00  ps
\end{lstlisting}

Para \emph{finger}, expande usuarios:

\begin{lstlisting}[language=bash]
g@sifl:pts/7% finger o[TAB]
odin    omg    oof    operator    orb
\end{lstlisting}

y hosts:

\begin{lstlisting}[language=bash]
g@sifl:pts/7% finger oof@[TAB]
brak    localhost    sifl    zorak
\end{lstlisting}

Usando la función \emph{compdef} distribuida, puedes definir tus propias completaciones, utilizando tus propias funciones personalizadas o las funciones de completado que vienen con \emph{zsh}. Por ejemplo, la distribución define el comando \emph{kill} para usar la función de distribución \texttt{\_pids} para proporcionar identificadores de procesos. También puedes usarlo para definir la completación para otros comandos, como el comando \emph{pstack} de Solaris:

\begin{lstlisting}[language=bash]
compdef _pids pstack
\end{lstlisting}

Una vez hecho esto, puedes aplicar la completación al comando \emph{pstack} de la siguiente manera:

\begin{lstlisting}[language=bash]
g@sifl:pts/7% pstack [TAB]
13606 pts/7    00:00:00 zsh 
13607 pts/7    00:00:00 ps
\end{lstlisting}

Otra función de completado de distribución muy útil es \emph{\_gnu\_generic}. Esto se puede aplicar a cualquier comando que utilice las convenciones de opción de línea de comando \texttt{--long-option} de GNU. La distribución de \emph{zsh} especifica muchos comandos de GNU para completar con esta función (como \emph{tar}):

\begin{lstlisting}[language=bash]
g@sifl:pts/7% tar --v[TAB]
--verbose   --verify   --version   --volno-file
\end{lstlisting}

Y esto es solo la punta del proverbial iceberg. Hay mucho más en el sistema de completado de \emph{zsh}; consulta \emph{zshcompsys(1)} para los detalles (\emph{gory}).

\subsection{Editor de línea de comandos}
El editor de línea de comandos de \emph{zsh} es extremadamente potente. Tiene varias características únicas, incluida la edición de varias líneas y una pila de búfer de entrada. El editor de comandos de varias líneas facilita la composición de pequeños scripts en la línea de comandos, ya que no solo tienes una línea para editar. 

La pila de búfer de entrada resulta muy útil. Mientras escribes un comando, puedes escribir ESC q y la línea actual se coloca en la pila de búfer. La línea de entrada se borra y puedes escribir otro comando. Cuando se ejecuta ese comando, la línea anterior se saca de la pila y puedes continuar con ese comando. Consulta \emph{zshzle(1)} para obtener más detalles.

\subsection{Indicadores y temas de indicadores}
Aunque la mayoría de las shells modernas tienen indicadores personalizables, \emph{zsh} lo eleva a una forma de arte. Una de las características únicas es un indicador del lado derecho, \texttt{RPROMPT}, que es muy útil para mostrar el directorio actual. Esto a su vez elimina el desorden del indicador del lado izquierdo:

\begin{lstlisting}[language=bash]
g@sifl:pts/2% RPROMPT='%~' 
g@sifl:pts/2%             ~/src/xemacs-21.1.14
\end{lstlisting}

Además, puedes definir colores y fuentes en negrita, y el indicador puede ocupar más de una línea.

Y dado que la noción de temas\footnote{Algunas GUIs populares, como GNOME, soportan temas. En lugar de tener una apariencia inmutable, pueden cambiarse a diferentes estilos o temas. Las distribuciones de estos GUIs a menudo contienen varios para elegir. Algunas de ellas tienden a emular otras GUI, mientras que otras son nuevas y son más que nada divertidas decoraciones de ventanas.}
se ha vuelto popular en interfaces de usuario gráficas como GNOME, se pueden definir temas de indicadores de \emph{zsh}; la distribución incluye varios entre los que puedes elegir. Para habilitar los temas de indicadores, agrega estas líneas a tu \texttt{\~{}/.zshrc}:

\begin{lstlisting}[language=bash]
autoload -U promptinit
promptinit
\end{lstlisting}

Para ver qué temas están disponibles, ejecuta:

\begin{lstlisting}[language=bash]
g@sifl:pts/2% prompt -l 
Currently available prompt themes: 
adam1 adam2 bart bigfade clint elite2 elite fade fire off oliver 
redhat suse zefram
\end{lstlisting}

Para habilitar un tema, usa la opción \texttt{-s}. Por ejemplo:

\begin{lstlisting}[language=bash]
g@sifl:pts/7% prompt -s bart 
sifl [prompt -s bart] ~                           01-10-04 11:58PM 
g@sifl:pts/7%
\end{lstlisting}

Puedes ver que \emph{bart} es un indicador de dos líneas con varios componentes como el nombre del host, el comando anterior, el directorio actual y la fecha y hora. Consulta \emph{zshcontrib(1)} para obtener más detalles sobre los temas de indicadores.

\subsection{Diferencias entre \emph{zsh} y \emph{ksh}}
Esta sección se deriva de información en el FAQ de \emph{zsh}.

La mayoría de las características de \emph{ksh88} (y, por lo tanto, también del Shell de Bourne, \emph{sh}) están implementadas en zsh; pueden surgir problemas porque la implementación es ligeramente diferente. También ten en cuenta que no todas las \emph{ksh} son iguales. Esto se basa en la versión 11/16/88f de \emph{ksh}; las diferencias con \emph{ksh93} son más sustanciales.

Como resumen del estado:

\begin{enumerate}
	\item Debido a todas las opciones, no es seguro asumir que una ejecución general de \emph{zsh} por un usuario se comportará como \emph{sh} o \emph{ksh} compatible.
	\item Invocar \emph{zsh} como \emph{sh} o \emph{ksh} (o si alguno de ellos es un enlace simbólico a \emph{zsh}) establece opciones apropiadas y mejora la compatibilidad (desde dentro de \emph{zsh}, llamar \texttt{ARGV0=sh zsh} también funcionará).
	\item Desde la versión 3.0 en adelante, el grado de compatibilidad con \emph{sh} en estas circunstancias es muy alto: \emph{zsh} ahora se puede usar con GNU \emph{configure} o \emph{Configure de perl}, por ejemplo.
	\item El grado de compatibilidad con \emph{ksh} también es alto, pero faltan algunas cosas: por ejemplo, las expresiones de coincidencia de patrones más sofisticadas son diferentes para versiones anteriores a 3.1.3; consulta la lista detallada a continuación.
	\item También a partir de 3.0, está disponible el comando \emph{emulate}: \texttt{emulate ksh} y \texttt{emulate sh} establecen varias opciones, así como cambian el efecto de las banderas de opciones de un solo carácter, como si el shell se hubiera invocado con el nombre apropiado. Incluir el comando \texttt{emulate sh; setopt localoptions} en una función del shell activa la emulación \emph{sh} solo para esa función. En 4.0 (y en 3.0.6 a 8), esto se puede abreviar como \texttt{emulate -L sh}.
\end{enumerate}

La diferencia clásica es la división de palabras: \emph{zsh} mantiene el resultado de \texttt{\$variable} como una sola palabra, incluso si la variable contiene espacios en blanco. Esto confunde a muchos \emph{usuarios principiantes de zsh}. La respuesta es establecer \texttt{SH\_WORD\_SPLIT} para compatibilidad hacia atrás. La siguiente diferencia más clásica es que los patrones de globs no coincidentes hacen que el comando \emph{abort}; establece \texttt{NO\_NOMATCH} para evitar eso.

\emph{zsh} tiene un conjunto grande de opciones que aumentan la compatibilidad con \emph{ksh}, aunque tal vez disminuyan las habilidades de \emph{zsh}: consulta las entradas del manual para más detalles. Si se invoca como \emph{ksh}, el shell establece las opciones adecuadas.

Aquí hay algunas diferencias con \emph{ksh} que podrían ser significativas para los programadores de \emph{ksh}, algunas de las cuales pueden interpretarse como errores. Ten en cuenta que esta lista está deliberadamente bastante completa y que la mayoría de los elementos son bastante menores. Aquellos marcados con \nmid{} realizan de manera similar a \emph{ksh} si el shell se invoca con el nombre \emph{ksh} o si está en efecto \texttt{emulate ksh}. Las palabras en mayúsculas con guiones bajos en sus nombres se refieren a opciones del shell.

\emph{Sintaxis}

\begin{itemize}
	\item \nmid{} División de palabras en el shell: consulta arriba.
	\item \nmid{} Los arrays son (por defecto) más parecidos a \emph{csh} que a \emph{ksh}: los subíndices comienzan en 1, no en 0; \texttt{array[0]} se refiere a \texttt{array[1]; \$array} se refiere a todo el array, no a \texttt{\$array[0]}; las llaves no son necesarias: \texttt{\$a[1]} es lo mismo que \texttt{\$\{a[1]\}}, etc. Establece la opción \texttt{KSH\_ARRAYS} para compatibilidad.
	\item Los coprocesos se establecen con \texttt{coproc; |\&} se comporta como \emph{csh}.\footnote{En \texttt{csh, |\&} envía tanto la salida estándar como la salida de error por el mismo conducto; es equivalente a ... \texttt{2>\&1 | ....}}
El manejo de los descriptores de archivo de coproceso también es diferente.
	\item Para \texttt{cmd1 \&\& cmd2 \&}, solo \texttt{cmd2}, en lugar de toda la expresión, se ejecuta en segundo plano en \emph{zsh}. El manual da a entender que esto es un error. Usa \texttt{\{ cmd1 \&\& cmd2 \} \&} como solución.
\end{itemize}

\emph{Substituciones de línea de comandos, globbing, etc.}

\begin{itemize}
	\item \nmid{} La falta de coincidencia con un patrón de globbing provoca un error (usa \texttt{NO\_NOMATCH}).
	\item \nmid{} Los resultados de las sustituciones de parámetros se tratan como texto plano: \texttt{foo="*"; print \$foo} imprime todos los archivos en \emph{ksh} pero imprime * en \emph{zsh} (usa \texttt{GLOB\_SUBST}).
	\item \nmid{} Las variables de indicador (por ejemplo, \texttt{PS1}) no sufren sustitución de parámetros por defecto (usa \texttt{PROMPT\_SUBST}).
	\item \nmid{} El globbing estándar no permite listas de patrones al estilo \emph{ksh}. La Tabla \ref{Tab:A-1} muestra patrones equivalentes.\\
Las formas \^{}, \~{} y \# (pero no |) requieren establecer \texttt{EXTENDED\_GLOB}. A partir de la versión 3.1.3, las formas de \emph{ksh} son completamente compatibles cuando está en efecto la opción \texttt{KSH\_GLOB}; para versiones anteriores debes usar los equivalentes dados en la Tabla \ref{Tab:A-1}.
	\item Las asignaciones no entrecomilladas hacen la expansión de archivos después de los dos puntos (destinado para variables de estilo \texttt{PATH}).
	\item \emph{integer} no permite \texttt{-i}.
	\item \emph{typeset} e integer tienen un comportamiento especial para las asignaciones en ksh, pero no en \emph{zsh}. Por ejemplo, esto no funciona en \emph{zsh}:

	\begin{lstlisting}[language=bash]
integer k=$(wc -l ~/.zshrc)
\end{lstlisting}

porque el valor de retorno de \emph{wc} incluye espacios en blanco iniciales, lo que provoca la división de palabras. \emph{ksh} maneja la asignación de manera especial, como una sola palabra.
\end{itemize}

**Tabla A-1. Equivalentes de patrones ksh/zsh**
\begin{table}[h]
	\center
	\caption{Equivalentes de patrones \emph{ksh/zsh}}
	\label{Tab:A-1}
	\begin{tabular}{|m{2cm}|m{2cm}|m{11cm}|} \hline
		\textbf{ksh} & \textbf{zsh} & \textbf{Significado} \\ \hline
		!(foo) & \^{}foo & Cualquier cosa menos \emph{foo} \\\hline
		& foo1\~{}foo2 & Cualquier cosa que coincida con foo1 pero no con foo2.\tablefootnote{Ten en cuenta que \~{} es el único operador de globbing que tiene una precedencia inferior a /. Por ejemplo, \texttt{**/foo\~{}*bar*} coincide con cualquier archivo en un subdirectorio llamado \emph{foo}, excepto donde \emph{bar} ocurrió en alguna parte de la ruta (por ejemplo, \texttt{users/barstaff/foo} será excluido por el operador \~{}). Como el operador \texttt{**} no puede agruparse (dentro de paréntesis se trata como *), esta es la manera de excluir algunos subdirectorios de hacer coincidir un \texttt{**}.} \\\hline
		@(foo1|foo2|...) & (foo1|foo2|...) & \emph{foo1} o \emph{foo2} o ... \\\hline
		?(foo) & (foo|) & Cero o una ocurrencia de \emph{foo} \\\hline
		*(foo) & (foo)\# & Cero o más ocurrencias de \emph{foo} \\\hline
		+(foo) & (foo)\#\# & Uno o más ocurrencias de \emph{foo} \\\hline
	\end{tabular}
\end{table}

\emph{Ejecución de comandos}

\begin{itemize}
	\item \nmid{} No hay variable \texttt{ENV} (usa \texttt{/etc/zshrc}, \texttt{\~{}/.zshrc}; también nota \texttt{\$ZDOTDIR}).
	\item \texttt{\$PATH} no se busca para comandos especificados en la invocación sin \texttt{-c}.
\end{itemize}

\emph{Alias y funciones}

\begin{itemize}
	\item El orden en que se definen los alias y las funciones es significativo: las definiciones de funciones con () expanden alias.
	\item Los alias y las funciones no se pueden exportar.
	\item No hay alias rastreados: el hashing de comandos reemplaza esto.
	\item El uso de alias para la vinculación de teclas se reemplaza por \emph{bindkey}.
	\item \nmid{} Las opciones no son locales para las funciones (usa \texttt{LOCAL\_OPTIONS}; nota que esto siempre puede no estar configurado localmente para propagar la configuración de opciones desde una función hasta el nivel de llamada).
	\item Las funciones definidas con \texttt{function funcname \{ body ;\}} se comportan de la misma manera que las definidas con \texttt{funcname () \{ body ;\}}. En \emph{ksh93}, solo las primeras se comportan como funciones verdaderas, y las segundas se comportan como si el cuerpo se leyera desde un archivo con el comando punto.
\end{itemize}

\emph{Trampas y señales}

\begin{itemize}
	\item \nmid{} Las trampas no son locales para las funciones. La opción \texttt{LOCAL\_TRAPS} está disponible desde 3.1.6.
	\item \texttt{TRAPERR} se convierte en \texttt{TRAPZERR} (esto fue forzado por \texttt{UNICOS} que tiene \texttt{SIGERR}).
\end{itemize}

\emph{Edición}

\begin{itemize}
	\item Las opciones \emph{emacs, gmacs} y \emph{viraw} no son compatibles. Usa \emph{bindkey} para cambiar el comportamiento de edición: \texttt{set -o emacs} se convierte en \texttt{bindkey -e} y \texttt{set -o vi} se convierte en \texttt{bindkey -v}; para \emph{gmacs}, ve a \emph{emacs-mode} y usa \texttt{bindkey \textbackslash\^{}t gosmacs-transpose-characters}.
	\item La opción de \emph{palabra clave} no existe y \texttt{set -k} es en su lugar \emph{interactivecomments}.
	\item \nmid{} La gestión de historiales en múltiples shells es diferente: la lista de historiales no se guarda y restaura después de cada comando. La opción \texttt{SHARE\_HISTORY} apareció en 3.1.6 y se establece en el modo de compatibilidad con ksh para remediar esto.
	\item \textbackslash{} no escapa caracteres de edición (usa CTRL-V).
	\item No se establecen todos los enlaces de \emph{ksh} (por ejemplo, ESC \#; prueba ESC q).
	\item \nmid{} \# en una shell interactiva no se trata como un comentario por defecto.
\end{itemize}

\emph{Comandos incorporados}

\begin{itemize}
	\item Algunos comandos incorporados (\emph{r, autoload, history, integer,} ...) son alias en \emph{ksh}.
	\item No hay un comando incorporado \emph{newgrp}: usa \texttt{alias newgrp="exec newgrp"}.
	\item \emph{jobs} no tiene una bandera \texttt{-n}.
	\item \emph{read} no tiene una bandera \texttt{-s}.
\end{itemize}

\emph{Otras idiosincrasias}

\begin{itemize}
	\item \texttt{select} siempre vuelve a mostrar la lista de selecciones en cada bucle.
\end{itemize}

\section{Sustitutos en Plataformas PC}
La proliferación del shell Korn no se detuvo en los límites de Unix. Muchos programadores que obtuvieron su experiencia inicial en sistemas Unix y posteriormente cruzaron al mundo de PC deseaban un entorno agradable tipo Unix (especialmente cuando se enfrentaban a los horrores de la línea de comandos MS-DOS), así que no sorprende que hayan aparecido varias interfaces tipo shell Unix para sistemas operativos de pequeñas computadoras, entre ellas, emulaciones del shell Korn.

En los últimos años, no solo han aparecido clones de shell, sino entornos Unix <<completo>>. Dos de ellos utilizan shells que ya hemos discutido. Dos proporcionan sus propias re-implementaciones del shell. Proporcionar listas de diferencias mayores y menores es contraproducente. En cambio, esta sección describe cada entorno a su vez (en orden alfabético), junto con información de contacto y descarga en Internet.

\subsection{Cygwin}
Cygnus Consulting (ahora Red Hat) creó el entorno \emph{Cygwin}. Crearon primero \emph{cgywin.dll}, una biblioteca compartida que proporciona emulación de llamadas al sistema Unix, y luego trasladaron un gran número de utilidades GNU a varias versiones de Microsoft Windows. La emulación incluye redes TCP/IP con la API de sockets de Berkeley. La mayor funcionalidad se encuentra en Windows/NT, Windows 2000 y Windows XP, aunque el entorno puede funcionar en Windows 95/98/ME también.

El entorno \emph{Cygwin} utiliza \emph{bash} como su shell, GCC como su compilador C y el resto de las utilidades GNU para su conjunto de herramientas Unix. Un comando de montaje sofisticado proporciona un mapeo de la notación de ruta de Windows \texttt{C:\textbackslash{}path} a nombres de archivos Unix.

El punto de partida para el proyecto \emph{Cygwin} es \url{http://www.cygwin.com}. Lo primero que debes descargar es un programa instalador. Al ejecutarlo, eliges qué paquetes adicionales deseas instalar. La instalación es completamente basada en Internet; no hay CD oficiales de \emph{Cygwin}, al menos no de los mantenedores del proyecto.

\subsection{DJGPP}
El conjunto DJGPP proporciona herramientas GNU de 32 bits para el entorno MS-DOS. Para citar la página web:

\begin{itemize}
	\item DJGPP es un sistema de desarrollo C/C++ completo de 32 bits para PC Intel 80386 (y superiores) que ejecutan MS-DOS. Incluye puertos de muchas utilidades de desarrollo GNU. Las herramientas de desarrollo requieren una computadora 80386 o más nueva para ejecutarse, al igual que los programas que producen. En la mayoría de los casos, los programas que produce se pueden vender comercialmente sin licencia ni regalías.
	\item El nombre proviene de las iniciales de D.J. Delorie, quien portó el compilador GNU C++, g++, a MS-DOS, y las iniciales de texto de g++, GPP. Se convirtió esencialmente en un entorno Unix completo en la parte superior de MS-DOS, con todas las herramientas GNU y \emph{bash} como su shell. A diferencia de \emph{Cygwin} o UWIN (ver más adelante en este capítulo), no necesitas una versión de Windows, solo un procesador de 32 bits completo y MS-DOS. (Aunque, por supuesto, puedes usar DJGPP desde una ventana MS-DOS de Windows). El sitio web es \url{http://www.delorie.com/djgpp/}.
\end{itemize}

\subsection{MKS Toolkit}
Quizás el entorno Unix más establecido para el mundo de las PC es el MKS Toolkit de Mortice Kern Systems:

\begin{footnotesize}
\singlespace
MKS Canada - Sede Corporativa \\
410 Albert Street \\
Waterloo, ON N2L 3V3 \\
Canadá \\
(519) 884-2251 \\
(519) 884-8861 (fax) \\
(800) 265-2797 (ventas) \\
\url{http://www.mks.com}
\end{footnotesize}

MKS Toolkit viene en varias versiones dependiendo del entorno de desarrollo y la cantidad de desarrolladores que lo utilizarán. Incluye un shell que cumple con POSIX, junto con casi todas las características del shell Korn de 1988, así como más de 300 utilidades como \emph{awk, perl, vi, make,} y demás. Su biblioteca admite más de 1500 API de Unix, haciéndola extremadamente completa y facilitando la portabilidad al entorno Windows. Más información está disponible en \url{http://www.mkssoftware.com/products/tk/ds_tkpdev.asp}.

\subsection{Thompson Automation Software Toolkit}
Thompson Automation Software proporciona el Thompson Toolkit, que incluye un shell y más de 100 utilidades. El kit está disponible para MS-DOS 2.1 y superior, OS/2 1.2 o WARP y para Microsoft Windows 95 y superior. La información de contacto es:

\begin{footnotesize}
\singlespace
Thompson Automation Software \\
5616 SW Jefferson \\
Portland, OR 97221 \\
1-800-944-0139 (EE. UU. y Canadá) \\
1-503-224-1639 (internacional/local) \\
1-503-224-3230 (fax) \\
sales@tasoft.com \\
\url{http://www.tasoft.com/toolkit.html/}
\end{footnotesize}

El software de Thompson es conocido por su implementación de \emph{awk}, que es rápida y confiable, con muchas extensiones poderosas al lenguaje awk. El shell del toolkit es compatible con POSIX y la versión 1988 del shell Korn.

\subsection{AT\&T UWIN}
El paquete UWIN es un proyecto de David Korn y sus colegas para poner un entorno Unix disponible bajo Microsoft Windows. Es similar en estructura a \emph{Cygwin}, discutido anteriormente. Una biblioteca compartida, \emph{posix.dll}, proporciona emulación de las APIs de llamadas al sistema Unix. La emulación de llamadas al sistema es bastante completa. Un giro interesante es que el registro de Windows se puede acceder como un sistema de archivos bajo \texttt{/reg}. Sobre la emulación de la API de Unix, se han compilado y ejecutado \emph{ksh93} y más de 200 utilidades Unix (o más bien, re-implementaciones). El entorno UWIN depende del compilador nativo de Microsoft Visual C/C++, aunque las herramientas de desarrollo GNU están disponibles para descargar y usar con UWIN.

\url{http://www.research.att.com/sw/tools/uwin/} es la página web del proyecto. Describe lo que está disponible, con enlaces para descargar binarios, así como información sobre la licencia comercial del paquete UWIN. También se incluyen enlaces a varios documentos sobre UWIN, software adicional útil y enlaces a otros paquetes similares. 

La ventaja más notable del paquete UWIN es que su shell es el auténtico \emph{ksh93}. Por lo tanto, la compatibilidad con la versión Unix de \emph{ksh93} no es un problema.
