diff --git a/Aprendiendo_Korn_Shell.pdf b/Aprendiendo_Korn_Shell.pdf new file mode 100644 index 0000000..23e51ac Binary files /dev/null and b/Aprendiendo_Korn_Shell.pdf differ diff --git a/Aprendiendo_Korn_Shell.tex b/Aprendiendo_Korn_Shell.tex new file mode 100644 index 0000000..9316ed5 --- /dev/null +++ b/Aprendiendo_Korn_Shell.tex @@ -0,0 +1,158 @@ +\documentclass[12pt,a4paper]{report} +\usepackage[ + spanish, + mexico, + es-lcroman % Poder usar numeración romana en minúscula +]{babel} +\usepackage[utf8]{luainputenc} % Tildes y caracteres especiales con lualatex +\usepackage{eso-pic} % Insertar imagen de fondo para portada +\usepackage{graphicx} +\graphicspath{{./Imágenes}} +\usepackage{parskip} % Espacio entre párrafos en lugar de sangría +\usepackage{setspace} % Permite definir el interlineado +\usepackage{array} % Ajuste de columnas en tablas +\usepackage{xcolor} +\newcommand{\highlight}[1]{\colorbox{black}{\textcolor{white}{#1}}} % Utilizado para resaltar +\usepackage[hidelinks]{hyperref} +\hypersetup{ + pdfauthor={Omar Sánchez Enríquez}, + pdftitle={Aprendiendo Korn Shell}, + pdfkeywords={korn, shell, built-in, ksh} + pdfproducer={Latex con hyperref en Void Linux}, + pdfcreator={Texlive with Lualatex}, + colorlinks=true, + filecolor=magenta, + linkcolor=blue, + urlcolor=green +} + +\usepackage{listings} % Escribir bloques de código +\definecolor{codegreen}{rgb}{0,0.6,0} +\definecolor{codegray}{rgb}{0.5,0.5,0.5} +\definecolor{codepurple}{rgb}{0.58,0,0.82} +\definecolor{backcolour}{rgb}{0.95,0.95,0.92} +\lstdefinestyle{mystyle}{ + backgroundcolor=\color{backcolour}, + commentstyle=\color{codegreen}, % estilo de comentario + keywordstyle=\color{blue}, + stringstyle=\color{codepurple}, + basicstyle=\ttfamily\scriptsize, % el tamaño de las fuentes utilizadas para el código + breakatwhitespace=false, + breaklines=true, % establece el corte de línea automático + captionpos=b, % Establece la posición del título en la parte inferior + keepspaces=true, + numbersep=5pt, + showspaces=false, + showstringspaces=false, + showtabs=false, + keepspaces=true, + tabsize=2 +} +\lstset{style=mystyle} +\usepackage{tablefootnote} +\usepackage{multirow} +\usepackage{longtable} +\usepackage{tcolorbox} % Crear cuadros de texto +% Definir un nuevo entorno tcolorbox +\newtcolorbox{mybox}[1][]{colback=blue!5!white, colframe=blue!75!black, fonttitle=\bfseries, title=#1} + +\usepackage{amssymb, amsmath} +\urlstyle{same} % Misma fuente para los vínculos + +%%%%% Márgenes %%%%% +\usepackage[ + top=2cm, % Margen superior + bottom=1.5cm, % Margen inferior + right=2.4cm, % Margen derecho + left=2.4cm % Margen izquierdo +]{geometry} + + +%%%%% Cambiar de tamaño y centrar capítulos %%%%% +\usepackage[explicit]{titlesec} +% Configuración para los capítulos +\titleformat{\chapter}[display]{\bfseries\centering}{\Large CAPÍTULO \thechapter}{1em}{\large #1} + +%%%%% Encabezado y pie de página %%%%% +\usepackage{fancyhdr} +\pagestyle{fancy} +\fancyhf{} % Borrar los valores que vienen por defecto +\rhead[]{\fontsize{9}{12} \selectfont{\rightmark}} +\renewcommand{\footrulewidth}{0.4pt} % Añadir linea horizontal a pie de página +\lfoot[\thepage]{\fontsize{9}{12} \selectfont{Aprendiendo Korn Shell}} +\rfoot[]{\fontsize{9}{12} \selectfont{\thepage}} + +%%%%% Portada %%%%% +\title { + \input{./Secciones/Portada} +} + +%%%%% Contenido del documento %%%%% +\begin{document} +\spacing{1.5} % Interlineado 1.5 + +% % % % % Estructura % % % % % +\input{./Secciones/Portada} +\chapter*{COPYRIGHT} +\thispagestyle{empty} +\input{./Secciones/Copyright} +\chapter*{DEDICATORIA} +\thispagestyle{empty} +\input{./Secciones/Dedicatoria} +\chapter*{PREFACIO}\label{sec:Prefacio} +\thispagestyle{empty} +\input{./Secciones/Prefacio} + +% Índices +\pagenumbering{roman} % Iniciar numeración desde 1 en números romanos minúscula +\renewcommand\contentsname{\centering Contenido} % Renombrar y centrar nombre de índices +\setcounter{page}{0} +\tableofcontents +\listoffigures +\listoftables + +\chapter{CONCEPTOS BÁSICOS DE KORN SHELL}\label{sec:Chapter1} +\pagenumbering{arabic} % Iniciar numeración desde 1 en números arábigos +\input{./Secciones/Capitulo1} + +\chapter{EDICIÓN DESDE LA LÍNEA DE COMANDOS}\label{sec:Chapter2} +\input{./Secciones/Capitulo2} + +\chapter{PERSONALIZACIÓN DEL ENTORNO}\label{sec:Chapter3} +\input{./Secciones/Capitulo3} + +\chapter{PROGRAMACIÓN BÁSICA DE SHELL}\label{sec:Chapter4} +\input{./Secciones/Capitulo4} + +\chapter{CONTROL DE FLUJO}\label{sec:Chapter5} +\input{./Secciones/Capitulo5} + +\chapter{OPCIONES DE LA LÍNEA DE COMANDOS Y VARIABLES TIPOGRÁFICAS}\label{sec:Chapter6} +\input{./Secciones/Capitulo6} + +\chapter{ENTRADA/SALIDA Y PROCESAMIENTO DESDE LA LÍNEA DE COMANDOS}\label{sec:Chapter7} +\input{./Secciones/Capitulo7} + +\chapter{MANEJO DE PROCESOS}\label{sec:Chapter8} +\input{./Secciones/Capitulo8} + +\chapter{DEPURACIÓN DE PROGRAMAS DEL SHELL}\label{sec:Chapter9} +\input{./Secciones/Capitulo9} + +\chapter{ADMINISTRACIÓN DE KORN SHELL}\label{sec:Chapter10} +\input{./Secciones/Capitulo10} + +\appendix +\chapter{SHELLS RELACIONADOS}\label{sec:ApendiceA} +\input{./Secciones/ApendiceA} + +\chapter{INFORMACIÓN DE REFERENCIA}\label{sec:ApendiceB} +\input{./Secciones/ApendiceB} + +\chapter{CONSTRUCCIÓN DE KSH A PARTIR DEL CÓDIGO FUENTE} +\input{./Secciones/ApendiceC}\label{sec:ApendiceC} + +\chapter{ACUERDO DE LICENCIA DE CÓDIGO FUENTE DE AT\&T ast}\label{sec:ApendiceD} +\input{./Secciones/ApendiceD} + +\end{document} diff --git a/Imagenes/Portada.png b/Imagenes/Portada.png new file mode 100644 index 0000000..205241c Binary files /dev/null and b/Imagenes/Portada.png differ diff --git a/Imagenes/fig_01.png b/Imagenes/fig_01.png new file mode 100644 index 0000000..a37699f Binary files /dev/null and b/Imagenes/fig_01.png differ diff --git a/Imagenes/fig_02.png b/Imagenes/fig_02.png new file mode 100644 index 0000000..e42bddf Binary files /dev/null and b/Imagenes/fig_02.png differ diff --git a/Imagenes/fig_03.png b/Imagenes/fig_03.png new file mode 100644 index 0000000..65f7ac1 Binary files /dev/null and b/Imagenes/fig_03.png differ diff --git a/Imagenes/fig_04.png b/Imagenes/fig_04.png new file mode 100644 index 0000000..5623e05 Binary files /dev/null and b/Imagenes/fig_04.png differ diff --git a/Imagenes/fig_05.png b/Imagenes/fig_05.png new file mode 100644 index 0000000..804ea18 Binary files /dev/null and b/Imagenes/fig_05.png differ diff --git a/Imagenes/fig_06.png b/Imagenes/fig_06.png new file mode 100644 index 0000000..9148ab6 Binary files /dev/null and b/Imagenes/fig_06.png differ diff --git a/Imagenes/fig_07.png b/Imagenes/fig_07.png new file mode 100644 index 0000000..84ea73b Binary files /dev/null and b/Imagenes/fig_07.png differ diff --git a/Imagenes/fig_08.png b/Imagenes/fig_08.png new file mode 100644 index 0000000..f90dc63 Binary files /dev/null and b/Imagenes/fig_08.png differ diff --git a/Imagenes/fig_09.png b/Imagenes/fig_09.png new file mode 100644 index 0000000..321409b Binary files /dev/null and b/Imagenes/fig_09.png differ diff --git a/Imagenes/fig_10.png b/Imagenes/fig_10.png new file mode 100644 index 0000000..2805b9d Binary files /dev/null and b/Imagenes/fig_10.png differ diff --git a/Secciones/ApendiceA.tex b/Secciones/ApendiceA.tex new file mode 100644 index 0000000..d33a9e8 --- /dev/null +++ b/Secciones/ApendiceA.tex @@ -0,0 +1,860 @@ +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 <> 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 <> 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 <> 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 <>.} +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 <> 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 <> 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 <> 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 <>; 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 <> 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 <> mostrando una pequeña ventana con un botón <>. 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 <> 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 <> 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 <>. 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. diff --git a/Secciones/ApendiceB.tex b/Secciones/ApendiceB.tex new file mode 100644 index 0000000..8623bcd --- /dev/null +++ b/Secciones/ApendiceB.tex @@ -0,0 +1,813 @@ +Este apéndice contiene listas de referencia para opciones de invocación, comandos incorporados y palabras clave, alias predefinidos, variables de shell incorporadas, operadores de \emph{prueba}, opciones de shell, opciones de \emph{typeset}, aritmética, comandos en modo \emph{emacs} y comandos de control en modo \emph{vi}. Además, describe cómo utilizar todas las facilidades del comando incorporado \emph{getopts}. + +\section{Opciones de invocación} +Esta es una lista de las opciones que puede usar cuando invoque al shell Korn. Además de éstas, se puede utilizar cualquier opción establecida en la línea de órdenes; consulte la tabla de opciones más adelante en este apéndice. Los intérpretes de comandos de inicio de sesión suelen invocarse con las opciones \texttt{-i} (interactivo), \texttt{-s} (leer de la entrada estándar) y \texttt{-m} (habilitar el control de trabajos). + +\begin{table}[h] + \center + \begin{tabular}{|m{2cm}|m{13cm}|} \hline + \textbf{Opción} & \textbf{Significado} \\ \hline + -c \emph{string} & Ejecuta \emph{string} y después sale \\\hline + -D & Imprime todas las cadenas \texttt{\$"..."} del script. Esto se utiliza para crear una base de datos de traducciones específicas de cada idioma de las cadenas de un script. \\\hline + -i & Shell interactivo. Ignora las señales TERM, INTR y QUIT. \\\hline + -r & Shell restringido. Ver \hyperref[sec:Chapter10]{Capítulo 10} \\\hline + -R \emph{filename} & Crea una base de datos de referencias cruzadas para definiciones de variables y comandos en \emph{filename}. No se puede compilar. \\\hline + -s & Leer comandos de la entrada estándar. Si se proporciona un argumento, esta bandera tiene prioridad (es decir, el argumento no se tratará como un nombre de script y se leerá la entrada estándar). \\\hline + \end{tabular} +\end{table} + +\section{Comandos integrados y palabras clave} +He aquí un resumen de todos los comandos y palabras clave incorporados. + +\begin{longtable}[h]{|p{2cm}|p{3.5cm}|p{2cm}|p{7.5cm}|} \hline + \textbf{Nombre} & \small{\textbf{Comando / Palabra Clave}} & \textbf{Capítulo} & \textbf{Resumen} \\\hline + \endfirsthead + \hline + \textbf{Nombre} & \small{\textbf{Comando / Palabra Clave}} & \textbf{Capítulo} & \textbf{Resumen} \\\hline + \endhead + ! & Palabra clave & 5 & Invierte el resultado verdadero/falso de la siguiente tubería. \\\hline + : & Comando & 7 & No hacer nada (sólo hacer expansiones de argumentos). \\\hline + . & Comando & 4 & Leer archivo y ejecutar su contenido en el shell actual. \\\hline + alias & Comando & 3 & Establecer la abreviatura de comando o línea de comandos. \\\hline + bg & Comando & 8 & Poner trabajo en segundo plano. \\\hline + builtin & Comando & & Añade o elimina comandos incorporados; imprime información sobre ellos. \\\hline + break & Comando & 5 & Salir del bucle \texttt{for, select, while} o \texttt{until} circundante. \\\hline + case & Comando & 5 & Construcción condicional multidireccional. \\\hline + cd & Comando & 1 & Cambiar el directorio de trabajo. \\\hline + command & Comando & 5 & Localizar comandos integrados y externos; encontrar un comando integrado en lugar de una función con el mismo nombre. \\\hline + continue & Comando & 4 & Salta a la siguiente iteración del bucle \texttt{for, select, while} o \texttt{until}. \\\hline + disown & Comando & 8 & Desasociar un trabajo en segundo plano del shell actual. El efecto es que el trabajo no recibe la señal HUP cuando el shell sale. \\\hline + echo & Comando & 4 & Expandir e imprimir argumentos (obsoleto). \\\hline + exec & Comando & 9 & Sustituye el shell por el programa dado. \\\hline + exit & Comando & 5 & Salida del shell. \\\hline + export & Comando & 3 & Crear variables de entorno. \\\hline + eval & Comando & 7 & Procesa los argumentos como una línea de comandos. \\\hline + false & Comando & 8 & No hacer nada y salir sin éxito. Útil para hacer bucles infinitos. \\\hline + fg & Comando & 8 & Poner el trabajo de fondo en primer plano. \\\hline + for & Palabra clave & 5 & Construcción en bucle. \\\hline + function & Palabra clave & 4 & Definir función \\\hline + getconf & Comando & & Obtener información específica del sistema. Los parámetros están definidos por POSIX. \\\hline + getopts & Comando & 6 & Opciones de la línea de comandos del proceso. \\\hline + hist & Palabra clave & 2 & Trabajar con el historial de comandos. \\\hline + if & Comando & 1 & Construcción condicional. \\\hline + jobs & Comando & 1 & Enumera los trabajos de fondo. \\\hline + kill & Comando & 8 & Enviar señal al proceso. \\\hline + let & Comando & 6 & Asignación aritmética de variables. \\\hline + newgrp & Comando & & Iniciar nuevo shell con nuevo ID de grupo (obsoleto). \\\hline + print & Comando & 1 & Expande e imprime los argumentos en la salida estándar. \\\hline + printf & Comando & 7 & Expande e imprime los argumentos en la salida estándar, utilizando los especificadores de formato \emph{printf(3)} de ANSI C. \\\hline + pwd & Comando & 1 & Imprimir directorio de trabajo. \\\hline + read & Comando & 7 & Leer una línea de la entrada estándar. \\\hline + readonly & Comando & 5 & Hacer que las variables sean de sólo lectura (no asignables). \\\hline + return & Comando & 5 & Retorno desde función o script circundante. \\\hline + select & Palabra clave & 5 & Constructo de generación de menús. \\\hline + set & Comando & 3 & Configura las opciones. \\\hline + shift & Comando & 6 & Cambia los argumentos de la línea de comandos. \\\hline + sleep & Comando & 8 & Suspende la ejecución durante el número de segundos indicado. \\\hline + test & Comando & 5 & Versión antigua del programa de prueba condicional. Utilice \texttt{[[...]]} en su lugar. \\\hline + time & Palabra clave & & Ejecuta el comando e imprime los tiempos de ejecución. Por sí mismo, imprime los tiempos acumulados para el shell y todos los hijos. \\\hline + trap & Comando & 8 & Establezca una rutina de captación de señales. \\\hline + true & Comando & 8 & No hacer nada y salir con éxito. Útil para hacer bucles infinitos. \\\hline + typeset & Comando & 6 & Establecer características especiales de variables y funciones. \\\hline + ulimit & Comando & 10 & Establecer/mostrar los límites de recursos del proceso. \\\hline + umask & Comando & 10 & Establecer/mostrar máscara de permisos de archivo. \\\hline + unalias & Comando & 3 & Eliminar definiciones de alias. \\\hline + unset & Comando & 3 & Eliminar definiciones de variables o funciones. \\\hline + until & Palabra clave & 5 & Construcción en bucle. \\\hline + wait & Comando & 8 & Espere a que termine(n) la(s) tarea(s) en segundo plano. \\\hline + whence & Comando & 3 & Identificar la fuente de mando. \\\hline + while & Palabra clave & 5 & Construcción en bucle. \\\hline +\end{longtable} + +Las asignaciones para los comandos \emph{alias, export, readonly} y \emph{typeset} se procesan como asignaciones de variables, en el sentido de que la expansión de tilde se realiza después del carácter =, y la división de campos no se realiza en ninguna sustitución de variable en el valor que se asigna. + +\section{Alias predefinidos} +Hay una serie de alias predefinidos, es decir, incorporados automáticamente a \emph{ksh} en tiempo de compilación. Están listados en la siguiente tabla. Tenga en cuenta que algunos de ellos se definen con un carácter de espacio al final. Esto permite la expansión del alias en la palabra que sigue al alias en la línea de comandos. + +\begin{table}[h] + \center + \begin{tabular}{|m{2cm}|m{2cm}|m{11cm}|} \hline + \textbf{Nombre} & \textbf{Capítulo} & \textbf{Valor completo} \\ \hline + autoload & 4, 6 & \texttt{alias autoload='typeset -fu'} \\\hline + command & 7 & \texttt{alias command='command '} \\\hline + fc & 2 & \texttt{alias fc=hist} \\\hline + float & 6 & \texttt{alias float='typeset -E'} \\\hline + functions & 6 & \texttt{alias functions='typeset -f'} \\\hline + hash & 3 & \texttt{alias hash='alias -t --'} \\\hline + history & 2 & \texttt{alias history='hist -l'} \\\hline + integer & 6 & \texttt{alias integer='typeset -i'} \\\hline + nameref & 4 & \texttt{alias nameref='typeset -n'} \\\hline + nohup & 3,8 & \texttt{alias nohup='nohup '} \\\hline + r & 2 & \texttt{alias r='hist -s'} \\\hline + redirect & 9 & \texttt{alias redirect='command exec'} \\\hline + stop & 8 & \texttt{alias stop='kill -s STOP'} \\\hline + times & & \texttt{alias time='\{ \{time;\} 2>\&1;\}'} \\\hline + type & 4 & \texttt{alias type='whence -v'} \\\hline + \end{tabular} +\end{table} + +\section{Variables de Shell incorporadas} +He aquí un resumen de todas las variables de shell incorporadas: + +\begin{longtable}[h]{|p{3cm}|p{2cm}|p{10cm}|} \hline + \textbf{Variable} & \textbf{Capítulo} & \textbf{Significado}\\ \hline + \endfirsthead + \hline + \textbf{Variable} & \textbf{Capítulo} & \textbf{Significado}\\ \hline + \endhead + \# & 4 & Número de argumentos dados al proceso actual. \\\hline + 0 & 4 & Argumentos de línea de comandos para el proceso actual. Dentro de comillas dobles, se expande a argumentos individuales. \\\hline + * & 4 & Argumentos de línea de comandos para el proceso actual. Dentro de comillas dobles, se expande a un único argumento. \\\hline + - (guión) & & Opciones dadas al shell en la invocación. \\\hline + ? & 5 & Estado de salida del comando anterior. \\\hline + \$ & 8 & ID de proceso del proceso shell. \\\hline + \_ (guón bajo) & 3 & Dentro de \texttt{\$MAILPATH:} el nombre de archivo que activó el mensaje <>. En la línea de comandos: último argumento del comando anterior. Dentro de un script: la ruta completa utilizada para encontrar y ejecutar el script. \\\hline + ! & 8 & ID de proceso del último comando en segundo plano. \\\hline + .sh.edchar & 10 & Caracteres introducidos al procesar una trampa KEYBD. \\\hline + .sh.edcol & 10 & Posición del cursor en la trampa KEYBD más reciente. \\\hline + .sh.edmode & 10 & Igual a ESC en modo \emph{vi}, vacío en caso contrario. \\\hline + .sh.edtext & 10 & Caracteres en el búfer de entrada durante una trampa KEYBD. \\\hline + .sh.match & 4 & Variable de matriz con texto que coincide con el patrón en la sustitución de variables. (A partir de \emph{ksh93l}.) \\\hline + .sh.name & 9 & Nombre de una variable que ejecuta una función de disciplina. \\\hline + .sh.subscript & 9 & Subíndice de una variable de matriz que ejecuta una función de disciplina. \\\hline + .sh.value & 9 & Valor de la variable que ejecuta una función de disciplina. \\\hline + .sh.version & 4, 9 & Versión de \emph{ksh}. \\\hline + CDPATH & 3 & Lista de directorios en los que debe buscar el comando \emph{cd}. \\\hline + COLUMNS & 3 & Anchura de visualización en columnas (para los modos de edición y \texttt{select}). \\\hline + EDITOR & 2 & Se utiliza para establecer el modo de edición; también lo utilizan \emph{mail} y otros programas. Anulado por \texttt{VISUAL}, si está configurado. \\\hline + EMPV & 3 & Nombre del archivo que se ejecutará como archivo de entorno cuando se invoque al shell. \\\hline + FCEDIT & 2 & Editor por defecto obsoleto para el comando \emph{hist}. \\\hline + FIGNORE & 1 & Patrón para los archivos a ignorar durante la expansión del patrón. \\\hline + FPATH & 4 & Ruta de búsqueda de funciones autocargadas. \\\hline + HISTCMD & 2 & Número del comando actual en el historial de comandos. \\\hline + HISTEDIT & 2 & Editor por defecto para el comando \emph{hist} \\\hline + HISTFILE & 2 & Nombre del archivo de historial de comandos. \\\hline + HISTSIZE & 2 & Número de líneas guardadas en el archivo histórico. \\\hline + HOME & 3 & Directorio de inicio (login). \\\hline + IFS & 7 & Separador de campo interno: lista de caracteres que actúan como separadores de palabras. Normalmente se establece en espacio, TAB y nueva línea. \\\hline + LANG & & Nombre por defecto de la configuración regional actual; reemplazado por otras variables LC\_*. \\\hline + LC\_ALL & & Nombre de la configuración regional actual; sustituye a LANG y a las demás variables LC\_*. \\\hline + LC\_COLLATE & & Nombre de la configuración regional actual para la clasificación de caracteres. \\\hline + LC\_CTYPE & & Nombre de la configuración regional actual para determinar la clase de caracteres durante la comparación de patrones; véase el \hyperref[sec:Chapter4]{Capítulo 4}. \\\hline + LC\_NUMERIC & & Nombre de la configuración regional actual para el formato de los números (punto decimal, separador de miles). \\\hline + LINEO & 9 & Número de línea del script o función que se acaba de ejecutar. \\\hline + LINES & 3 & Altura de la pantalla en líneas (para el comando \texttt{select}). \\\hline + MAIL & 3 & Nombre del archivo para comprobar si hay correo nuevo. \\\hline + MAILCHECK & 3 & Frecuencia (en segundos) con la que se comprueba si hay correo nuevo. \\\hline + MAILPATH & 3 & Lista de nombres de archivo para comprobar si hay correo nuevo, si MAIL no está configurado. \\\hline + OLDPWD & 3 & Directorio de trabajo anterior. \\\hline + OPTARG & 6 & Argumento de la opción procesada por \emph{getopts}. \\\hline + OPTIND & 6 & Número del primer argumento después de las opciones. \\\hline + PATH & 3 & Ruta de búsqueda de comandos. \\\hline + PPID & 8 & ID del proceso padre. \\\hline + PS1 & 3 & String del símbolo del sistema principal. \\\hline + PS2 & 3 & String de solicitud de continuación de línea. \\\hline + PS3 & 5 & String de consulta para el comando \texttt{select}. \\\hline + PS4 & 9 & String de consulta para la opción \texttt{xtrace}. \\\hline + PWD & 3 & Directorio de trabajo actual. \\\hline + RANDOM & 9 & Número aleatorio entre 0 y 32767 ($2^15-1$). \\\hline + REPLY & 5, 7 & Respuesta del usuario al comando \texttt{select}; resultado del comando \emph{read} si no se dan nombres de variables. \\\hline + SECONDS & 3 & Número de segundos transcurridos desde que se invocó al shell. \\\hline + SHELL & 3 & Ruta completa de los programas shell que se deben utilizar para ejecutar comandos. \\\hline + TMOUT & 5, 7, 10 & Si se establece en un número entero positivo, número de segundos entre comandos tras los cuales el shell termina automáticamente. También se aplica a la lectura de respuestas a \texttt{select} y \emph{read}. \\\hline + VISUAL & 2 & Permite establecer el modo de edición. \\\hline +\end{longtable} + +\section{Operadores de prueba} +Son los operadores que se utilizan con la construcción \texttt{[[...]]}. Pueden combinarse lógicamente con \texttt{\&\&} (\texttt{"}y\texttt{"}) y \texttt{||} (\texttt{"}o\texttt{"}) y agruparse con paréntesis. Cuando se utilizan con nombres de archivo de la forma \texttt{/dev/fd/N}, comprueban el atributo correspondiente del descriptor de archivo abierto \emph{N}. + +\begin{longtable}{|p{4cm}|p{11cm}|} \hline + \textbf{Operador} & \textbf{Verdadero si} \\ \hline + \endfirsthead + \hline + \textbf{Operador} & \textbf{Verdadero si} \\ \hline + \endhead + -a file & \emph{file} existe (Obsoleto. \texttt{-e} es preferido) \\\hline + -b file & \emph{file} es un dispositivo de bloque \\\hline + -c file & \emph{file} es un dispositivo de caracteres \\\hline + -d file & \emph{file} es un directorio \\\hline + -e file & \emph{file} existe \\\hline + -f file & \emph{file} es un archivo regular \\\hline + -g file & \emph{file} tiene activado el bit de \emph{setgid} \\\hline + -G file & El ID de grupo de \emph{file} es el mismo que el ID de grupo efectivo del intérprete de comandos \\\hline + -h file & \emph{file} es un enlace simbólico \\\hline + -k file & \emph{file} tiene su bit \emph{sticky} activado \\\hline + -l file & \emph{file} es un enlace simbólico. (Solo funciona en sistemas en los que \texttt{/bin/test -l} comprueba si hay enlaces simbólicos \\\hline + -L file & \emph{file} es un enlace simbólico \\\hline + -n string & strin no es nulo \\\hline + -o option & Option está activado \\\hline + -O file & \emph{file} es propiedad del ID de usuario efectivo del intérprete de comandos \\\hline + -p file & \emph{file} es una tubería o una tubería con nombre ( archivo FIFO) \\\hline + -r file & \emph{file} tiene permisos de lectura \\\hline + -s file & \emph{file} no está vacío \\\hline + -S file & \emph{file} es un socket \\\hline + -t file & El descriptor de fichero \emph{N} apunta a una terminal \\\hline + -u file & \emph{file} tiene activado el bit \emph{setuid} \\\hline + -w file & \emph{file} tiene permisos de escritura \\\hline + -x file & \emph{file} tiene permisos de ejecución, o el archivo es un directorio en el que se puede buscar \\\hline + -z string & \emph{string} es nulo \\\hline + fileA -nt fileB & fileA es más reciente que file B, o fileB no existe \\\hline + fileA -ot fileB & fileA es más antiguo que fileB, o fileB no existe \\\hline + fileA -ef fileB & fileA y fileB apuntan al mismo archivo \\\hline + string = pattern & \emph{string} coincide con el patrón (que puede contener comodines). Obsoleto; se prefiere == \\\hline + string == pattern & \emph{String} coincide con el patrón (que puede contener comodines) \\\hline + string != pattern & String no coincide con el patrón \\\hline + stringA < stringB & \emph{StringA} está antes que \emph{StringB} en el orden del diccionario \\\hline + stringA > stringB & \emph{StringA} va después que \emph{StringB} en el orden del diccionario \\\hline + exprA -eq expB & Las expresiones aritméticas \emph{exprA} y \emph{exprB} son iguales \\\hline + exprA -ne exprB & Las expresiones aritméticas \emph{exprA} y \emph{exprB} no son iguales \\\hline + exprA -lt exprB & \emph{exprA} es menor que \emph{exprB} \\\hline + exprA -gt exprB & \emph{exprA} es mayor que \emph{exprB} \\\hline + exprA -le exprB & \emph{exprA} es menor o igual que \emph{exprB} \\\hline + exprA -ge exprB & \emph{exprA} es mayor o igual que \emph{exprB} \\\hline + \end{longtable} + +Los operadores \emph{-eq, -ne, -lt, -le, -gt} y \emph{-ge} se consideran obsoletos en \emph{ksh93}; en su lugar debe utilizarse el comando \emph{let} o \texttt{((...))}. + +Para =, == y !=, cite el patrón para realizar comparaciones literales de strings. + +\section{Opciones} +Son opciones que pueden activarse con el comando \texttt{set -o}. Todas están inicialmente desactivadas excepto donde se indique lo contrario. Las abreviaturas, cuando aparecen, son opciones de set que pueden utilizarse en lugar de la orden \texttt{set -o} completa (por ejemplo, \texttt{set -a} es una abreviatura de \texttt{set -o allexport}). En la mayoría de los casos, las abreviaturas son opciones del shell Bourne compatibles con versiones anteriores. Para desactivar una opción, utilice \texttt{set +o nombre largo} o \texttt{set +X}, donde \emph{nombre largo} y \emph{X} son la <> o la forma de <> de la opción, respectivamente. + +\begin{longtable}[h]{|p{2cm}|p{2.5cm}|p{11.5cm}|} \hline + \textbf{Opción} & \small{\textbf{Abreviatura}} & \textbf{Significado} \\ \hline + \endfirsthead + \hline + \textbf{Opción} & \small{\textbf{Abreviatura}} & \textbf{Significado} \\ \hline + \endhead + allexport & -a & Exporta todas las variables definidas posteriormente. \\\hline + bgnice & & Ejecuta todos los trabajos en segundo plano con prioridad reducida (activada por defecto). \\\hline + emacs & & Utilice la edición de línea de comandos estilo Emacs. \\\hline + errexit & -e & Salir del shell cuando un comando sale con un estado distinto de cero. \\\hline + gmacs & & Utiliza la edición de línea de comandos al estilo de Emacs, pero con un significado ligeramente diferente para CTRL-T (véase el capítulo 2). \\\hline + ignoreeof & & No permitir CTRL-D para salir del shell. \\\hline + keyword & -k & Ejecutar asignaciones en medio de líneas de comando. (Muy obsoleto.) \\\hline + markdirs & & Añade \texttt{/} a todos los nombres de directorio generados a partir de la expansión de comodines. \\\hline + monitor & -m & Activar el control de trabajos (activado por defecto). \\\hline + noclobber & -c & No permitir a > la redirección a archivos existentes. \\\hline + noexec & -n & Leer los comandos y comprobar si hay errores de sintaxis, pero no los ejecuta. \\\hline + noglob & -f & Desactivar la expansión de comodines. \\\hline + nolog & & Desactivar el historial de comandos para las definiciones de funciones. \\\hline + notify & -b & Imprime mensajes de finalización de trabajo inmediatamente, en lugar de esperar a la siguiente solicitud. \\\hline + nounset & -u & Tratar las variables indefinidas como errores, no como nulos. \\\hline + pipefail & & Espera a que se completen todos los trabajos de una cadena. El estado de salida es el del último comando que falló, o cero en caso contrario. (\emph{ksh93g} y posteriores). \\\hline + privileged & -p & El script se ejecuta en modo \emph{suid}. \\\hline + trackall & -h & Crea un alias para cada ruta completa encontrada en una búsqueda de comandos. (\emph{ksh93} ignora esta opción; el comportamiento es siempre activado, incluso si esta opción está desactivada). \\\hline + verbose & -v & Imprime los comandos (textualmente) antes de ejecutarlos. \\\hline + vi & & Utilice la edición de línea de comandos estilo \emph{vi}. \\\hline + viraw & & Utilice el modo \emph{vi} y haga que cada pulsación de tecla tenga efecto inmediatamente. (Esto es necesario en algunos sistemas muy antiguos para que el modo \emph{vi} funcione, y es necesario en todos los sistemas para poder usar TAB para completar. A partir de \emph{ksh93n}, se habilita automáticamente cuando se usa \emph{vi-mode}). \\\hline + xtrace & -x & Imprime los comandos (después de las expansiones) antes de ejecutarlos. \\\hline +\end{longtable} + +El comando set tiene algunas opciones adicionales que no tienen sus correspondientes versiones set -o, como se indica a continuación: + +\begin{table}[h] + \center + \begin{tabular}{|m{2cm}|m{13cm}|} \hline + \textbf{Opción} & \textbf{Significado} \\ \hline + set -A ... & Asignación de matrices indexadas. \\\hline + set -s & Ordena los parámetros posicionales. \\\hline + set -t & Leer y ejecutar un comando, y luego salir. (Obsoleto.) \\\hline + \end{tabular} +\end{table} + +\section{Opciones tipográficas} +Estas son las opciones del comando \emph{typeset}. Utilice \texttt{+option} para desactivar una opción, por ejemplo, \texttt{typeset +x foo} para dejar de exportar la variable foo. + +\begin{longtable}[h]{|p{2.5cm}|p{12.5cm}|} \hline + \textbf{Opción} & \textbf{Significado} \\ \hline + \endfirsthead + \hline + \textbf{Opción} & \textbf{Significado} \\ \hline + \endhead + & Sin opción, crear variable local dentro de la función. \\\hline + -A & Declarar variable como array asociativo. \\\hline + -E[\emph{n}] & Declara la variable como un número de punto flotante. Opcional \emph{n} es el número de cifras significativas. \\\hline + -F[\emph{n}] & Declara la variable como un número de punto flotante. Opcional \emph{n} es el número de dígitos significativos. \\\hline + -f & Sin argumentos, imprime todas las definiciones de funciones. \\\hline + -f \emph{fname} & Imprime la definición de la función \emph{fname}. \\\hline + +f & Imprime todos los nombres de las funciones. \\\hline + -ft & Activar el modo de rastreo para la(s) función(es) nombrada(s). \\\hline + +ft & Desactiva el modo de rastreo para la(s) función(es) nombrada(s). \\\hline + -fu & Definir nombre(s) dado(s) como función(es) \emph{autoloaded}. \\\hline + -fx & Obsoleto; no hace nada en \emph{ksh93}. \\\hline + -H & Asignación de nombres de archivo de Unix a host para sistemas no Unix. \\\hline + -i[\emph{n}] & Declara la variable como un entero. Opcional \emph{n} es la base de salida. \\\hline + -l & Convierte todas las letras a minúsculas. \\\hline + -L & Justificar a la izquierda y eliminar los espacios a la izquierda. \\\hline + -n & Declarar variable como \emph{nameref}. \\\hline + -p & Imprime comandos \emph{tipográficos} (\emph{typeset}) para volver a crear variables con los mismos atributos. \\\hline + -r & Hacer que la variable sea de sólo lectura. \\\hline + -R & Justificar a la derecha y eliminar los espacios finales. \\\hline + -t & Etiquetar la variable. (Obsoleto.) \\\hline + -u & Convierte todas las letras a mayúsculas. \\\hline + -ui[\emph{n}] & Declara la variable como un entero sin signo. Opcional \emph{n} es la base de salida. (\emph{ksh93m} y posteriores). \\\hline + -x & Variable de exportación, es decir, poner en el entorno para que se pase a los subprocesos. \\\hline + -Z[\emph{n}] & Justificar a la derecha y rellenar con ceros a la izquierda. \emph{n} es la anchura, o la anchura se establece a partir del valor utilizado en la primera asignación. \\\hline +\end{longtable} + +\section{Aritmética} +A partir de \emph{ksh93m}, la instalación de aritmética incorporada comprende un gran porcentaje de las expresiones del lenguaje C. Esto hace que el shell sea más atractivo como un lenguaje de programación completo. Las siguientes características están disponibles: + +\emph{Sufijos de tipo al final}\\ +Las constantes enteras pueden tener un sufijo \texttt{U} o \texttt{L} al final para indicar que son sin signo o largas, respectivamente. Aunque las versiones en minúsculas también se pueden usar, esto no se recomienda, ya que es fácil confundir una \texttt{l} (ele minúscula) con un 1 (uno). + +\emph{Constantes de caracteres en C} \\ +Se reconocen las constantes de caracteres individuales en C, entre comillas simples. Al igual que en C, actúan como constantes enteras. Por ejemplo: + +\begin{lstlisting}[language=bash] +$ typeset -i c +$ for ((c = 'a'; c <= 'z'; c++)) +> do print $c +> done +97 +98 +99 +100 +... +\end{lstlisting} + +\emph{Constantes octales y hexadecimales} \\ +Puedes utilizar el formato C para constantes octales (base 8) y hexadecimales (base 16). Las constantes octales comienzan con un 0 líder, y las constantes hexadecimales comienzan con un \texttt{0x} o \texttt{0X} líder. Por ejemplo: + +\begin{lstlisting}[language=bash] +$ print $((010 + 1)) # Octal 10 es decimal 8 +9 +$ print $((0x10 + 1)) # Hexadecimal 10 es decimal 16 +17 +\end{lstlisting} + +\emph{Aritmética con enteros sin signo} \\ +Al usar \texttt{typeset -ui}, puedes crear enteros sin signo. Los enteros regulares representan números positivos y negativos. Los enteros sin signo comienzan en 0, llegan hasta algún valor dependiente de la implementación y luego <> nuevamente a 0. Del mismo modo, restar 1 de 0 se envuelve en la otra dirección, dando como resultado el número sin signo más grande: + +\begin{lstlisting}[language=bash] +$ typeset -ui u=0 +$ let u-- +$ print $u +4294967295 +\end{lstlisting} + +\emph{Operadores y precedencia en C} \\ +\emph{ksh} admite el conjunto completo de operadores en C, con la misma precedencia y asociatividad. Los operadores se presentaron en detalle en el \hyperref[sec:Chapter6]{Capítulo 6} y se resumen nuevamente a continuación. + +\begin{longtable}[h]{|p{5cm}|p{6cm}|p{4cm}|} \hline + \textbf{Operador} & \textbf{Significado} & \textbf{Asociatividad} \\\hline + \endfirsthead + \hline + \textbf{Operador} & \textbf{Significado} & \textbf{Asociatividad} \\\hline + \endhead + \texttt{++ --} & Incremento y decremento, prefijo y postfijo & De izquierda a derecha \\\hline + \texttt{+ - ! \~{}} & Más y menos unarios; negación lógica y por bits & De derecha a izquierda \\\hline + \texttt{**} & Exponenciación \tablefootnote{\emph{ksh93m} y versiones más recientes. El operador ** no está en el lenguaje C.} & De derecha a izquierda \\\hline + \texttt{* ? / \%} & Multiplicación, división y resta & De izquierda a derecha \\\hline + \texttt{+ -} & Suma y resta & De izquierda a derecha \\\hline + \texttt{<< >>} & Desplazamiento de bits a izquierda y derecha & De izquierda a derecha \\\hline + \texttt{< <= > >=} & Comparaciones & De izquierda a derecha \\\hline + \texttt{== !=} & Iguales y no iguales & De izquierda a derecha \\\hline + \texttt{\&} & Bit a bit <> & De izquierda a derecha \\\hline + \texttt{\^{}} & <> exlusivo bit a bit & de Izquierda a derecha \\\hline + \texttt{|} & Bit a bit <> & De izquierda a derecha \\\hline + \texttt{\&\&} & AND lógico & De izquierda a derecha \\\hline + \texttt{||} & OR lógico & De izquierda a derecha \\\hline + \texttt{?:} & Expresión condicional & De derecha a izquierda \\\hline + \texttt{= += -= *= /= \%= \&= \^{}= <<= >>=} & Operadores de asignación & De derecha a izquierda \\\hline + \texttt{,} & Evaluación secuencial & De izquierda a derecha \\\hline +\end{longtable} + +\section{Comandos del modo Emacs} +Aquí tienes una lista completa de todos los comandos del modo de edición de emacs. Algunos de estos, como \texttt{ESC [ A,} representan secuencias de teclas de flecha de terminal estándar ANSI; se agregaron para \emph{ksh93h}. + +\begin{longtable}[h]{|p{3cm}|p{12cm}|} \hline + \textbf{Comando} & \textbf{Significado} \\\hline + \endfirsthead + \hline + \textbf{Comando} & \textbf{Significado} \\\hline + \endhead + CTRL-A & Mover al principio de la línea \\\hline + CTRL-B & Retroceder un carácter sin borrar \\\hline + CTRL-C & Capitalizar el carácter después del punto \\\hline + CTRL-D & Borrar un carácter hacia adelante \\\hline + CTRL-E & Mover al final de la línea \\\hline + CTRL-F & Avanzar un carácter \\\hline + CTRL-I (TAB) & Completar el nombre de archivo en la palabra actual (a partir de \emph{ksh93h}) \\\hline + CTRL-J & Igual que ENTER. \\\hline + CTRL-K & Borrar (<>) hacia adelante hasta el final de la línea \\\hline + CTRL-L & Limpiar pantalla \\\hline + CTRL-M & Igual que ENTER \\\hline + CTRL-N & Línea siguiente \\\hline + CTRL-O & Igual que ENTER, luego muestra la línea siguiente en el archivo de historial \\\hline + CTRL-P & Línea anterior \\\hline + CTRL-R & Buscar hacia atrás \\\hline + CTRL-T & Intercambiar los dos caracteres a cada lado del punto \\\hline + CTRL-U & Repetir el siguiente comando cuatro veces \\\hline + CTRL-V & Imprimir la versión del shell Korn \\\hline + CTRL-W & Borrar (<>) todos los caracteres entre el punto y la marca \\\hline + CTRL-X CTRL-E & Invocar el programa emacs en el comando actual \\\hline + CTRL-X CTRL-X & Intercambiar el punto y la marca \\\hline + CTRL-Y & Recuperar (<>) el último elemento eliminado \\\hline + CTRL-] x & Buscar hacia adelante x, donde x es cualquier carácter \\\hline + CTRL-@ & Establecer la marca en el punto \\\hline + DEL & Borrar un carácter hacia atrás \\\hline + CTRL-[ & Igual que ESC (en la mayoría de los teclados) \\\hline + ESC b & Mover una palabra hacia atrás \\\hline + ESC c & Cambiar la palabra después del punto a mayúsculas \\\hline + ESC d & Borrar una palabra hacia adelante \\\hline + ESC f & Mover una palabra hacia adelante \\\hline + ESC h & Borrar una palabra hacia atrás \\\hline + ESC l & Cambiar la palabra después del punto a minúsculas \\\hline + ESC p & Guardar caracteres entre el punto y la marca como si estuvieran borrados \\\hline + ESC CTRL-H & Borrar una palabra hacia atrás \\\hline + ESC CTRL-] x & Buscar hacia atrás x, donde x es cualquier carácter \\\hline + ESC ESPACIO & Establecer la marca en el punto \\\hline + ESC \# & Insertar línea en el archivo de historial para edición futura \\\hline + ESC DEL & Borrar una palabra hacia atrás \\\hline + ESC < & Mover al principio del archivo de historial \\\hline + ESC > & Mover al final del archivo de historial \\\hline + ESC . & Insertar última palabra en la línea de comando anterior después del punto \\\hline + ESC \_ & Igual que arriba \\\hline + ESC ESC & Hacer la completación de nombre de archivo/comando/variable en la palabra actual \\\hline + ESC * & Hacer la expansión de nombre de archivo/comando/variable en la palabra actual \\\hline + ESC = & Hacer la lista de nombre de archivo/comando/variable en la palabra actual \\\hline + ESC [ A & Línea anterior (\emph{ksh93h} y más reciente) \\\hline + ESC [ B & Línea siguiente (\emph{ksh93h} y más reciente) \\\hline + ESC [ C & Mover un carácter hacia adelante (\emph{ksh93h} y más reciente) \\\hline + ESC [ D & Mover un carácter hacia atrás (sin borrar) (\emph{ksh93h} y más reciente) \\\hline + ESC [ H & Mover al principio de la línea (\emph{ksh93h} y más reciente) \\\hline + ESC [ Y & Mover al final de la línea (\emph{ksh93h} y más reciente) \\\hline + Kill & El carácter de eliminación \emph{stty(1)}, a menudo CTRL-U o @ o CTRL-X. Esto borra todo en la línea. Escribirlo dos veces activa el modo <>, que emite un carácter de avance de línea para empezar en una nueva línea. Esto es apropiado para terminales solo de papel. \\\hline +\end{longtable} + +\section{Comandos del modo de control vi} +Aquí tienes una lista completa de todos los comandos de control en el modo \emph{vi}. Al igual que con los comandos del modo \emph{emacs}, las secuencias como \texttt{[ A} son para las teclas de flecha estándar ANSI y se agregaron para \emph{ksh93h}. + +\begin{longtable}[h]{|p{3cm}|p{12cm}|} \hline + \textbf{Comando} & \textbf{Significado} \\\hline + \endfirsthead + \hline + \textbf{Comando} & \textbf{Significado} \\\hline + \endhead +h & Mover a la izquierda un carácter \\\hline +[ & D Mover a la izquierda un carácter (\emph{ksh93h} y más reciente) \\\hline +l & Mover a la derecha un carácter \\\hline +space & Mover a la derecha un carácter \\\hline +[ C & Mover a la derecha un carácter (\emph{ksh93h} y más reciente) \\\hline +w & Mover a la derecha una palabra \\\hline +b & Mover a la izquierda una palabra \\\hline +W & Mover al principio de la siguiente palabra no en blanco \\\hline +B & Mover al principio de la palabra no en blanco precedente \\\hline +e & Mover al final de la palabra actual \\\hline +E & Mover al final de la palabra actual no en blanco \\\hline +0 & Mover al principio de la línea \\\hline +[ H & Mover al principio de la línea (\emph{ksh93h} y más reciente) \\\hline +\^{} & Mover al primer carácter no en blanco en la línea \\\hline +\$ & Mover al final de la línea \\\hline +[ Y & Mover al final de la línea (\emph{ksh93h} y más reciente) \\\hline +i & Insertar texto antes del carácter actual \\\hline +a & Insertar texto después del carácter actual \\\hline +I & Insertar texto al principio de la línea \\\hline +A & Insertar texto al final de la línea \\\hline +r & Reemplazar un carácter (no entra en modo de entrada) \\\hline +R & Sobrescribir el texto existente \\\hline +dh & Eliminar un carácter hacia atrás \\\hline +dl & Eliminar un carácter hacia adelante \\\hline +db & Eliminar una palabra hacia atrás \\\hline +dw & Eliminar una palabra hacia adelante \\\hline +dB & Eliminar una palabra no en blanco hacia atrás \\\hline +dW & Eliminar una palabra no en blanco hacia adelante \\\hline +d\$ & Eliminar hasta el final de la línea \\\hline +d0 & Eliminar hasta el principio de la línea \\\hline +D & Equivalente a d\$ (eliminar hasta el final de la línea) \\\hline +dd & Equivalente a 0d\$ (eliminar toda la línea) \\\hline +C & Equivalente a c\$ (eliminar hasta el final de la línea, entrar en modo de entrada) \\\hline +cc & Equivalente a 0\$ (eliminar toda la línea, entrar en modo de entrada) \\\hline +s & Equivalente a xi (eliminar el carácter actual, entrar en modo de entrada) \\\hline +S & Equivalente a cc (eliminar toda la línea, entrar en modo de entrada) \\\hline +x & Equivalente a dl (eliminar carácter hacia atrás) \\\hline +X & Equivalente a dh (eliminar carácter hacia adelante) \\\hline +k o - & Mover hacia atrás una línea [ A Mover hacia atrás una línea (\emph{ksh93h} y más reciente) \\\hline +j o + & Mover hacia adelante una línea \\\hline +[ B & Mover hacia adelante una línea (\emph{ksh93h} y más reciente) \\\hline +G & Mover a la línea dada por el recuento de repeticiones \\\hline +/string & Buscar hacia adelante la cadena \\\hline +?string & Buscar hacia atrás la cadena \\\hline +n & Repetir la búsqueda hacia adelante \\\hline +N & Repetir la búsqueda hacia atrás \\\hline +f x & Mover a la siguiente ocurrencia de x hacia la derecha \\\hline +F x & Mover a la ocurrencia anterior de x hacia la izquierda \\\hline +t x & Mover a la siguiente ocurrencia de x hacia la derecha, luego hacia atrás un espacio \\\hline +T x & Mover a la ocurrencia anterior de x hacia la izquierda, luego hacia adelante un espacio \\\hline +yh & Yankar un carácter hacia atrás \\\hline +yl & Yankar un carácter hacia adelante \\\hline +yb & Yankar una palabra hacia atrás \\\hline +yw & Yankar una palabra hacia adelante \\\hline +yB & Yankar una palabra no en blanco hacia atrás \\\hline +yW & Yankar una palabra no en blanco hacia adelante \\\hline +y\$ & Yankar hasta el final de la línea \\\hline +y0 & Yankar hasta el principio de la línea \\\hline +Y & Equivalente a y\$ (yankar hasta el final de la línea) \\\hline +yy & Equivalente a 0y\$ (yankar toda la línea) \\\hline +u & Deshacer el último cambio de edición \\\hline +U & Deshacer todos los cambios de edición realizados en la línea \\\hline +. (punto) & Repetir el último comando de edición \\\hline +| & Mover a la posición absoluta de la columna \\\hline +; & Rehacer el último comando de búsqueda de caracteres \\\hline +, & Rehacer el último comando de búsqueda de caracteres, pero en dirección opuesta \\\hline +\% & Mover a la coincidencia de (, ), \{, \}, [, o ] \\\hline +\textbackslash{} & Realizar la completación de nombre de archivo/comando/variable \\\hline +CTRL-I (TAB) & Realizar la completación de nombre de archivo/comando/variable (solo para \texttt{set -o viraw}) (a partir de \emph{ksh93h}) \\\hline +* & Realizar la expansión de nombre de archivo/comando/variable (en la línea de comandos) \\\hline += & Realizar la expansión de nombre de archivo/comando/variable (como lista impresa) \\\hline +\~{} & Invertir (<>) mayúsculas y minúsculas del carácter actual \\\hline +\_ & Anexar la última palabra del comando anterior, entrar en modo de entrada \\\hline +v & Ejecutar el comando hist en la línea actual (en realidad, ejecutar el comando \texttt{hist -e \$\{VISUAL:-\$\{EDITOR:-vi\}\}}); generalmente esto significa ejecutar \emph{vi} completo en la línea actual \\\hline +CTRL-J & Igual que ENTER \\\hline +CTRL-L & Iniciar una nueva línea y volver a dibujar la línea actual en ella \\\hline +CTRL-M & Igual que ENTER \\\hline +CTRL-V & Imprimir la versión del shell Korn \\\hline +\# & Agregar \# (carácter de comentario) a la línea y enviarlo. Si la línea comienza con \#, quitar el \# inicial y todos los \# iniciales después de cualquier salto de línea incrustado \\\hline +@ x & Insertar expansión de alias \_x como entrada de modo de comando \\\hline +\end{longtable} + +\section{Uso de getopts} +El comando \emph{getopts} es extremadamente capaz. Con él, puedes hacer que tus scripts de shell acepten opciones largas, especificar que los argumentos son opcionales o numéricos, y proporcionar descripciones de los argumentos y valores para que las opciones \texttt{-?, --man, --html} y \texttt{--nroff} funcionen de la misma manera para tu programa que para los comandos internos de \emph{ksh93}. + +El precio por este poder es la complejidad del <> de descripción de opciones. Basándonos en una descripción proporcionada por el Dr. Glenn Fowler de AT\&T Research, describimos cómo evolucionaron las facilidades, cómo funcionan y resumimos cómo usarlas en tus propios programas. Usamos el comando getopts extendido en la solución para la \hyperref[box:B-1]{Tarea B-1}. + +\begin{mybox}[Tarea B-1]\label{box:B-1} +Diseña el programa \emph{phaser4}, que combina las características de los programas \emph{phaser3} y \emph{tricorder}. Asegúrate de que sea autosuficiente.\footnote{No, las paredes de mi habitación no están cubiertas de pósters de Star Trek. Superé eso hace mucho tiempo, y además, mi esposa no me dejaría de todos modos. ADR.} +\end{mybox} + +El primer paso es describir las opciones. Esto se hace con un comentario en la parte superior del script: + +\begin{lstlisting}[language=bash] +# uso: phaser4 [ opciones ] archivos +# -k, --kill usar configuración de eliminación (predeterminado) +# -l n, --level n establecer el nivel del phaser (predeterminado = 2) +# -s, --stun usar configuración solo de aturdimiento +# -t [lf], --tricorder [lf] modo tricorder, escaneo opcional para forma de vida lf +\end{lstlisting} + +Ahora comienza la diversión. Este esquema de capacidades sigue el orden en que se agregaron funciones a \emph{getopts}. + +\begin{enumerate} + \item Comienza con el comando \emph{getopts} como se describe en el \hyperref[sec:Chapter6]{Capítulo 6}. Esto produce una cadena de opciones simple que solo permite opciones de una sola letra: + +\begin{lstlisting}[language=bash] +USAGE="kl#st:" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Añade una descripción textual para el argumento de opción. Esto se hace encerrando texto arbitrario entre [ y ]: + +\begin{lstlisting}[language=bash] +USAGE="kl#[level]st:[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Permite un valor predeterminado para el argumento de una opción. Esto se hace especificando \texttt{:= value} dentro de la descripción entre corchetes: + +\begin{lstlisting}[language=bash] +USAGE="kl#[level:=2]st:[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Añade ? después de : para indicar un argumento opcional: + +\begin{lstlisting}[language=bash] +USAGE="kl#[level:=2]st:?[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Permite opciones largas que comienzan con \texttt{--}. Esto se hace usando \texttt{[let:long]} en lugar de la única letra de opción: + +\begin{lstlisting}[language=bash] +USAGE="[k:kill]" +USAGE+="[l:level]#[level:=2]" +USAGE+="[s:stun]" +USAGE+="[t:tricorder]:?[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + +Aquí, hemos dividido cada opción en su propia línea para facilitar el seguimiento y las hemos concatenado usando el operador de asignación +=. Ten en cuenta que no hay saltos de línea en la cadena. + + \item Dentro de los corchetes cuadrados de una letra de opción, permite que siga un texto descriptivo después de un signo de interrogación. Este texto se ignora, al igual que cualquier carácter de espacio en blanco, incluidos los saltos de línea: + +\begin{lstlisting}[language=bash] +USAGE="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Ahora se pone interesante. Los encabezados de sección al estilo de la página man de Unix vienen \emph{antes} de la descripción de la opción. Se distinguen de las descripciones de las opciones al comenzar con un + dentro de corchetes cuadrados: + +\begin{lstlisting}[language=bash] +USAGE="[+NOMBRE?phaser4 --- phaser y tricorder combinados]" +USAGE+="[+DESCRIPCIÓN?El programa phaser4 combina la operación " +USAGE+="de los programas phaser3 y tricorder en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + +Observa que \emph{getopts} comprende automáticamente que la descripción real de las opciones viene después de los encabezados de la página man; no hay un explícito \texttt{[+OPTIONS?...]} en el texto del string. + + \item Se puede proporcionar texto adicional descriptivo para el resumen de uso corto después de la descripción de las opciones, separado por dos saltos de línea: + +\begin{lstlisting}[language=bash] +USAGE="[+NOMBRE?phaser4 --- phaser y tricorder combinados]" +USAGE+="[+DESCRIPCIÓN?El programa phaser4 combina la operación " +USAGE+="de los programas phaser3 y tricorder en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +USAGE+=$'\n\narchivo ...\n\n' # Usa cadena ANSI C para el carácter \n +USAGE+="[+VER TAMBIÉN?phaser3(1), tricorder(1)]" +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Para indicar texto que debe cursivarse, enciérralo entre pares de caracteres \textbackslash{}a. Para indicar texto que debe ponerse en negrita, enciérralo entre pares de caracteres \textbackslash{}b: + +\begin{lstlisting}[language=bash] +USAGE="[+NOMBRE?phaser4 --- phaser y tricorder combinados]" +USAGE+="[+DESCRIPCIÓN?El programa \aphaser4\a combina la operación " +USAGE+="de los programas \aphaser3\a y \atricorder\a en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +USAGE+=$'\n\narchivo ...\n\n' # Usa cadena ANSI C para el carácter \n +USAGE+=$'[+VER TAMBIÉN?\aphaser3\a(1), \atricorder\a(1)]' +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Es posible un control dinámico de la salida descriptiva. Para hacer esto, escribe una función que imprima lo que desees y luego encierra el nombre de la función entre un par de caracteres \textbackslash{}f: \textbackslash{}fname\textbackslash{}f (esto no es necesario para phaser4). + + \item Si una opción (o cualquier otra cosa) necesita una descripción detallada, encerrar el texto entre { y } crea una lista sangrada. Esto es particularmente útil para describir diferentes valores de opción: + +\begin{lstlisting}[language=bash] +USAGE="[+NOMBRE?phaser4 --- phaser y tricorder combinados]" +USAGE+="[+DESCRIPCIÓN?El programa \aphaser4\a combina la operación " +USAGE+="de los programas \aphaser3\a y \atricorder\a en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]{ Añadir descripciones de valores + [level=0-2?configuraciones no letales] + [level=3-10?letales, usar con precaución] +}" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +USAGE+=$'\n\narchivo ...\n\n' # Usa cadena ANSI C para el carácter \n +USAGE+=$'[+VER TAMBIÉN?\aphaser3\a(1), \atricorder\a(1)]' +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Casi terminado. El texto entre corchetes cuadrados que comienza con un signo menos proporciona información de versión e identificación. Tal texto va al principio. El ítem vacío indica una versión y puede contener tanto cadenas de SCCS como de RCS, como se muestra aquí: + +\begin{lstlisting}[language=bash] +USAGE=$'[-?\n@(#)$Id: phaser4 (Investigación y Desarrollo de la Flota Estelar)' +USAGE+=$' Stardate 57234.22 $\n]' +USAGE+="[-autor?J. Programador ]" +USAGE+="[-derechos?Copyright (c) Stardate 57000 Flota Estelar.]" +USAGE+="[-licencia?http://www.starfleet.mil.fed/weapons-license.xml23]" +USAGE+="[+NOMBRE?phaser4 --- phaser y tricorder combinados]" +USAGE+="[+DESCRIPCIÓN?El programa \aphaser4\a combina la operación " +USAGE+="de los programas \aphaser3\a y \atricorder\a en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de eliminación (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]{ + [level=0-2?configuraciones no letales] + [level=3-10?letales, usar con precaución] +}" +USAGE+="[s:stun?¡Solo aturdimiento!]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +USAGE+=$'\n\narchivo ...\n\n' # Usa cadena ANSI C para el carácter \n +USAGE+=$'[+VER TAMBIÉN?\aphaser3\a(1), \atricorder\a(1)]' +while getopts "$USAGE" optchar ... +\end{lstlisting} + + \item Finalmente, permite escapes dentro de las cadenas. \texttt{]]} representa un corchete de cierre literal cuando \emph{getopts} de otra manera podría interpretarlo como un corchete de cierre. De manera similar, ?? representa un signo de interrogación literal que de otra manera podría iniciar una descripción. +\end{enumerate} + +Uff, ¡eso es mucha información! Sin embargo, verlo en el orden en que se agregó ayuda a que tenga sentido. Aquí tienes un resumen de los elementos que van en la cadena de uso, en el orden que requiere `getopts`: + +\begin{enumerate} + \item Las cadenas de identificación para la versión, autor, licencia, etc., son la primera parte. Están encerradas en corchetes y comienzan con un signo menos. El nombre del ítem, como <>, sigue el signo menos y termina en un signo de interrogación. Después del signo de interrogación viene la información asociada. + +El ítem vacío indica información de versión y debe tener la forma mostrada anteriormente; \emph{getopts} elimina los caracteres de identificación especiales de SCCS y RCS. + + \item Las secciones y el texto de estilo de la página de manual de Unix vienen a continuación. Están encerrados en corchetes y comienzan con un signo más. El nombre de la sección termina en el carácter ?, y el texto descriptivo sigue. + +El texto separado por dos nuevas líneas desde la descripción de las opciones se añade al mensaje breve de uso. + + \item Las descripciones de las opciones forman la tercera sección. Todavía se permite la forma corta original, como se describió en el \hyperref[sec:Chapter6]{Capítulo 6}: + \begin{itemize} + \item Usa : para opciones que requieren argumentos. + \item Usa \# para opciones que requieren argumentos numéricos. + \item Usa :? y \#? para opciones que permiten argumentos pero no los requieren. + \end{itemize} + + \item Sigue las opciones con un texto descriptivo entre [ y ]. Usa := dentro del texto descriptivo para especificar un valor predeterminado para un argumento de opción. + \item Las opciones largas se emparejan con una letra de opción corta encerrándolas entre corchetes y separándolas por dos puntos. Esto reemplaza la forma de una sola letra. + \item Encierra entre dos caracteres \texttt{\textbackslash{}a} los elementos que se deben cursivar. Encierra entre dos caracteres \texttt{\textbackslash{}\b} los elementos que se deben poner en negrita. Encierra el nombre de una función de personalización a llamar entre dos caracteres \texttt{\textbackslash{}f}. + \item Usa \{ y \} para encerrar descripciones de opciones anidadas e indentadas. + \item Sigue la sección de opciones con dos nuevas líneas y texto adicional para el resumen de las opciones cortas. + \item Usa \texttt{]]} para representar un corchete de cierre literal y \texttt{??} para representar un signo de interrogación literal. +\end{enumerate} + +Aquí está la versión esquelética de \emph{phaser4}: + +\begin{lstlisting}[language=bash] +#! /bin/ksh + +# uso: phaser4 [ opciones ] archivos +# -k, --kill usa la configuración de matar (predeterminado) +# -l n, --level n establece el nivel del phaser (predeterminado = 2) +# -s, --stun usa la configuración de aturdir +# -t [lf], --tricorder [lf] modo tricorder, escaneo opcional para la forma de vida lf + +USAGE=$'[-?\n@(#)$Id: phaser4 (Investigación y Desarrollo de la Flota Estelar)' +USAGE+=$' Fecha estelar 57234.22 $\n]' +USAGE+="[-autor?J. Programador ]" +USAGE+="[-copyright=Derechos de autor (c) Fecha estelar 57000 Flota Estelar.]" +USAGE+="[-licencia?http://www.flotaestelar.mil.fed/licencia-armas.xml23]" +USAGE+="[+NOMBRE?phaser4 --- combinación de phaser y tricorder]" +USAGE+="[+DESCRIPCIÓN?El programa \aphaser4\a combina la operación " +USAGE+="de los programas \aphaser3\a y \atricorder\a en una herramienta práctica.]" +USAGE+="[k:kill?Usar configuración de matar (predeterminado).]" +USAGE+="[l:level]#[level:=2?Establecer el nivel del phaser.]{ + [0-2?configuraciones no letales] + [3-10?letales, usar con precaución] +}" +USAGE+="[s:stun?Solo aturdir.]" +USAGE+="[t:tricorder?Modo tricorder.]:?[life_form]" +USAGE+=$'\n\narchivo ...\n\n' +USAGE+=$'[+VER TAMBIÉN?\aphaser3\a(1), \atricorder\a(1)]' + +kill=1 aturdir=0 nivel=2 # valores predeterminados +tricorder=0 phaser=1 +life_form= +while getopts "$USAGE" optchar ; do + case $optchar in + k) kill=1 aturdir=0 ;; + s) kill=0 aturdir=1 ;; + l) level=$OPTARG + if ((level < 0)) ; then + level=0 ; + fi + if ((level > 10)) ; then + level=10 ; + fi + ;; + t) phaser=0 tricorder=1 + life_form=${OPTARG:-"desconocido_general"} + ;; + esac +done + +print kill=$kill +print aturdir=$aturdir +print level=$level +print phaser=$phaser +print tricorder=$tricorder +print life_form=$life_form +\end{lstlisting} + +Aquí está la salida de \texttt{phaser4 --man}: + +\begin{lstlisting}[language=bash] + +NAME + phaser4 --- combinación de phaser y tricorder + +SYNOPSIS + phaser4 [ opciones ] archivo ... + +DESCRIPTION + El programa phaser4 combina la operación de los programas phaser3 y tricorder + en una herramienta práctica. + +OPTIONS + -k, --kill Usar configuración de kill (predeterminado). + -l, --level=level Establecer el level del phaser. + level=0-2 + configuraciones no letales + level=3-10 + letales, usar con precaución + El valor predeterminado es 2. +-s, --stun Solo aturdir. +-t, --tricorder[=life_form] + Modo tricorder. El valor de la opción puede omitirse. + +SEE ALSO + phaser3(1), tricorder(1) + +IMPLEMENTATION + version phaser4 (Investigación y Desarrollo de la Flota Estelar) Fecha estelar + 57234.22 + autor J. Programador + copyright Copyright (c) Fecha estelar 57000 Flota Estelar. + license http://www.flotaestelar.mil.fed/licencia-armas.xml23 +\end{lstlisting} diff --git a/Secciones/ApendiceC.tex b/Secciones/ApendiceC.tex new file mode 100644 index 0000000..f57d898 --- /dev/null +++ b/Secciones/ApendiceC.tex @@ -0,0 +1,123 @@ +Este apéndice describe cómo descargar binarios para \emph{ksh93}, así como cómo descargar el código fuente para \emph{ksh93} y construir una versión funcional. Deberías hacer esto si tu sistema no tiene \emph{ksh93} en absoluto o si necesitas alguna de las características que solo están disponibles en las versiones más recientes. + +\section{Sitios web de Korn Shell} +El punto de partida para todo lo relacionado con el shell Korn es \url{http://www.kornshell.com}, mantenido por David Korn, con enlaces agrupados en las siguientes categorías: + +\begin{description} + \item[Información] Al hacer clic en este enlace, se accede a una descripción general de una página sobre el shell Korn. + \item[Software] Al hacer clic en este enlace, se encuentran enlaces al sitio de descargas de AT\&T (ver la siguiente sección), algún código de ejemplo, un artículo en línea para \emph{dtksh} y un enlace para \emph{tksh}. Estos dos últimos se describen en el Apéndice A. + \item[Documentación] Este enlace lleva a una página con enlaces a información en línea, incluida información general, páginas de manual tanto para \emph{ksh88} como para \emph{ksh93}, libros y referencias sobre el shell Korn, y documentos sobre el shell Korn de diversas conferencias. + \item[Recursos] Una lista de enlaces a otros recursos en la web para \emph{ksh} y muchos de los otros shells descritos en el Apéndice A, como \emph{bash} y \emph{dtksh}. + \item[Diversión] David G. Korn, el programador, se encuentra con KoRN, el grupo de rock. Dicho y hecho. +\end{description} + +\section{Lo que puedes descargar} +\url{http://www.research.att.com/sw/download} es el punto de partida para descargar el software de \emph{ksh}. El software está cubierto por una licencia de estilo de código abierto. La versión actual de la licencia se encuentra en \url{http://www.research.att.com/sw/license/ast-open.html}. Esta licencia se reproduce en el Apéndice D. Deberías leerla y entenderla primero; si sus términos no son aceptables para ti, no deberías descargar el código fuente o binarios del software desde el sitio web de AT\&T. + +El software en el sitio web de AT\&T está disponible en diferentes <>, la mayoría de los cuales tienen nombres con el prefijo <>, que significa \emph{Advanced Software Tools} (Herramientas de Software Avanzado). Los paquetes de origen vienen como archivos tar comprimidos con \emph{gzip}, usando el sufijo de nombre de archivo \emph{.tgz}. Elige uno o más de los siguientes paquetes para descargar: + +\begin{description} + \item[ratz] Un programa ejecutable independiente para leer archivos tar comprimidos con \emph{gzip}. Úsalo si no tienes \emph{gzip} en tu sistema y no quieres molestarte en descargar y compilar \emph{gzip} primero. Puedes descargar el código fuente para este paquete o un ejecutable binario para cualquiera de las arquitecturas enumeradas en la Tabla \ref{Tab:C-1}. + \item[ksh] Esta es la forma más rápida de obtener un ejecutable de \emph{ksh93}. Hay versiones disponibles para las arquitecturas enumeradas en la Tabla \ref{Tab:C-1}. + \item[INIT] Este paquete debe descargarse al construir cualquiera de los siguientes paquetes fuente. Contiene los archivos y estructuras de directorio en los que dependen las herramientas y el sistema de construcción de AST. + \item[ast-ksh] Este paquete construye solo la infraestructura de soporte (bibliotecas, programas de prueba de entorno, etc.) para \emph{ksh} y el ejecutable \emph{ksh}. Es lo más sencillo de construir. + \item[ast-base] Este paquete construye todo en el paquete \emph{ast-ksh} y algunas herramientas AST básicas adicionales. En particular, incluye \emph{pax}, una herramienta de archivado que combina funciones de \emph{tar(1)} y \emph{cpio(1)}, y \emph{nmake}, una versión significativamente mejorada del programa estándar \emph{make(1)} de Unix. También incluye las bibliotecas \emph{sfio} (Safe Fast I/O) y \emph{ast}, que puedes usar para tus propios programas. + \item[ast-open] Este paquete construye todo en el paquete ast-base y muchas herramientas adicionales. Ten en cuenta que \emph{tksh} (ver Apéndice A) está incluido en este paquete. +\end{description} + +Cada uno de los paquetes (excepto \emph{INIT}) también está disponible como binarios precompilados. La Tabla C-1 enumera las arquitecturas disponibles para estos paquetes. También hay traducciones de locales para algunos locales y algunos programas. + +\begin{table}[h] + \center + \caption{Arquitecturas admitidas para programas AST} + \label{Tab:C-1} + \begin{tabular}{|m{3cm}|m{12cm}|} \hline + \textbf{Nombre} & \textbf{SO/Arquitectura} \\ \hline +darwin.ppc & Apple's MacOS X (también conocido como Darwin) para Motorola Power PC \\\hline +hp.pa & Hewlett-Packard HP-UX para HP Precision Architecture \\\hline +ibm.risc & AIX de IBM para RS/6000 \\\hline +linux.i386 & GNU/Linux en Intel 80386 y superior \\\hline +linux.s390 & GNU/Linux en el mainframe IBM S/390 \\\hline +mvs.390 & MVS de IBM en el mainframe IBM S/390 \\\hline +netbsd.i386 & NetBSD en Intel 80386 y superior (ver \url{http://www.netbsd.org}) \\\hline +openbsd.i386 & OpenBSD en Intel 80386 y superior (ver \url{http://www.openbsd.org}) \\\hline +osf.alpha & OSF/1 en el procesador Compaq (anteriormente Digital) Alpha \\\hline +sgi.mips3 & Silicon Graphics (SGI) Irix en el procesador MIPS \\\hline +sol.sun4 & Solaris 5.4 en la arquitectura Sun SPARC \\\hline +sol6.sun4 & Solaris 5.6 en la arquitectura Sun SPARC \\\hline +sol7.i386 & Solaris 7 en Intel 80386 y superior \\\hline +sol7.sun4 & Solaris 7 en la arquitectura Sun SPARC \\\hline +sol8.sun4 & Solaris 8 en la arquitectura Sun SPARC \\\hline +sun4 & SunOS 4.x en la arquitectura Sun SPARC \\\hline +unixware.i386 & UnixWare (la última versión oficial de System V) en Intel 80386 y superior \\\hline + \end{tabular} +\end{table} + +\section{Construcción de ksh (Shell Korn)} +Construir cualquiera de los paquetes a partir del código fuente es bastante sencillo. Todos los detalles, junto con preguntas frecuentes y notas, se encuentran en el sitio web de AT\&T. Aquí tienes una guía paso a paso de los pasos. Mostramos los pasos para el paquete \emph{ast-open}, pero son idénticos para los demás paquetes de código fuente. + +\begin{enumerate} + \item Asegúrate de tener un compilador de C para tu sistema. Se prefiere un compilador de C ANSI/ISO, pero un compilador K\&R también funcionará. Obtener un compilador de C si no tienes uno está más allá del alcance de este libro; contacta a tu administrador de sistema local. + \item Descarga el/los paquete(s) que deseas construir en un directorio vacío. Aquí, construimos el paquete ast-open del 31 de octubre de 2001: + +\begin{lstlisting}[language=bash] +$ ls +INIT.2001-10-31.tgz ast-open.2001-10-31.tgz +\end{lstlisting} + + \item Crea el directorio \texttt{lib/package/tgz} y mueve los archivos allí: + +\begin{lstlisting}[language=bash] +$ mkdir lib lib/package lib/package/tgz +$ mv *.tgz lib/package/tgz +\end{lstlisting} + + \item Extrae el paquete \emph{INIT} manualmente: + +\begin{lstlisting}[language=bash] +$ gzip -d < lib/package/tgz/INIT.2001-10-31.tgz | tar -xvpf - +\r\v\vNOTICE -- LICENSED SOFTWARE -- SEE README FOR DETAILS\r\v\v +README +src/Makefile +src/cmd/Makefile +src/lib/Makefile +... +\end{lstlisting} + +Si no tienes \emph{gzip}, usa el programa \emph{ratz}, como se describió anteriormente. + + \item Inicializa la lista de paquetes disponibles: + +\begin{lstlisting}[language=bash] +$ bin/package read +\r\v\vNOTICE -- LICENSED SOFTWARE -- SEE README FOR DETAILS\r\v\v +README +src/Makefile +src/cmd/Makefile +src/lib/Makefile +src/Mamfile +... +\end{lstlisting} + + \item Inicia la compilación. Este paso es bastante detallado y llevará un tiempo. La duración exacta depende de la velocidad de tu sistema y compilador, y del paquete que estás construyendo: + +\begin{lstlisting}[language=bash] +$ bin/package make +package: initialize the /home/arnold/ast-open/arch/linux.i386 view +package: update /home/arnold/ast-open/arch/linux.i386/bin/proto +package: update /home/arnold/ast-open/arch/linux.i386/bin/mamake +package: update /home/arnold/ast-open/arch/linux.i386/bin/ratz +package: update /home/arnold/ast-open/arch/linux.i386/bin/release +... +\end{lstlisting} + + \item Instala los archivos creados. Esto se puede hacer con el comando \texttt{bin/package install directory}, donde \emph{directory} es la ubicación para colocar las cosas. + +Alternativamente, si todo lo que te interesa es el binario de \emph{ksh}, simplemente puedes copiarlo. El binario compilado estará en un directorio llamado \texttt{arch/ARCH/bin}, donde \emph{ARCH} representa tu arquitectura, como \emph{linux.i386}: + +\begin{lstlisting}[language=bash] +cp arch/linux.i386/bin/ksh $HOME/bin/ksh93 +\end{lstlisting} + + \item{¡Disfruta!} +\end{enumerate} diff --git a/Secciones/ApendiceD.tex b/Secciones/ApendiceD.tex new file mode 100644 index 0000000..8926355 --- /dev/null +++ b/Secciones/ApendiceD.tex @@ -0,0 +1,99 @@ +\begin{textbf} +ACUERDO DE CÓDIGO FUENTE \\ +Versión 1.2D +\end{textbf} + +POR FAVOR, LEA ESTE ACUERDO DETENIDAMENTE. Al acceder y utilizar el \textbf{Código Fuente}, acepta este Acuerdo en su totalidad y se compromete a utilizar el \textbf{Código Fuente} únicamente de acuerdo con los siguientes términos y condiciones. Si no desea quedar vinculado por estos términos y condiciones, no acceda ni utilice el \textbf{Código Fuente}. + +\begin{enumerate} + \item TUS REPRESENTACIONES + \begin{itemize} + \item Declara y garantiza que: + \begin{enumerate} + \item Si eres una entidad, o un individuo que no es la persona que acepta este Acuerdo, la persona que acepta este Acuerdo en tu nombre es tu representante legalmente autorizado, debidamente autorizado para aceptar acuerdos de este tipo en tu nombre y obligarte a cumplir con sus disposiciones. + \item Has leído y comprendido completamente este Acuerdo en su totalidad. + \item Tus \textbf{Materiales de Construcción} son originales o no incluyen ningún \textbf{Software} obtenido bajo una licencia que entre en conflicto con las obligaciones contenidas en este Acuerdo. + \item Según tu leal saber y entender, tus \textbf{Materiales de Construcción} no infringen ni apropian indebidamente los derechos de ninguna persona o entidad. +Monitorizarás regularmente el Sitio web en busca de cualquier aviso. + \end{enumerate} + \end{itemize} + \item DEFINICIONES E INTERPRETACIÓN + \begin{enumerate} + \item A los efectos de este Acuerdo, ciertos términos se han definido a continuación y en otros lugares de este Acuerdo para abarcar significados que pueden diferir o agregarse a la connotación normal de la palabra definida. + \begin{enumerate} + \item \textbf{<>} significa \textbf{Software} en forma de código fuente que no contiene ningún + \begin{itemize} + \item \textbf{Código Fuente}, o + \item trabajo derivado (este término tiene el mismo significado en este Acuerdo que en la Ley de Derechos de Autor de EE. UU.) del \textbf{Código Fuente}. + \end{itemize} + \item \textbf{<>} significa, en referencia a un \textbf{Producto Derivado}, el \textbf{Parche} y el \textbf{Código Adicional}, si los hay, utilizados en la preparación de dicho \textbf{Producto Derivado}, junto con instrucciones escritas que describan, de manera razonable detallada, dicha preparación. + \item \textbf{<>} significa un archivo informático que contiene exactamente el mismo contenido que un archivo informático descargado del \textbf{Sitio web}. + \item \textbf{<>} significa un \textbf{Producto de Software} que es una obra derivada del \textbf{Código Fuente}. + \item \textbf{<>} significa todos los derechos protegibles bajo la ley de propiedad intelectual en cualquier lugar del mundo, incluidos los derechos protegibles bajo las leyes de patentes, derechos de autor y secretos comerciales, pero no los derechos de marca. + \item \textbf{<>} significa \textbf{Software} para cambiar toda o cualquier parte del \textbf{Código Fuente}. + \item \textbf{<>} significa la siguiente declaración: + +<>) propietarios de AT\&T Corp. (<>). El Software de AT\&T se proporciona tal cual. USTED ACEPTA TODA LA RESPONSABILIDAD Y RIESGO POR EL USO DEL SOFTWARE DE AT\&T. AT\&T NO REALIZA, Y RENUNCIA EXPRESAMENTE, CUALQUIER GARANTÍA EXPRESA O IMPLÍCITA DE NINGÚN TIPO, INCLUIDAS, SIN LIMITACIÓN, LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD O ADECUACIÓN PARA UN PROPÓSITO PARTICULAR, LAS GARANTÍAS DE TÍTULO O NO INFRACCIÓN DE NINGÚN DERECHO DE PROPIEDAD INTELECTUAL, CUALQUIER GARANTÍA QUE SURJA POR EL USO DEL COMERCIO, CURSO DE NEGOCIACIÓN O DESEMPEÑO, O CUALQUIER GARANTÍA DE QUE EL SOFTWARE DE AT\&T ES <> O CUMPLIRÁ CON SUS REQUISITOS. + +A menos que acepte una licencia para utilizar el Software de AT\&T, no debe descompilar, desensamblar o realizar ingeniería inversa de este producto para averiguar el código fuente de ningún Software de AT\&T. + +© AT\&T Corp. Todos los derechos reservados. AT\&T es una marca registrada de AT\&T Corp.>> + + \item \textbf{<>} significa, según lo que pueda requerir el contexto, instrucciones de código fuente u objeto para controlar el funcionamiento de una unidad central de procesamiento o computadora, y archivos informáticos que contienen datos o texto. + \item \textbf{<>} significa una colección de archivos informáticos que contienen \textbf{Software} solo en forma de código objeto, que, tomados en conjunto, comprenden razonablemente un producto, independientemente de si dicho producto está destinado para uso interno o explotación comercial. Un solo archivo informático puede constituir un \textbf{Producto de Software}. + \item \textbf{<>} significa el \textbf{Software} contenido en forma comprimida en la \textbf{Cápsula}. + \item \textbf{<>} significa el sitio web de Internet con la URL \url{http://www.research.att.com/sw/download/}. AT\&T puede \textbf{cambiar} el contenido o la URL del \textbf{Sitio web}, o eliminarlo por completo de Internet. + \end{enumerate} + \item A modo de aclaración solamente, los términos \textbf{Cápsula, Aviso Propietario} y \textbf{Código Fuente}, cuando se utilizan en este Acuerdo, significarán los materiales e información definidos por dichos términos sin ningún cambio, mejora, enmienda, alteración o modificación (colectivamente, \textbf{<>}). + \end{enumerate} + \item CONCESIÓN DE DERECHOS + \begin{enumerate} + \item Sujeto a reclamaciones de propiedad intelectual de terceros, si las hay, y a los términos y condiciones de este Acuerdo, AT\&T te otorga bajo: + \begin{enumerate} + \item Las \textbf{Reclamaciones de Patente} de AT\&T y los derechos de autor de AT\&T en el \textbf{Código Fuente}, una licencia no exclusiva y totalmente pagada para: + \begin{enumerate} + \item Reproducir y distribuir la \textbf{Cápsula}. + \item Mostrar, ejecutar, utilizar y compilar el \textbf{Código Fuente} y ejecutar el \textbf{Software} binario resultante en una computadora. + \item Preparar un \textbf{Producto Derivado} únicamente compilando \textbf{Código Adicional}, si lo hay, junto con el código resultante de operar un \textbf{Parche} en el \textbf{Código Fuente}. + \item Ejecutar en una computadora y distribuir a otros \textbf{Productos Derivados}, excepto que, con respecto a las \textbf{Reclamaciones de Patente de AT\&T}, los derechos de licencia otorgados en los incisos (iii) y (iv) anteriores solo se extenderán y limitarán a esa parte de un \textbf{Producto Derivado} que es un \textbf{Software} compilado a partir de alguna parte del \textbf{Código Fuente}; y, + \end{enumerate} + \item Los derechos de autor de AT\&T en el \textbf{Código Fuente}, una licencia no exclusiva y totalmente pagada para preparar y distribuir \textbf{Parches} para el \textbf{Código Fuente}. + \end{enumerate} + \item Sujeto a los términos y condiciones de este Acuerdo, puedes crear un hipervínculo entre un sitio web de Internet de tu propiedad y controlado por ti y el \textbf{Sitio web}, que describa de manera justa y de buena fe dónde se pueden obtener la \textbf{Cápsula} y el \textbf{Código Fuente}, siempre que no enmarques el \textbf{Sitio web} ni des la falsa impresión de que AT\&T está de alguna manera asociado, respalda o patrocina tu sitio web. Cualquier buena voluntad asociada con dicho hipervínculo será para el único beneficio de AT\&T. Además de la creación de dicho hipervínculo, nada en este Acuerdo se interpretará como que te confiere el derecho de usar cualquier referencia a AT\&T, sus nombres comerciales, marcas comerciales, marcas de servicio o cualquier otro indicio de origen propiedad de AT\&T, o indicar que tus productos o servicios están de alguna manera patrocinados, aprobados o respaldados por, o afiliados con, AT\&T. + \item Excepto según se establece expresamente en la Sección 3.1 anterior, no se otorgan ni otros derechos ni licencias bajo ninguna \textbf{IPR} de AT\&T ni, por implicación, impedimento o de otra manera, se confieren. A modo de ejemplo únicamente, no se otorgan ni se confieren derechos ni licencias bajo ninguna de las patentes de AT\&T ni, por implicación, impedimento o de otra manera, con respecto a ninguna parte de un \textbf{Producto Derivado} que no sea un \textbf{Software} compilado a partir de alguna parte, sin \textbf{cambios}, del \textbf{Código Fuente}. + \end{enumerate} + \item TUS OBLIGACIONES + \begin{enumerate} + \item Si distribuyes \textbf{Materiales de Construcción} (incluido si estás obligado a hacerlo en virtud de este Acuerdo), debes asegurarte de que el destinatario celebre y acepte debidamente un acuerdo contigo que incluya los términos mínimos establecidos en el Apéndice A (\url{http://www.research.att.com/sw/license/ast-terms.html}) (completado para indicar que eres el LICENCIANTE) y ninguna otra disposición que, en opinión de AT\&T, entre en conflicto con tus obligaciones según, o el propósito de, este Acuerdo. El acuerdo requerido en virtud de esta Sección 4.1 puede estar en forma electrónica y puede distribuirse con los \textbf{Materiales de Construcción} de una manera tal que el destinatario acepte el acuerdo mediante el uso o la instalación de los \textbf{Materiales de Construcción}. Si algún \textbf{Código Adicional} contenido en tus \textbf{Materiales de Construcción} incluye \textbf{Software} que obtuviste bajo licencia, el acuerdo también incluirá detalles completos sobre la licencia y cualquier restricción u obligación asociada con dicho \textbf{Software}. + \item Si preparas un Parche que distribuyes a cualquier otra persona, debes: + \begin{enumerate} + \item Ponerte en contacto con AT\&T, según se pueda proporcionar en el \textbf{Sitio web} o en un archivo de texto incluido con el \textbf{Código Fuente}, y describir para AT\&T dicho \textbf{Parche} y proporcionar a AT\&T una copia de dicho \textbf{Parche} según lo indique AT\&T; o, + \item Donde hagas tu \textbf{Parche} generalmente disponible en tu sitio web de Internet, debes proporcionar a AT\&T la URL de tu sitio web y, por la presente, otorgar a AT\&T un derecho no exclusivo y totalmente pagado para crear un hipervínculo entre tu sitio web y una página asociada al \textbf{Sitio web}. + \end{enumerate} + \item Si preparas un \textbf{Producto Derivado}, dicho producto debe mostrar de manera conspicua a los usuarios, y cualquier documentación y acuerdo de licencia correspondiente debe incluir como disposición el \textbf{Aviso Propietario}. + \end{enumerate} + \item TU CONCESIÓN DE DERECHOS A AT\&T + \begin{enumerate} + \item Concedes a AT\&T, bajo cualquier \textbf{propiedad intelectual de tu propiedad} o con licencia tuya que de alguna manera esté relacionada con tus \textbf{Parches}, una licencia no exclusiva, perpetua, mundial, totalmente pagada, sin restricciones, irrevocable, junto con el derecho de sublicenciar a otros, para (a) fabricar, hacer fabricar, usar, ofrecer en venta, vender e importar cualquier producto, servicio o cualquier combinación de productos o servicios, y (b) reproducir, distribuir, preparar trabajos derivados basados en, realizar, mostrar y transmitir tus Parches en cualquier medio, ya sea conocido ahora o desarrollado en el futuro. + \end{enumerate} + \item CLAUSULA <> / LIMITACIÓN DE RESPONSABILIDAD + \begin{enumerate} + \item El \textbf{Código Fuente} y la \textbf{Cápsula} se proporcionan <>. ASUMES LA RESPONSABILIDAD Y RIESGO TOTAL POR SU USO, INCLUYENDO EL RIESGO DE DEFECTOS O INEXACTITUDES. AT\&T NO REALIZA, Y RENUNCIA EXPRESAMENTE A, CUALQUIER GARANTÍA EXPRESA O IMPLÍCITA DE NINGÚN TIPO, INCLUYENDO, SIN LIMITACIÓN, LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD O ADECUACIÓN PARA UN PROPÓSITO PARTICULAR, GARANTÍAS DE TÍTULO O NO INFRACCIÓN DE CUALQUIER DERECHO DE PROPIEDAD INTELECTUAL O MARCA, CUALQUIER GARANTÍA QUE SURJA DEL USO DEL COMERCIO, CURSO DE TRATAMIENTO O DESEMPEÑO, O CUALQUIER GARANTÍA DE QUE EL CÓDIGO FUENTE O LA CÁPSULA SON <> O CUMPLIRÁN CON TUS REQUISITOS. + \item EN NINGÚN CASO AT\&T SERÁ RESPONSABLE DE (a) DAÑOS INCIDENTALES, CONSECUENTES O INDIRECTOS (INCLUYENDO, SIN LIMITACIÓN, DAÑOS POR PÉRDIDA DE BENEFICIOS, INTERRUPCIÓN DEL NEGOCIO, PÉRDIDA DE PROGRAMAS O INFORMACIÓN, Y SIMILARES) DERIVADOS DEL USO O LA INCAPACIDAD DE USAR EL \textbf{CÓDIGO FUENTE} O \textbf{LA CÁPSULA}, INCLUSO SI SE HA INFORMADO A AT\&T O A CUALQUIERA DE SUS REPRESENTANTES AUTORIZADOS DE LA POSIBILIDAD DE TALES DAÑOS, (b) CUALQUIER RECLAMO ATRIBUIBLE A ERRORES, OMISIONES U OTRAS INEXACTITUDES EN EL \textbf{CÓDIGO FUENTE} O \textbf{LA CÁPSULA}, O (c) CUALQUIER RECLAMO DE TERCEROS. + \item DEBIDO A QUE ALGUNOS ESTADOS NO PERMITEN LA EXCLUSIÓN O LIMITACIÓN DE RESPONSABILIDAD POR DAÑOS INCIDENTALES O CONSECUENTES, ES POSIBLE QUE LAS LIMITACIONES ANTERIORES NO SE APLIQUEN A TI. EN CASO DE QUE LA LEGISLACIÓN APLICABLE NO PERMITA LA EXCLUSIÓN O LIMITACIÓN TOTAL DE RESPONSABILIDAD DE RECLAMACIONES Y DAÑOS SEGÚN LO ESTABLECIDO EN ESTE ACUERDO, LA RESPONSABILIDAD DE AT\&T SE LIMITA EN LA MAYOR MEDIDA PERMITIDA POR LA LEY. + \end{enumerate} + \item INDEMNIZACIÓN + \begin{enumerate} + \item Indemnizarás y eximirás de responsabilidad a ATi\&T, sus afiliados y representantes autorizados contra cualquier reclamo, demanda o procedimiento presentado o iniciado por cualquier tercero y derivado de, o relacionado con, tu uso del \textbf{Código Fuente}. Esta obligación incluirá indemnizar contra todos los daños, pérdidas, costos y gastos (incluidos los honorarios de abogados) incurridos por AT\&T, sus afiliados y representantes autorizados como resultado de tales reclamaciones, demandas o procedimientos, incluidos los costos o gastos incurridos en la defensa contra tales reclamaciones, demandas o procedimientos. + \end{enumerate} + \item GENERAL + \begin{enumerate} + \item No presentarás contra AT\&T, sus afiliados o representantes autorizados ningún reclamo por infracción o apropiación indebida de cualquier \textbf{propiedad intelectual} o derechos de marca de alguna manera relacionados con el \textbf{Código Fuente}, incluidos aquellos relacionados con cualquier \textbf{Parche}. + \item En caso de que alguna disposición de este Acuerdo se considere ilegal o inaplicable, AT\&T puede, pero no está obligada a, publicar en el \textbf{sitio web} una nueva versión de este Acuerdo que, en opinión de AT\&T, preserve razonablemente la intención de este Acuerdo. + \item Tus derechos y licencia (pero no tus obligaciones) bajo este Acuerdo se terminarán automáticamente en caso de que (a) se publique en el \textbf{sitio web} un aviso de una reclamación no frívola de un tercero relacionada con el \textbf{Código Fuente} o la \textbf{Cápsula}, (b) tengas conocimiento de dicha reclamación, (c) alguna de tus representaciones o garantías en el Artículo 1.0 o la Sección 8.4 sean falsas o inexactas, (d) excedas los derechos y la licencia otorgados o (e) no cumplas completamente con cualquier disposición de este Acuerdo. Nada en esta disposición se interpretará para restringirte, a tu opción y sujeto a la ley aplicable, de reemplazar la parte del \textbf{Código Fuente} que sea objeto de una reclamación de un tercero con código no infractor o de negociar de manera independiente los derechos necesarios con el tercero. + \item Reconoces que el \textbf{Código Fuente} y la \textbf{Cápsula} pueden estar sujetos a las leyes y regulaciones de exportación de EE. UU. y, en consecuencia, garantizas a AT\&T que no violarás, directa o indirectamente, ninguna ley o regulación de exportación de los EE. UU. aplicable. + \item Sin limitar ninguno de los derechos de AT\&T en virtud de este Acuerdo o por ley o en equidad, ni ampliar de otra manera el alcance de la licencia y los derechos otorgados en virtud del presente, si no cumples con alguna de tus obligaciones bajo este Acuerdo con respecto a cualquiera de tus \textbf{Parches} o \textbf{Productos Derivados}, o si realizas cualquier acto que exceda el alcance de la licencia y los derechos otorgados en este documento, entonces dichos \textbf{Parches, Productos Derivados} y actos no están licenciados ni autorizados en virtud de este Acuerdo y dicho incumplimiento también se considerará una violación de este Acuerdo. Además de cualquier otro remedio disponible por cualquier violación de tus obligaciones bajo este Acuerdo, AT\&T tendrá derecho a una orden judicial que te obligue a cumplir con dichas obligaciones. + \item Este Acuerdo se regirá e interpretará de acuerdo con las leyes del Estado de Nueva York, EE. UU., sin tener en cuenta sus reglas de conflictos de leyes. Este Acuerdo será interpretado de manera justa de acuerdo con sus términos y sin ninguna interpretación estricta a favor o en contra de AT\&T o de ti. Cualquier demanda o procedimiento que presentes en relación con este Acuerdo deberá presentarse y tramitarse únicamente en Nueva York, Nueva York, EE. UU. + \end{enumerate} +\end{enumerate} diff --git a/Secciones/Capitulo1.tex b/Secciones/Capitulo1.tex new file mode 100644 index 0000000..39a4eee --- /dev/null +++ b/Secciones/Capitulo1.tex @@ -0,0 +1,782 @@ +Usted ha utilizado su ordenador para realizar tareas sencillas, como invocar sus programas de aplicación favoritos, leer su correo electrónico y quizás examinar e imprimir archivos. Sabe que su máquina ejecuta el sistema operativo Unix, o quizá lo conozca bajo algún otro nombre, como Solaris, HP-UX, AIX o SunOS. (O puede que esté utilizando un sistema como GNU/Linux o uno de los sistemas derivados de 4.4-BSD que no está basado en el código fuente original de Unix). Pero aparte de eso, puede que no hayas pensado demasiado en lo que ocurre dentro de la máquina cuando escribes un comando y pulsas ENTER. + +Es cierto que varias capas de eventos tienen lugar cada vez que introduces un comando, pero vamos a considerar sólo la capa superior, conocida como shell. En términos generales, un shell es cualquier interfaz de usuario para el sistema operativo Unix, es decir, cualquier programa que toma la entrada del usuario, la traduce en instrucciones que el sistema operativo puede entender, y transmite la salida del sistema operativo de vuelta al usuario. + +Hay varios tipos de interfaz de usuario. El shell Korn pertenece a la categoría más común, conocida como interfaces de usuario basadas en caracteres. Estas interfaces aceptan líneas de comandos textuales que el usuario escribe; normalmente producen una salida basada en texto. Otros tipos de interfaz incluyen las ahora comunes interfaces gráficas de usuario (GUI), que añaden la capacidad de mostrar gráficos arbitrarios (no sólo caracteres de máquina de escribir) y de aceptar entradas de ratones y otros dispositivos señaladores, interfaces de pantalla táctil (como las que se ven en algunos cajeros automáticos), etc. + +\section{¿Qué es un Shell?} +El trabajo del shell, entonces, es traducir las líneas de comando del usuario en instrucciones del sistema operativo. Por ejemplo, considere esta línea de comando: + +\begin{lstlisting}[language=bash] +sort -n phonelist > phonelist.sorted +\end{lstlisting} + +Esto significa: <> Esto es lo que hace el shell con este comando: +\begin{enumerate} + \item Divide la línea en los trozos \texttt{sort, -n, phonelist, >,} y \texttt{phonelist.sorted}. Estos trozos se llaman \emph{palabras}. + \item Determina el propósito de las palabras: \texttt{sort} es un comando; \texttt{-n} y \texttt{phonelist} son argumentos; \texttt{>} y \texttt{phonelist.sorted}, en conjunto, son instrucciones de E/S. + \item Establece la E/S según \texttt{> phonelist.sorted} (salida al archivo \emph{phonelist.sorted}) y algunas instrucciones estándar implícitas. + \item Busca el comando \emph{sort} en un archivo y lo ejecuta con la opción \emph{-n} (orden numérico) y el argumento \emph{phonelist} (nombre de archivo de entrada). +\end{enumerate} + +Por supuesto, cada paso implica realmente varios subpasos, y cada subpaso incluye una instrucción particular al sistema operativo subyacente. + +Recuerde que el shell en sí mismo no es Unix - sólo la interfaz de usuario para él. Esto se ilustra en la Figura \ref{fig1}. Unix es uno de los primeros sistemas operativos en hacer la interfaz de usuario independiente del sistema operativo. + +\begin{figure}[h!] + \centering + \includegraphics[scale=1]{fig_01} + \caption{\small{El shell es una capa alrededor del sistema operativo Unix}} + \label{fig1} +\end{figure} + +\section{Alcance de Este Libro} +En este libro, aprenderá sobre el shell Korn, que es el más reciente y potente de los shells distribuidos con los sistemas Unix comerciales. Hay dos formas de utilizar el shell Korn: como interfaz de usuario y como entorno de programación. + +Este capítulo y el siguiente cubren el uso interactivo. Estos dos capítulos deberían darle suficiente información para usar el shell con confianza y de forma productiva para la mayoría de sus tareas diarias. + +Después de haber utilizado el shell durante un tiempo, sin duda encontrará ciertas características de su entorno (la <> del shell) que le gustaría cambiar y tareas que le gustaría automatizar. El \hyperref[sec:Chapter3]{Capítulo 3} muestra varias formas de hacerlo. + +El \hyperref[sec:Chapter3]{Capítulo 3} también le prepara para la programación del shell, la cual se cubre en su mayor parte en los Capítulos \hyperref[sec:Chapter4]{4} a \hyperref[sec:Chapter6]{6}. No necesita tener ninguna experiencia en programación para entender estos capítulos y aprender la programación del shell. El \hyperref[sec:Chapter7]{Capítulo 7} y el \hyperref[sec:Chapter8]{Capítulo 8} dan descripciones más completas de las capacidades de E/S y de manejo de procesos del shell, y el \hyperref[sec:Chapter9]{Capítulo 9} discute varias técnicas para encontrar y eliminar problemas en sus programas del shell. + +Aprenderá mucho sobre el shell Korn en este libro; también aprenderá sobre las utilidades de Unix y el funcionamiento del sistema operativo Unix en general. Es posible convertirse en un virtuoso programador de shell sin ninguna experiencia previa en programación. Al mismo tiempo, hemos evitado cuidadosamente bajar más allá de un cierto nivel de detalle sobre los aspectos internos de Unix. Mantenemos que no deberías ser un experto en el funcionamiento interno para usar y programar el shell de forma efectiva, y no nos detendremos en las pocas características del shell que están pensadas específicamente para los programadores de sistemas de bajo nivel. + +\section{Historia de los Shells de Unix} +La independencia del shell del sistema operativo Unix en sí mismo ha llevado al desarrollo de docenas de shells a lo largo de la historia de Unix, aunque sólo unos pocos han logrado un uso generalizado. + +El primer intérprete de comandos importante fue el intérprete de comandos Bourne (llamado así por su inventor, Stephen Bourne); se incluyó en la primera versión ampliamente popular de Unix, la versión 7, a partir de 1979. El shell Bourne se conoce en el sistema como sh. Aunque Unix ha pasado por muchos, muchos cambios, el shell Bourne sigue siendo popular y esencialmente sin cambios. Varias utilidades y funciones de administración de Unix dependen de él. + +El primer shell alternativo ampliamente utilizado fue el shell C, o csh. Fue escrito por Bill Joy en la Universidad de California en Berkeley como parte de la versión de Unix de la Berkeley Software Distribution (BSD) que salió un par de años después de la versión 7. Está incluido en casi todas las versiones recientes de Unix. (Una variante popular es el llamado Twenex csh, tcsh). + +El shell C recibe su nombre del parecido de sus comandos con las declaraciones del lenguaje de programación C, lo que hace que el shell sea más fácil de aprender para los programadores de los sistemas Unix. Soporta una serie de características del sistema operativo (por ejemplo, el control de trabajos; véase el \hyperref[sec:Chapter8]{Capítulo 8}) que antes eran exclusivas de BSD Unix pero que ahora han migrado a casi todas las demás versiones modernas. También tiene algunas características importantes (por ejemplo, los alias; véase el \hyperref[sec:Chapter3]{Capítulo 3}) que facilitan su uso en general. + +\subsection{El Shell de Korn} +El shell Korn, o \emph{ksh}, fue inventado por David Korn de AT\&T Bell Laboratories a mediados de la década de 1980. Es casi totalmente compatible con el shell Bourne,\footnote{Con algunas excepciones extremadamente pequeñas. Vea el \hyperref[sec:Chapter10]{Capítulo 10} para la única importante.} +lo que significa que los usuarios del shell Bourne pueden utilizarlo inmediatamente, y todas las utilidades del sistema que utilizan el shell Bourne pueden utilizar el shell Korn en su lugar. De hecho, algunos sistemas tienen el shell Korn instalado como si fuera el shell Bourne. + +El intérprete de comandos Korn comenzó su vida pública en 1986 como parte del <> de AT\&T, lo que significa que su código fuente estaba disponible a muy bajo costo para cualquiera que estuviera dispuesto a usarlo sin soporte técnico y con el conocimiento de que todavía podría tener algunos errores. Finalmente, los Laboratorios de Sistemas Unix (USL) de AT\&T decidieron darle soporte completo como utilidad Unix. A partir de la versión de Unix de USL llamada System V Release 4 (SVR4 para abreviar, 1989), se distribuyó con todos los sistemas Unix de USL, todas las versiones de Unix de terceros derivadas de SVR4 y muchas otras versiones. + +A finales de 1993, David Korn publicó una versión más reciente, conocida popularmente como ksh93. Esta versión se distribuye con muchos sistemas Unix comerciales como parte del Entorno Común de Escritorio (CDE), normalmente como el <>, \emph{/usr/dt/bin/dtksh}. + +Aunque el propio Unix ha cambiado de propietario varias veces desde entonces, David Korn permaneció en los Laboratorios Bell hasta 1996, cuando AT\&T (voluntariamente, esta vez) se dividió en AT\&T Corporation, Lucent Technologies y NCR. En ese momento, se trasladó a AT\&T Research Laboratories desde Bell Labs (que siguió formando parte de Lucent). Aunque tanto Lucent como AT\&T conservaron todos los derechos del shell de Korn, todas las mejoras y cambios provienen ahora de David Korn en AT\&T. + +El 1 de marzo de 2000, AT\&T liberó el código fuente de ksh93 bajo una licencia de tipo Open Source. La obtención del código fuente se discute en el \hyperref[sec:ApendiceC]{Apéndice C}, y la licencia se presenta en el \hyperref[sec:ApendiceD]{Apéndice D}. + +Este libro se centra en la versión 2001 de \emph{ksh93}. Ocasionalmente, el libro señala una diferencia significativa entre las versiones de 1993 y 1988. Cuando es necesario, las distinguimos como \emph{ksh93} y \emph{ksh88}, respectivamente. En el \hyperref[sec:ApendiceA]{Apéndice A} se describen las diferencias entre las versiones de 1988 y 1993 de forma ordenada, y en ese apéndice también se resumen brevemente otras versiones del shell. + +\subsection{Características del Shell Korn} +Aunque el shell Bourne sigue siendo conocido como el shell <>, el shell Korn también es popular. Además de su compatibilidad con el shell Bourne, incluye las mejores características del shell C, así como varias ventajas propias. También se ejecuta de forma más eficiente que cualquier shell anterior. + +Los modos de edición de la línea de comandos del shell Korn son las características que suelen atraer a la gente al principio. Con la edición de la línea de comandos, es mucho más fácil volver atrás y corregir errores que con el mecanismo de historial del shell C -- y el shell Bourne no permite hacer esto en absoluto. + +La otra característica principal del shell Korn que está pensada principalmente para los usuarios interactivos es el control de trabajos. Como se explica en el \hyperref[sec:Chapter8]{Capítulo 8}, el control de trabajos le da la capacidad de parar, iniciar y pausar cualquier número de comandos al mismo tiempo. Esta característica fue tomada casi literalmente del shell C. + +El resto de las ventajas importantes del shell Korn están destinadas principalmente a los personalizadores y programadores del shell. Tiene muchas opciones y variables nuevas para la personalización, y sus características de programación se han ampliado significativamente para incluir la definición de funciones, más estructuras de control, expresiones regulares y aritmética incorporadas, matrices asociativas, variables estructuradas, control avanzado de E/S, y más. + +\section{Cómo Obtener el Shell Korn de 1993} +Este libro cubre la versión de 1993 del shell Korn. Gran parte de lo que se cubre es exclusivo de ese shell; un subconjunto de lo que es exclusivo se aplica sólo a las versiones recientes disponibles directamente de AT\&T. Para hacer un mejor uso de este libro, debería estar usando el shell Korn de 1993. Utilice la siguiente secuencia de instrucciones para determinar qué shell tiene actualmente y si el shell Korn de 1993 existe en su sistema, y para hacer que el shell Korn de 1993 sea su shell de inicio de sesión. + +\begin{enumerate} + \item{Determine qué shell está utilizando. La variable SHELL indica su shell de inicio de sesión. Entre en su sistema y escriba \emph{echo \$SHELL} en el prompt. Verá una respuesta que contiene sh, csh, o ksh; estos denotan los shells Bourne, C, y Korn, respectivamente. (También es muy probable que esté utilizando un shell de terceros como bash o tcsh). Si la respuesta es ksh, vaya al paso 3. De lo contrario, continúe con el paso 2.} + \item{Vea si existe alguna versión de ksh en su sistema en un directorio estándar. Escriba ksh. Si eso funciona (imprime un prompt \$), tiene una versión del shell Korn; continúe con el paso 3. De lo contrario, continúe con el paso 5.} + \item{Compruebe la versión. Escriba \emph{echo \${.sh.version}}. Si eso imprime una versión, está todo listo; omita el resto de estas instrucciones. De lo contrario, continúe con el paso 4.} + \item{No tiene la versión 1993 del shell Korn. Para saber qué versión tienes, escribe el comando \emph{set -o emacs}, y luego presiona CTRL-V. Esto te dirá si tienes la versión de 1988 o el shell Korn de dominio público. En cualquier caso, continúe con el paso 5.} + \item{Escribe el comando \texttt{/usr/dt/bin/dtksh}. Si esto le da un prompt \emph{\$}, usted tiene el Desktop Korn Shell, que está basado en una versión temprana de ksh93. Puede utilizar esta versión; casi todo lo que se dice en este libro funcionará. Vaya al paso 7.} + \item{Necesita descargar una versión ejecutable de \emph{ksh93} o descargar el código fuente y construir un ejecutable a partir de él. Estas tareas se describen en el \hyperref[sec:ApendiceC]{Apéndice C}. Lo mejor sería solicitar la ayuda de su administrador de sistemas para este paso. Una vez que tenga un \emph{ksh93} que funcione, continúe con el paso 7.} + \item{Instale \emph{ksh93} como su shell de inicio de sesión. Hay dos situaciones; elija la que le convenga:} + \begin{description} + \item[Sistema monousuario] En un sistema monousuario, en el que usted es el administrador, probablemente tendrá que añadir la ruta completa a \emph{ksh93} al archivo \emph{/etc/shells} como primer paso. Luego, debería poder cambiar su shell de inicio de sesión escribiendo \emph{chsh nombre-k}, donde \emph{nombre-k} es la ruta completa al ejecutable \emph{ksh93}. Si esto funciona, se te pedirá tu contraseña. Escriba su contraseña, salga y vuelva a entrar para empezar a usar el shell Korn. \\ +Si \emph{chsh} no existe o no funciona, consulte la página man de \emph{passwd(1)}. Busque las opciones \emph{-e} o \emph{-s} para actualizar la información de su archivo de contraseñas. Utilice lo que sea apropiado para su sistema para cambiar su shell de inicio de sesión. \\ +Si nada de lo anterior funciona, puede recurrir a editar el archivo \emph{/etc/passwd} mientras está conectado como root. Si tienes el comando vipw(8), deberías usarlo para editar tu archivo de contraseñas. Si no, edita el archivo manualmente con tu editor de texto favorito. + \item[Sistema multiusuario grande] Esta situación es aún más compleja que el caso de un solo usuario. Lo mejor es dejar que el administrador del sistema se encargue de cambiar el shell por ti. La mayoría de las instalaciones grandes tienen un <> (accesible por correo electrónico o por teléfono, o ambos) para introducir dichas solicitudes. + \end{description} +\end{enumerate} + +\section{Uso Interactivo del Shell} +Cuando usas el shell de forma interactiva, entras en una sesión de inicio de sesión que comienza cuando te conectas y termina cuando sales o presionas CTRL-D.\footnote{Puedes configurar tu shell para que no acepte CTRL-D, es decir, que requiera que escribas exit para terminar tu sesión. Recomendamos esto, porque CTRL-D es demasiado fácil de escribir por accidente; vea la sección de opciones en el \hyperref[sec:Chapter3]{Capítulo 3}.} +Durante una sesión de inicio de sesión, escribes líneas de comando en el shell; estas son líneas de texto que terminan en ENTER y que escribes en tu terminal o estación de trabajo.\footnote{Aunque asumimos que hay pocas personas que todavía usan terminales seriales reales, los sistemas modernos de ventanas proporcionan acceso al shell a través de un emulador de terminal. Por lo tanto, al menos cuando se trata del uso interactivo del shell, el término <> se aplica igualmente a un entorno de ventanas.} +Por defecto, el shell te pide cada comando con un signo de dólar, aunque, como verás en el Capítulo 3, el prompt puede ser cambiado. + +\subsection{Comandos, Argumentos y Opciones} +Las líneas de comandos del shell consisten en una o más palabras, que se separan en una línea de comandos por espacios o TABs. La primera palabra de la línea es el comando. El resto (si lo hay) son argumentos (también llamados parámetros) del comando, que son nombres de cosas sobre las que actuará el comando. + +Por ejemplo, la línea de comandos \texttt{lpr myfile} está formada por el comando \emph{lpr} (imprimir un archivo) y el único argumento \emph{myfile}. \emph{lpr} trata \emph{myfile} como el nombre de un archivo a imprimir. Los argumentos suelen ser nombres de archivos, pero no necesariamente: en la línea de comandos \texttt{mail billr}, el programa de correo trata a \emph{billr} como el nombre del usuario al que se enviará un mensaje. + +Una opción es un tipo especial de argumento que da al comando información específica sobre lo que debe hacer. Las opciones suelen consistir en un guión seguido de una letra; decimos <> porque se trata de una convención más que de una regla rígida. El comando \texttt{lpr -h miarchivo} contiene la opción \emph{-h}, que le dice a \emph{lpr} que no imprima la <> antes de imprimir el archivo. + +A veces las opciones tienen sus propios argumentos. Por ejemplo, \texttt{lpr -P hp3si -h miarchivo} tiene dos opciones y un argumento. La primera opción es \emph{-P hp3si} , que significa <>. La segunda opción y el argumento son como los anteriores. + +\subsection{Ayuda Incorporada (Built-in)} +Casi todos los comandos incorporados en ksh tienen ayuda <> tanto mínima como más extensa. Si le das a un comando la opción -?, imprime un breve resumen de uso: + +\begin{lstlisting}[language=bash, escapeinside={(*}{*)}]] +$ (*\textbf{cd -?}*) +Usage: cd [-LP] [directory] + Or: cd [ options ] old new +\end{lstlisting} + +(Es posible que desee citar la \texttt{?}, ya que, como veremos más adelante, es especial para el shell). También puede dar la opción \emph{--man} para imprimir la ayuda en la forma de la tradicional página man de Unix\footnote{A partir de \emph{ksh93i}.} +La salida usa secuencias de escape estándar ANSI para producir un cambio visible en la pantalla, representado aquí usando una fuente en negrita: + +\begin{lstlisting}[language=bash, escapeinside={(*}{*)}]] +$ (*\textbf{cd --man}*) +NAME + cd - change working directory + +SYNOPSIS + (*\textbf{cd} [ \textbf{options}*) ] [directory] + (*\textbf{cd} [ \textbf{options}*) ] old new + +DESCRIPTION + (*\textbf{cd}*) changes the current working directory of the current shell + environment. + + In the first form with one operand, if (*\textbf{directory}*) begins with /, + or if the first component is . or .., the directory will be + changed to this directory... +\end{lstlisting} + +Del mismo modo, la opción \emph{--html} produce la salida en formato HTML para su posterior renderización con un navegador web. + +Por último, la opción \emph{--nroff} le permite producir la ayuda de cada comando en forma de entrada \emph{nroff} -man\footnote{Todas las opciones de ayuda envían su salida a error estándar (que se describe más adelante en este capítulo). Esto significa que tiene que usar las facilidades del shell que no cubriremos hasta el \hyperref[sec:Chapter7]{Capítulo 7} para capturar su salida. Por ejemplo, cd --man 2>\&1 | more ejecuta la ayuda en línea a través del programa paginador more.}, +lo que resulta práctico para dar formato a la ayuda para la salida impresa. + +Para cumplir con POSIX, algunos comandos no aceptan estas opciones: \emph{echo, false, jobs, login, newgrp, true} y :. Para \emph{test}, tienes que escribir \texttt{test - -man - -} para obtener la ayuda en línea. + +\section{Ficheros} +Aunque los argumentos de los comandos no siempre son ficheros, los ficheros son los tipos de <> más importantes en cualquier sistema Unix. Un archivo puede contener cualquier tipo de información, y hay diferentes tipos de archivos. Cuatro tipos son, con mucho, los más importantes: + +\begin{description} + \item[Archivos normales] También llamados \emph{archivos de texto}; contienen caracteres legibles. Por ejemplo, este libro se creó a partir de varios archivos regulares que contienen el texto del libro más instrucciones de formato DocBook XML legibles por humanos. + \item[Archivos ejecutables] También llamados programas; se invocan como comandos. Algunos no pueden ser leídos por humanos; otros - los scripts del shell que examinaremos en este libro - son sólo archivos de texto especiales. El propio shell es un archivo ejecutable (no legible por humanos) llamado ksh. + \item[Directorios] Como carpetas que contienen otros archivos - posiblemente otros directorios (llamados subdirectorios). + \item[Enlaces simbólicos] Una especie de <> de un lugar a otro en la jerarquía de directorios del sistema. Veremos más adelante en este capítulo cómo los enlaces simbólicos pueden afectar al uso interactivo del shell Korn. +\end{description} + +\subsection{Directorios} +Repasemos los conceptos más importantes sobre los directorios. El hecho de que los directorios puedan contener otros directorios da lugar a una estructura jerárquica, más popularmente conocida como árbol, para todos los ficheros de un sistema Unix. La Figura \ref{fig2} muestra parte de un árbol de directorios típico; los óvalos son ficheros normales y los rectángulos son directorios. + +\begin{figure}[h!] + \centering + \includegraphics[scale=1]{fig_02} + \caption{\small{Árbol de directorios y archivos}} + \label{fig2} +\end{figure} + +La parte superior del árbol es un directorio llamado <> o <> que no tiene nombre en el sistema\footnote{La mayoría de los tutoriales introductorios de Unix dicen que root tiene el nombre /. Nos quedamos con esta explicación alternativa porque es más consistente lógicamente.}. +Todos los archivos pueden nombrarse expresando su ubicación en el sistema en relación con la raíz; dichos nombres se construyen enumerando todos los nombres de directorio (en orden desde la raíz), separados por barras (/), seguidos del nombre del archivo. Esta forma de nombrar los archivos se denomina \emph{ruta completa (o absoluta)}. + +Por ejemplo, supongamos que hay un archivo llamado \emph{memo} en el directorio \emph{fred}, que está en el directorio \emph{home}, que está en el directorio raíz. La ruta completa de este fichero es \texttt{/home/fred/memo}. + +\subsubsection{El Directorio de Trabajo} +Por supuesto, es molesto tener que utilizar nombres de ruta completos cada vez que necesitas especificar un archivo, por lo que también existe el concepto de \emph{directorio de trabajo} (a veces llamado \emph{directorio actual}), que es el directorio en el que te encuentras en un momento dado. Si se da un nombre de ruta sin barra inicial, la ubicación del archivo se calcula en relación con el directorio de trabajo. Este tipo de nombres de ruta se denominan nombres de ruta relativos; los utilizarás con mucha más frecuencia que los nombres de ruta completos. + +Cuando te conectas al sistema, tu directorio de trabajo se establece inicialmente en un directorio especial llamado tu directorio personal (o \emph{de inicio de sesión}). Los administradores de sistemas a menudo configuran el sistema para que el nombre del directorio personal de cada usuario sea el mismo que su nombre de inicio de sesión, y todos los directorios personales están contenidos en un directorio común bajo root. En la actualidad, es habitual utilizar \emph{/home} como directorio principal para los directorios personales. + +Por ejemplo, \emph{/home/billr} es un directorio personal típico. Si este es tu directorio de trabajo y das el comando \texttt{lp memo}, el sistema busca el archivo memo en \emph{/home/billr}. Si tienes un directorio llamado bob en tu directorio personal, y contiene el archivo statrpt, puedes imprimir \emph{statrpt} con el comando \texttt{lp bob/statrpt}. + +\subsubsection{Notación con tilde} +Como puedes imaginar, los directorios personales aparecen a menudo en los nombres de ruta. Aunque muchos sistemas están organizados de forma que todos los directorios personales tienen un directorio principal común (como \emph{/home}), no debería depender de que esto sea así, ni siquiera debería saber cuál es el nombre absoluto del directorio personal de alguien. + +Por lo tanto, el shell Korn tiene una forma de abreviar los directorios home: basta con preceder el nombre del usuario con una tilde (\textasciitilde). Por ejemplo, puedes referirte al archivo memo en el directorio personal del usuario fred como \emph{\textasciitilde{} fred/memo}. Se trata de una ruta absoluta, por lo que no importa cuál sea tu directorio de trabajo cuando la utilices. Si el directorio personal de fred tiene un subdirectorio llamado bob y el archivo está allí, puedes usar \emph{\textasciitilde{} fred/bob/memo} como nombre. + +Aún más conveniente, una tilde por sí misma se refiere a su propio directorio personal. Puede referirse a un archivo llamado \emph{notas} en su directorio personal como \emph{\textasciitilde{} /notas} (observe la diferencia entre eso y \emph{\textasciitilde{} notas}, que el shell trataría de interpretar como el directorio personal del usuario notas). Si \emph{notes} está en tu subdirectorio bob, puedes llamarlo \emph{\textasciitilde{} /bob/notes}. Esta notación es más útil cuando su directorio de trabajo no está en su árbol de directorios personales, por ejemplo, cuando es algún directorio del <> como \emph{/tmp}. + +\subsubsection{Cambiar los Directorios de Trabajo} +Si desea cambiar su directorio de trabajo, utilice el comando \emph{cd}. Si no recuerda su directorio de trabajo, el comando \emph{pwd} indica al shell que lo imprima. + +\emph{cd} toma como argumento el nombre del directorio que desea que se convierta en su directorio de trabajo. Puede ser relativo a su directorio actual, puede contener una tilde, o puede ser absoluto (comenzando con una barra). Si omite el argumento, \emph{cd} cambia a su directorio personal (es decir, es lo mismo que \texttt{cd \~ }). + +La Tabla \ref{tab1} muestra algunos ejemplos de comandos \emph{cd}. Cada comando asume que tu directorio de trabajo es \emph{/home/billr} justo antes de que se ejecute el comando, y que tu estructura de directorios se parece a la Figura \ref{fig2}. + +\begin{table}[h] + \center + \caption{Ejemplos de comandos cd} + \label{tab1} + \begin{tabular}{m{4cm}|m{4cm}} \hline + \textbf{Comando} & \textbf{Nuevo directorio de trabajo} \\ \hline + \texttt{cd bob} & \emph{/home/billr/bob} \\ + \texttt{cd bob/dave} & \emph{/home/billr/bob/dave} \\ + \texttt{cd \textasciitilde{}/bob/dave} & \emph{/home/billr/bob/dave} \\ + \texttt{cd /usr/lib} & \emph{/usr/lib} \\ + \texttt{cd ..} & \emph{/home} \\ + \texttt{cd ../pete} & \emph{/home/pete} \\ + \texttt{cd \textasciitilde{}pete} & \emph{/home/pete} \\ + \texttt{cd billr pete} & \emph{/home/pete} \\ + \texttt{cd illr arry} & \emph{/home/barry} \\ + \end{tabular} +\end{table} + +Los cuatro primeros son sencillos. Los dos siguientes utilizan un directorio especial llamado .. (dos puntos, pronunciado <>), que significa <>. Todos los directorios tienen uno de estos; es una forma universal de llegar al directorio situado por encima del actual en la jerarquía, que se denomina directorio padre. + +Cada directorio también tiene el directorio especial . (punto simple), que sólo significa <>. Por lo tanto, \texttt{cd .} efectivamente no hace nada. Tanto . como .. son en realidad ficheros especiales ocultos en cada directorio que apuntan al propio directorio y a su directorio padre, respectivamente. El directorio raíz es su propio directorio padre. + +Los dos últimos ejemplos de la tabla utilizan una nueva forma del comando \emph{cd}, que no está incluida en la mayoría de los shells Bourne. La forma es \texttt{cd viejo nuevo}. Toma la ruta completa del directorio de trabajo actual e intenta encontrar la cadena \emph{old} en ella. Si encuentra la cadena, la sustituye por \emph{new} y cambia al directorio resultante. + +En el primero de los dos ejemplos, el shell sustituye \emph{pete} por \emph{billr} en el nombre del directorio actual y convierte el resultado en el nuevo directorio actual. El último ejemplo muestra que la sustitución no necesita ser un nombre de archivo completo: al sustituir \emph{arry} por \emph{illr} en \emph{/home/billr} se obtiene \emph{/home/barry}. (Si no se puede encontrar la cadena antigua en el nombre del directorio actual, el intérprete de comandos imprime un mensaje de error). + +Otra característica del comando cd del shell Korn es la forma \texttt{cd -}, que cambia al directorio en el que se encontraba antes del actual. Por ejemplo, si empiezas en \emph{/usr/lib}, escribes \texttt{cd} sin un argumento para ir a tu directorio personal, y luego escribes \texttt{cd -}, estarás de vuelta en \emph{/usr/lib}. + +\subsubsection{Enlaces Simbólicos a Directorios} +Los sistemas Unix modernos ofrecen \emph{enlaces simbólicos}. Los enlaces simbólicos (a veces llamados \emph{enlaces blandos}) proporcionan una especie de <> a los archivos en una parte diferente de la jerarquía de archivos del sistema. Se puede crear un enlace simbólico a un fichero o a un directorio, utilizando nombres de ruta completos o relativos. Cuando se accede a un fichero o directorio mediante un enlace simbólico, Unix <> hasta el fichero o directorio real. + +Los enlaces simbólicos a directorios pueden generar comportamientos sorprendentes. Para explicar por qué, vamos a empezar asumiendo que estás usando el shell Bourne normal, sh.\footnote{Si tienes un sistema donde el shell Korn está instalado como /bin/sh, este ejemplo no funcionará} +Ahora, supongamos que nosotros y el usuario fred estamos trabajando juntos en un proyecto, y el directorio primario para el proyecto está bajo su directorio personal, digamos \texttt{/home/fred/projects/} \texttt{important/wonderprog}. Es un nombre de ruta bastante largo, incluso usando la notación con tilde (que no podemos usar en el shell Bourne, pero eso es otra historia). Para hacer la vida más fácil, vamos a crear un enlace simbólico al directorio \emph{wonderprog} en nuestro directorio personal: + +\begin{lstlisting}[language=bash, escapeinside={(*}{*)}]] +$ (*\textbf{sh} \emph{Utilizar el shell Bourne}*) +$ (*\textbf{cd} \emph{Asegurarse de que se estamos en nuestro directorio de inicio}*) +$ (*\textbf{pwd} \emph{Mostrar el directorio en el que estamos}*) +/home/billr +(*\emph{Crear el enlace suave}*) +$ (*\textbf{ln -s /home/fred/projects/important/wonderprog wonderprog}*) +\end{lstlisting} + +Ahora, cuando escribimos \texttt{cd wonderprog}, terminamos en \texttt{/home/fred/projects/important} \texttt{/wonderprog}: + +\begin{lstlisting}[language=bash] +$ cd wonderprog +$ pwd +/home/fred/projects/important/wonderprog +\end{lstlisting} + +Después de trabajar un rato añadiendo nuevas e importantes características\footnote{Las <> son las que desea el departamento de marketing, las necesiten o no los clientes.} a \emph{wonderprog}, recordamos que necesitamos actualizar el archivo \emph{.profile} en nuestro directorio home. No hay problema: simplemente \emph{cd} de nuevo allí y empezar a trabajar en el archivo, mirándolo primero con \emph{more}. + +\begin{lstlisting}[language=bash] +$ cd .. + Retrocedemos un nivel +$ more .profile + Observamos .profile +.profile: No such file or directory +\end{lstlisting} + +¿Qué ha pasado? El \texttt{cd ..} no nos llevó de vuelta por donde vinimos. En su lugar, subió un nivel en la jerarquía \emph{física} del sistema de archivos: + +\begin{lstlisting}[language=bash] +$ pwd +/home/fred/projects/important +\end{lstlisting} + +Este es el <> de los enlaces simbólicos: la visión lógica de la jerarquía del sistema de ficheros que presenta un enlace simbólico a un directorio se rompe con la realidad física subyacente cuando se accede al directorio padre. + +El shell Korn funciona de forma diferente. Entiende los enlaces simbólicos y, por defecto, siempre te presenta una vista lógica del sistema de ficheros. No sólo \emph{cd} está integrado en el shell, sino también \emph{pwd}. Ambos comandos aceptan las mismas dos opciones: \emph{-L}, para realizar operaciones lógicas (por defecto), y \emph{-P}, para realizar las operaciones en los directorios reales. Empecemos de nuevo en el shell Korn: + +\begin{lstlisting}[language=bash] +$ cd wonderprog ; pwd + # cd a traves del enlace simbolico +/home/billr/wonderprog # La respuesta es la ubicacion logica +$ pwd -P + # Cual es la ubicacion fisica +/home/fred/projects/important/wonderprog # La respuesta es la ubicacion fisica +$ cd .. ; pwd + # Sube un nivel +/home/billr # El trayecto fue de nuevo logico + +$ cd -P wonderprog; pwd + # Hacer un cd fisico +/home/fred/projects/important/wonderprog # logico es ahora igual a fisico +cd .. ; pwd + # Vuelve a subir un nivel +/home/fred/projects/important # logico sigue siendo igual a fisico +\end{lstlisting} + +Como se muestra, la opción \emph{-P} de \emph{cd} y \emph{pwd} le permite <> el uso por defecto del posicionamiento lógico del shell Korn. La mayoría de las veces, sin embargo, el posicionamiento lógico es exactamente lo que quieres. + +\textbf{NOTA}: El intérprete de comandos establece las variables PWD y OLDPWD de forma correspondiente cada vez que se realiza un \emph{cd}; los resultados de escribir \emph{pwd} y \emph{print \$PWD} deberían ser siempre los mismos. + +Como nota no relacionada que redondea la discusión, los sistemas Unix también proporcionan <> (o simplemente \emph{enlaces}) a los archivos. Cada nombre para un fichero se llama enlace; todos los enlaces duros se refieren a los mismos datos en el disco, y si el fichero cambia de nombre, ese cambio se ve al mirarlo desde un nombre diferente. Los enlaces duros tienen ciertas restricciones, que los enlaces simbólicos superan. (Véase \emph{ln(1)} para más información). Sin embargo, no puedes hacer enlaces duros a directorios, así que los enlaces simbólicos son todo lo que importa para \emph{cd} y \emph{pwd}. + +\subsection{Nombres de Archivo y Comodines} +A veces es necesario ejecutar un comando en más de un archivo a la vez. El ejemplo más común de este tipo de órdenes es \emph{ls}, que muestra información sobre los ficheros. En su forma más simple, sin opciones ni argumentos, enumera los nombres de todos los archivos del directorio de trabajo excepto los archivos ocultos especiales, cuyos nombres empiezan por un punto (.). + +Si le das a \emph{ls} argumentos de nombre de archivo, listará esos archivos, lo cual es un poco tonto: si tu directorio actual tiene los archivos bob y fred, y escribes \texttt{ls bob fred}, el sistema simplemente te devolverá los nombres de los archivos. + +En realidad, \texttt{ls} se usa más a menudo con opciones que le dicen que liste información sobre los ficheros, como la opción \emph{-l} (long), que le dice a \emph{ls} que liste el propietario del fichero, el grupo, el tamaño, la hora de la última modificación y otra información, o \emph{-a} (all), que también lista los ficheros ocultos descritos anteriormente. Pero a veces quieres verificar la existencia de un determinado grupo de archivos sin tener que saber todos sus nombres; por ejemplo, si diseñas páginas web, puede que quieras ver qué archivos de tu directorio actual tienen nombres que terminan en \emph{.html}. + +Los nombres de fichero son tan importantes en Unix que el shell proporciona una forma integrada de especificar el patrón de un conjunto de nombres de fichero sin tener que conocer todos los nombres en sí. Puede utilizar caracteres especiales, llamados \emph{comodines}, en los nombres de archivo para convertirlos en patrones. Mostraremos los tres tipos básicos de comodines que soportan los principales shells de Unix, y dejaremos el conjunto de operadores comodín avanzados del shell Korn para el \hyperref[sec:Chapter4]{Capítulo 4}. La Tabla \ref{tab2} lista los comodines básicos. + +\begin{table}[h] + \center + \caption{Comodines básicos} + \label{tab2} + \begin{tabular}{m{2cm}|m{8cm}} \hline + \textbf{Comodín} & \textbf{Coincidencia} \\ \hline + ? & Cualquier carácter \\ + \texttt{*} & Cualquier cadena de caracteres \\ + \texttt{[set]} & Cualquier caracter del conjunto \\ + \texttt{[!set]} & Cualquier carácter no incluido en el conjunto \\ + \end{tabular} +\end{table} + +El comodín \texttt{?} coincide con cualquier carácter, de modo que si el directorio contiene los archivos \emph{program.c, program.log} y \emph{program.o}, la expresión \texttt{program.?} coincide con \emph{program.c} y \emph{program.o}, pero no con \emph{program.log}. + +El asterisco (*) es más potente y se utiliza mucho más; coincide con cualquier cadena de caracteres. La expresión \texttt{program.*} coincidirá con los tres archivos del párrafo anterior; los diseñadores web pueden utilizar la expresión \texttt{*.html} para coincidir con sus archivos de entrada\footnote{Los usuarios de MS-DOS, Windows y OpenVMS deben tener en cuenta que el punto (.) no tiene nada de especial en los nombres de archivo Unix (aparte del punto inicial, que <> el archivo); es simplemente otro carácter. Por ejemplo, ls * lista todos los ficheros del directorio actual; no se necesita *.* como en otros sistemas.}. + +La Tabla \ref{tab3} debería darte una mejor idea de cómo funciona el asterisco. Suponga que tiene los archivos \emph{bob, darlene, dave, ed, frank} y \emph{fred} en su directorio de trabajo. + +Observe que * puede no significar nada: tanto \texttt{*ed} como \texttt{*e*} coinciden con \emph{ed}. Observe también que el último ejemplo muestra lo que hace el intérprete de comandos si no puede encontrar ninguna coincidencia: simplemente deja la cadena con el comodín intacta. + +\begin{table}[h] + \center + \caption{Usando el comodín *} + \label{tab3} + \begin{tabular}{p{3cm}|p{6cm}} \hline + \textbf{Expresión} & \textbf{Campos} \\ \hline + fr* & frank fred \\ + *ed & ed fred \\ + b* & bob \\ + *e* & darlene dave ed fred \\ + *r* & darlene frank fred \\ + \texttt{*} & bob darlene dave ed frank fred \\ + d*e & darlene dave \\ + g* & g* + \end{tabular} +\end{table} + +Los archivos se guardan dentro de los directorios en un orden no especificado; el shell ordena los resultados de cada expansión de comodines. (En algunos sistemas, la ordenación puede estar sujeta a un orden apropiado para la ubicación del sistema, pero que es diferente del orden de cotejo subyacente de la máquina. Los tradicionalistas de Unix pueden utilizar \texttt{export LANG=C} para obtener el comportamiento al que están acostumbrados). + +El comodín restante es la construcción set. Un conjunto es una lista de caracteres (por ejemplo, abc), un rango inclusivo (por ejemplo, a-z) o una combinación de ambos. Si desea que el guión forme parte de una lista, sólo tiene que ponerlo en primer o último lugar. La Tabla \ref{tab4} (que asume un entorno ASCII) debería explicar las cosas más claramente. + +\begin{table}[h] + \center + \caption{Uso de los comodines de construcción de conjuntos} + \label{tab4} + \begin{tabular}{m{3cm}|m{10cm}} \hline + \textbf{Expresión} & \textbf{Coincidencia} \\ \hline + \texttt{[abc]} & a, b, ó c \\ + \texttt{[.,;]} & punto, coma o punto y coma \\ + \texttt{[\texttt{-}\_]} & Guión medio o guión bajo \\ + \texttt{[a-c]} & a, b ó c \\ + \texttt{[a-z]} & Todas las letras minúsculas \\ + \texttt{[!0-9]} & Todos los no dígitos \\ + \texttt{[0-9!]} & Todos los dígitos y signos de exclamación \\ + \texttt{[a-zA-Z]} & Todas las letras mayúsculas y minúsculas \\ + \texttt{[a-zA-Z0-9\_\texttt{-}]} & Todas las letras, todos los dígitos, guión bajo y guión \\ + \end{tabular} +\end{table} + +En el ejemplo del comodín original, \texttt{program.[co]} y \texttt{program.[a-z]} coinciden con \emph{program.c} y \emph{program.o}, pero no con \emph{program.log}. + +Un signo de exclamación tras el corchete izquierdo permite <> un conjunto. Por ejemplo, \texttt{[!.;]} coincide con cualquier carácter excepto punto y coma; \texttt{[!a-zA-Z]} coincide con cualquier carácter que no sea una letra. + +La notación de rango es útil, pero no debe hacer demasiadas suposiciones sobre los caracteres que se incluyen en un rango. Por lo general, es seguro utilizar un rango para letras mayúsculas, minúsculas, dígitos o cualquier subrango de éstos (por ejemplo, \texttt{[f-q], [2-6]}). No utilices rangos en caracteres de puntuación o letras mixtas: por ejemplo, no se debe confiar en que \texttt{[a-Z]} y \texttt{[A-z]} incluyan todas las letras y nada más. El problema es que esos rangos no son del todo portables entre distintos tipos de ordenadores\footnote{En concreto, los rangos dependen del esquema de codificación de caracteres que utilice tu ordenador. La gran mayoría utiliza ASCII, pero los mainframes IBM utilizan EBCDIC. (En realidad, en los sistemas EBCDIC, ni siquiera las mayúsculas y minúsculas forman un rango contiguo).}. + +Otro problema es que los sistemas modernos admiten diferentes configuraciones regionales, que son formas de describir cómo funciona el juego de caracteres local. En la mayoría de los países, el conjunto de caracteres por defecto de la configuración regional es diferente al del ASCII plano. En el \hyperref[sec:Chapter4]{Capítulo 4}, le mostramos cómo usar expresiones POSIX entre corchetes para denotar letras, dígitos, puntuación y otros tipos de caracteres de una forma portable. + +El proceso de hacer coincidir expresiones que contienen comodines con nombres de archivo se denomina \emph{expansión de comodines}. Este es sólo uno de los varios pasos que da el shell al leer y procesar una línea de órdenes; otro que ya hemos visto es la \emph{expansión de tildes}, en la que las tildes se sustituyen por directorios de inicio cuando procede. Veremos otros en capítulos posteriores, y los detalles completos del proceso se enumeran en el \hyperref[sec:Chapter7]{Capítulo 7}. + +Sin embargo, es importante tener en cuenta que los comandos que ejecutas sólo ven los resultados de la expansión de comodines. (De hecho, esto es cierto para todas las expansiones.) Es decir, sólo ven una lista de argumentos, y no tienen conocimiento de cómo surgieron esos argumentos. Por ejemplo, si escribe \texttt{ls fr*} y sus archivos son como los descritos anteriormente, entonces el shell expande la línea de comandos a \texttt{ls fred frank} e invoca el comando \emph{ls} con los argumentos \emph{fred} y \emph{frank}. Si escribe \texttt{ls g*}, entonces (porque no hay coincidencia) \emph{ls} recibirá la cadena literal \texttt{g*} y se quejará con el mensaje de error, \texttt{g* no encontrado}. \footnote{Esto es diferente del mecanismo de comodines del shell de C, que imprime un mensaje de error y no ejecuta el comando en absoluto.} (Es probable que el mensaje real varíe de un sistema a otro). + +He aquí otro ejemplo que le ayudará a entender por qué esto es importante. Supongamos que eres un programador en C. Esto significa que trabajas con archivos cuyos nombres terminan en \texttt{.c} (programas, también conocidos como archivos fuente), \texttt{.h} (archivos de cabecera para programas) y \texttt{.o} (archivos de código objeto que no son legibles por humanos), así como otros archivos. + +Supongamos que quieres listar todos los archivos fuente, objeto y de cabecera de tu directorio de trabajo. El comando \texttt{ls *.[cho]} hace el truco. El shell expande \texttt{*.[cho]} a todos los archivos cuyos nombres terminan en un punto seguido de una \texttt{c, h}, u \texttt{o} y pasa la lista resultante a ls como argumentos. + +En otras palabras, \emph{ls} verá los nombres de los ficheros como si se hubieran tecleado individualmente - ¡pero fíjese que no hemos asumido ningún conocimiento de los nombres reales de los ficheros! Dejamos que los comodines hagan el trabajo. + +A medida que adquiera experiencia con el shell, reflexione sobre cómo sería la vida sin comodines. Bastante miserable, diríamos nosotros. + +Una nota final sobre los comodines. Puede asignar a la variable \texttt{FIGNORE} un patrón del shell que describa los nombres de archivo que deben ignorarse durante la comparación de patrones. (Las capacidades completas de patrones del shell se describen más adelante, en el \hyperref[sec:Chapter4]{Capítulo 4}.) Por ejemplo, \emph{emacs} guarda copias de seguridad de archivos añadiendo un \texttt{\~} al nombre original. A menudo, no necesitas ver estos archivos. Para ignorarlos, puedes añadir lo siguiente a tu archivo \emph{.profile}: + +\begin{lstlisting}[language=bash] + export FIGNORE='*~' +\end{lstlisting} + +Al igual que con la expansión de comodines, la prueba contra FIGNORE se aplica a todos los componentes de un nombre de ruta, no sólo al final. + +\section{Entrada y Salida} +El campo del software -en realidad, cualquier campo científico- tiende a avanzar de forma más rápida e impresionante en esas pocas ocasiones en las que a alguien (es decir, no a un comité) se le ocurre una idea pequeña en concepto pero enorme en sus implicaciones. El esquema de entrada y salida estándar de Unix tiene que estar en la lista corta de tales ideas, junto con innovaciones clásicas como el lenguaje LISP, el modelo de datos relacional y la programación orientada a objetos. + +El esquema de E/S de Unix se basa en dos ideas deslumbrantemente simples. En primer lugar, la E/S de archivos Unix adopta la forma de secuencias arbitrariamente largas de caracteres (bytes). Por el contrario, los sistemas de archivos más antiguos tienen esquemas de E/S más complicados (por ejemplo, <>, <>, <>, etc.). En segundo lugar, todo lo que en el sistema produce o acepta datos se trata como un archivo; esto incluye dispositivos de hardware como unidades de disco y terminales. Los sistemas antiguos trataban cada dispositivo de forma diferente. Ambas ideas han hecho la vida de los programadores de sistemas mucho más agradable. + +\subsection{E/S Estándar} +Por convención, cada programa Unix tiene una única forma de aceptar entrada llamada \emph{entrada estándar}, una única forma de producir salida llamada \emph{salida estándar}, y una única forma de producir mensajes de error llamada \emph{salida de error estándar}, normalmente abreviada como \emph{error estándar}. Por supuesto, un programa puede tener también otras fuentes de entrada y salida, como veremos en el \hyperref[sec:Chapter7]{Capítulo 7}. + +La E/S estándar fue el primer esquema de su clase que se diseñó específicamente para usuarios interactivos, en lugar del antiguo estilo de uso por lotes que normalmente implicaba barajas de tarjetas perforadas. Dado que el shell de Unix proporciona la interfaz de usuario, no debería sorprendernos que la E/S estándar se diseñara para encajar perfectamente con el shell. + +Todos los shells manejan la E/S estándar básicamente de la misma manera. Cada programa que invocas tiene los tres canales de E/S estándar configurados para tu terminal o ventana de estación de trabajo, de modo que la entrada estándar es tu teclado, y la salida estándar y el error son tu pantalla o ventana. Por ejemplo, la utilidad de correo imprime mensajes para ti en la salida estándar, y cuando la usas para enviar mensajes a otros usuarios, acepta tu entrada en la entrada estándar. Esto significa que ves los mensajes en tu pantalla y escribes los nuevos en tu teclado. + +Cuando sea necesario, puede redirigir la entrada y la salida para que procedan o vayan a un archivo en su lugar. Si quieres enviar el contenido de un archivo preexistente a alguien como correo, redirige la entrada estándar de correo para que lea de ese archivo en lugar de tu teclado. + +También puedes conectar programas en una \emph{tubería (pipeline)}, en la que la salida estándar de un programa se alimenta directamente de la entrada estándar de otro; por ejemplo, podrías alimentar la salida de mail directamente al programa \emph{lp} para que los mensajes se impriman en lugar de mostrarse en pantalla. + +Esto hace posible el uso de utilidades Unix como bloques de construcción para programas más grandes. Muchos programas de utilidades Unix están pensados para ser utilizados de esta manera: cada uno de ellos realiza un tipo específico de operación de filtrado en el texto de entrada. Aunque este no es un libro de texto sobre utilidades Unix, son esenciales para el uso productivo del shell. Las utilidades de filtrado más populares se listan en la Tabla \ref{tab5} + +\begin{table}[h] + \center + \caption{Utilidades populares de filtrado de datos Unix} + \label{tab5} + \begin{tabular}{m{2cm}|m{11cm}} \hline + \textbf{Utilidad} & \textbf{Propósito} \\ \hline + cat & Copia la entrada estándar en la salida estándar \\ + grep & Busca \emph{strings} en la entrada estándar \\ + sort & Ordena las líneas de la entrada estándar \\ + sed & Realiza operaciones de edición en la entrada estándar \\ + tr & Traduce caracteres de la entrada estándar a otros caracteres \\ + \end{tabular} +\end{table} + +Es posible que haya utilizado alguna de estas utilidades antes y se haya dado cuenta de que toman nombres de archivos de entrada como argumentos y producen salida en la salida estándar. Sin embargo, puede que no sepa que todas ellas (y la mayoría de las utilidades de Unix) aceptan la entrada estándar si omite el argumento\footnote{Si una determinada utilidad Unix no acepta la entrada estándar cuando se omite el argumento nombre de fichero, pruebe a utilizar - como argumento. Esta es una convención común, aunque no universal.}. + +Por ejemplo, la utilidad más básica es \emph{cat}, que simplemente copia su entrada a su salida. Si escribe \texttt{cat} con un argumento de nombre de archivo, imprimirá el contenido de ese archivo en su pantalla. Pero si lo invocas sin argumentos, leerá la entrada estándar y la copiará en la salida estándar. Pruébelo: \emph{cat} esperará a que escriba una línea de texto; cuando teclee ENTER, \emph{cat} repetirá el texto como un loro. Para detener el proceso, pulse CTRL-D al principio de una línea (vea más abajo lo que significa este carácter). Verás \textasciicircum D cuando teclees CTRL-D. Esto es lo que debería parecer: + +\begin{lstlisting}[language=bash] +$ cat + Here is a line of text. +Here is a line of text. +This is another line of text. +This is another line of text. +^D +$ +\end{lstlisting} + +\subsection{Redirección de E/S} +\emph{cat} es en realidad la abreviatura de <>, es decir, unir. Acepta varios argumentos de nombre de archivo y los copia en la salida estándar. Pero supongamos, por el momento, que cat y otras utilidades no aceptan argumentos de nombre de archivo y sólo aceptan la entrada estándar. Como dijimos anteriormente, el shell le permite redirigir la entrada estándar para que provenga de un archivo. La notación \texttt{command < filename} hace esto; configura las cosas para que \emph{command} tome la entrada estándar de un archivo en lugar de una terminal. + +Por ejemplo, si usted tiene un archivo llamado fred que contiene algún texto, entonces \texttt{cat < fred} imprimirá el contenido de fred en su terminal. \texttt{sort < fred} ordenará las líneas en el archivo fred e imprimirá el resultado en su terminal (recuerde: estamos pretendiendo que las utilidades no toman argumentos de nombre de archivo). + +Del mismo modo, \texttt{command > filename} hace que la salida estándar del comando sea redirigida al archivo nombrado. El clásico ejemplo <> de esto es \texttt{date > now:} el comando \emph{date} imprime la fecha y hora actual en la salida estándar; el comando anterior la guarda en un archivo llamado \emph{now}. + +Las redirecciones de entrada y salida pueden combinarse. Por ejemplo, el comando cp se usa normalmente para copiar archivos; si por alguna razón no existiera o estuviera roto, podrías usar cat de esta manera: + +\begin{lstlisting}[language=bash] + cat < file1 > file2 +\end{lstlisting} + +Esto sería similar a \texttt{cp archivo1 archivo2}. + +Como recurso mnemotécnico, piensa en < y > como <>. Los datos entran por el extremo grande y salen por el pequeño. + +Cuando se utiliza de forma interactiva, el shell Korn le permite utilizar un comodín de shell después de un operador de redirección de E/S. Si el patrón coincide \emph{exactamente} con un archivo, ese archivo se utiliza para la redirección de E/S. De lo contrario, el patrón no se modifica y el shell intenta abrir un archivo cuyo nombre sea exactamente el que ha escrito. Además, no es válido intentar una redirección con la cadena nula como nombre de fichero (como podría ocurrir cuando se utiliza el valor de una variable, y la variable resulta estar vacía). + +Por último, es tentador utilizar el mismo fichero tanto para la entrada como para la salida: + +\begin{lstlisting}[language=bash] + sort < myfile > myfile +\end{lstlisting} + +Esto no funciona. El shell trunca \emph{myfile} cuando lo abre para la salida, y no habrá ningún dato allí para que sort lo procese cuando se ejecute. + +\subsection{Tuberías (pipes)} +También es posible redirigir la salida de un comando a la entrada estándar de otro comando en ejecución en lugar de a un archivo. La construcción que hace esto se llama tubería, anotada como |. Una línea de comandos que incluye dos o más comandos conectados con tuberías se denomina \emph{pipeline}. + +Las tuberías se utilizan muy a menudo con el comando \emph{more}, que funciona igual que cat excepto que imprime su salida pantalla a pantalla, haciendo una pausa para que el usuario escriba SPACE (siguiente pantalla), ENTER (siguiente línea), u otros comandos. Si estás en un directorio con un gran número de ficheros y quieres ver detalles sobre ellos, \texttt{ls -l | more} te dará un listado detallado pantalla a pantalla. + +Los pipelines pueden llegar a ser muy complejos (vea, por ejemplo, la función lsd en el \hyperref[sec:Chapter4]{Capítulo 4} o la versión pipeline del driver del compilador de C en el \hyperref[sec:Chapter7]{Capítulo 7}); también pueden combinarse con otros redireccionadores de E/S. Para ver un listado ordenado del fichero \emph{fred} pantalla a pantalla, escriba \texttt{sort < fred | more}. Para imprimirlo en lugar de verlo en su terminal, escriba \texttt{sort < fred | lp}. + +He aquí un ejemplo más complicado. El archivo \texttt{/etc/passwd} almacena información sobre las cuentas de usuario en un sistema Unix. Cada línea del archivo contiene el nombre de usuario, el número de identificación de usuario, la contraseña encriptada, el directorio de inicio, el shell de inicio de sesión y otra información. El primer campo de cada línea es el nombre de usuario; los campos están separados por dos puntos (:). Una línea de ejemplo podría tener este aspecto: + +\begin{lstlisting}[language=bash] +billr:5Ae40BGR/tePk:284:93:Bill Rosenblatt:/home/billr:/bin/ksh +\end{lstlisting} + +Para obtener un listado ordenado de todos los usuarios del sistema, escriba: + +\begin{lstlisting}[language=bash] +cut -d: -f1 < /etc/passwd | sort +\end{lstlisting} + +\newpage + +El comando cut extrae el primer campo \emph{(-f1)}, donde los campos están separados por dos puntos \emph{(-d:)}, de la entrada. La tubería completa imprime una lista que se parece a esto: + +\begin{lstlisting}[language=bash] +al +billr +bob +chris +dave + +ed +frank +... +\end{lstlisting} + +Si desea enviar la lista directamente a la impresora (en lugar de a la pantalla), puede ampliar el proceso de la siguiente manera: + +\begin{lstlisting}[language=bash] +cut -d: -f1 < /etc/passwd | sort | lp +\end{lstlisting} + +Ahora deberías ver cómo la redirección de E/S y los pipelines apoyan la filosofía de bloques de construcción de Unix. La notación es extremadamente concisa y poderosa. Igualmente importante, el concepto de tubería elimina la necesidad de archivos temporales desordenados para almacenar la salida de comandos antes de que se alimente a otros comandos. + +Por ejemplo, para hacer lo mismo que en la línea de comandos anterior en otros sistemas operativos (suponiendo que hubiera disponibles utilidades equivalentes), se necesitarían tres comandos. En el sistema OpenVMS de Compaq, tendrían este aspecto: + +\begin{lstlisting}[language=bash] +$ cut [etc]passwd /d=":" /f=1 /out=temp1 +$ sort temp1 /out=temp2 +$ print temp2 +\end{lstlisting} + +Después de practicar lo suficiente, se encontrará tecleando rutinariamente potentes conductos de comandos que hacen en una línea lo que en otros sistemas operativos requeriría varios comandos (y archivos temporales) para lograrlo. + +\section{Trabajos en Segundo Plano} +Las tuberías son en realidad un caso especial de una característica más general: hacer más de una cosa a la vez. cualquier otro sistema operativo comercial no tiene esta capacidad, debido a los rígidos límites que tienden a imponer a los usuarios. Unix, por otro lado, fue desarrollado en un laboratorio de investigación y pensado para uso interno, por lo que hace relativamente poco para imponer límites a los recursos disponibles para los usuarios en un ordenador - como de costumbre, inclinándose hacia la simplicidad despejada en lugar de la sobrecomplejidad. + +<> significa ejecutar más de un programa al mismo tiempo. Esto se hace cuando se invoca un pipeline; también se puede hacer iniciando sesión en un sistema Unix tantas veces simultáneamente como se desee. (Si lo intentas en un sistema IBM VM/CMS, por ejemplo, obtendrás un odioso mensaje de <>). + +El shell también le permite ejecutar más de un comando a la vez durante una única sesión de inicio de sesión. Normalmente, cuando escribes un comando y pulsas ENTER, el shell deja que el comando tenga el control de tu terminal hasta que termine; no puedes ejecutar más comandos hasta que termine el primero. Pero si quieres ejecutar un comando que no requiere la entrada del usuario y quieres hacer otras cosas mientras se ejecuta el comando, pon un ampersand (\&) después del comando. + +Esto se denomina ejecutar el comando en segundo plano, y un comando que se ejecuta de esta forma se denomina \emph{trabajo en segundo plano}; por el contrario, un trabajo que se ejecuta de la forma normal se denomina \emph{trabajo en primer plano}. Cuando inicias un trabajo en segundo plano, recuperas inmediatamente el prompt del shell, lo que te permite introducir otros comandos. + +El uso más obvio de los trabajos en segundo plano son los programas que pueden tardar mucho tiempo en ejecutarse, como \emph{sort} o \emph{gunzip} en archivos grandes. Por ejemplo, supongamos que acabas de cargar en tu directorio un enorme archivo comprimido desde una cinta magnética. Hoy en día, la utilidad \emph{gzip} es la utilidad de compresión de archivos de-facto. \emph{gzip} a menudo logra una compresión del 50\% al 90\% de sus archivos de entrada. Los archivos comprimidos tienen nombres del tipo \emph{nombrearchivo.gz}, donde \emph{nombrearchivo} es el nombre del archivo original sin comprimir. Digamos que el archivo es \emph{gcc-3.0.1.tar.gz}, que es un archivo comprimido que contiene más de 36 MB de código fuente. + +Escriba \texttt{gunzip gcc-3.0.1.tar.gz \&}, y el sistema inicia un trabajo en segundo plano que descomprime los datos <> y termina con el archivo \emph{gcc-3.0.1.tar}. Justo después de escribir el comando, verá una línea como esta: + +\begin{lstlisting}[language=bash] +[1] 4692 +\end{lstlisting} + +seguido de su prompt de shell, lo que significa que puede introducir otros comandos. Estos números te dan formas de referirte a tu trabajo en segundo plano; el \hyperref[sec:Chapter8]{Capítulo 8} los explica en detalle. + +Puede verificar los trabajos en segundo plano con el comando \emph{jobs}. Para cada trabajo en segundo plano, jobs imprime una línea similar a la anterior pero con una indicación del estado del trabajo: + +\begin{lstlisting}[language=bash] +[1] + Running gunzip gcc-3.0.1.tar.gz +\end{lstlisting} + +Cuando el trabajo termine, verás un mensaje como este justo antes de tu prompt de shell: + +\begin{lstlisting}[language=bash] +[1] + Done gunzip gcc-3.0.1.tar.gz +\end{lstlisting} + +El mensaje cambia si su trabajo en segundo plano finaliza con un error; de nuevo, consulte el \hyperref[sec:Chapter8]{Capítulo 8} para más detalles. + +\subsection{E/S en Segundo Plano} +Los trabajos que pongas en segundo plano no deberían hacer E/S a tu terminal. Piénsalo un momento y entenderás por qué. + +Por definición, un trabajo en segundo plano no tiene control sobre tu terminal. Entre otras cosas, esto significa que sólo el proceso en primer plano (o, en su defecto, el propio shell) está <> la entrada de tu teclado. Si un trabajo en segundo plano necesita entrada de teclado, a menudo se quedará ahí sin hacer nada hasta que usted haga algo al respecto (como se describe en el \hyperref[sec:Chapter8]{Capítulo 8}). + +Si un trabajo en segundo plano produce salida por pantalla, la salida simplemente aparecerá en su pantalla. Si está ejecutando un trabajo en primer plano que también produce salida, la salida de los dos trabajos se intercalará de forma aleatoria (y a menudo molesta). + +Si quieres ejecutar un trabajo en segundo plano que espera una entrada estándar o produce una salida estándar, la solución obvia es redirigirlo para que venga o vaya a un fichero. La única excepción es que algunos programas producen pequeños mensajes de una línea (advertencias, mensajes de <>, etc.); puede que no te importe si éstos se intercalan con cualquier otra salida que estés viendo en un momento dado. + +Por ejemplo, la utilidad \emph{diff} examina dos archivos, cuyos nombres se dan como argumentos, e imprime un resumen de sus diferencias en la salida estándar. Si los archivos son exactamente iguales, \emph{diff} no dice nada. Normalmente, usted invoca \emph{diff} esperando ver unas pocas líneas que son diferentes. + +\emph{diff}, al igual que \emph{sort} y \emph{gzip}, puede tardar mucho tiempo en ejecutarse si los ficheros de entrada son muy grandes. Suponga que tiene dos archivos grandes llamados \emph{warandpeace.html} y \emph{warandpeace.html.old}. El comando \texttt{diff warandpeace.html.old warandpeace.html} revela que el autor decidió cambiar el nombre <> por <> en todo el archivo - es decir, cientos de diferencias, lo que resulta en grandes cantidades de salida. + +Si escribe \texttt{diff warandpeace.html.old warandpeace.html \&}, el sistema le arrojará montones y montones de resultados, que serán muy difíciles de detener - incluso con las técnicas explicadas en el \hyperref[sec:Chapter7]{Capítulo 7}. Sin embargo, si escribe: + +\begin{lstlisting}[language=bash] +diff warandpeace.html.antiguo warandpeace.html > wpdiff & +\end{lstlisting} + +las diferencias se guardarán en el archivo \emph{wpdiff} ipara que pueda examinarlas más tarde. + +\subsection{Trabajos en Segundo Plano y Prioridades} +Las tareas en segundo plano pueden ahorrarte mucho tiempo (o pueden ayudarte a hacer dieta eliminando las excusas para ir corriendo a la máquina de caramelos). Pero recuerda que no hay almuerzo gratis; los trabajos en segundo plano consumen recursos que dejan de estar disponibles para ti o para otros usuarios del sistema. El hecho de que ejecutes varios trabajos a la vez no significa que vayan a funcionar más rápido que si se ejecutaran secuencialmente; de hecho, suele ser peor. + +A cada tarea del sistema se le asigna una \emph{prioridad}, un número que indica al sistema operativo cuánta prioridad debe darle a la hora de repartir los recursos (cuanto mayor sea el número, menor será la prioridad). Los comandos en primer plano que se introducen desde el shell suelen tener la misma prioridad estándar. Pero los trabajos en segundo plano, por defecto, tienen una prioridad más baja\footnote{Esta característica se tomó prestada del intérprete de comandos C; no está presente en la mayoría de los intérpretes de comandos Bourne.}. En el \hyperref[sec:Chapter3]{Capítulo 3} descubrirás cómo puedes anular esta asignación de prioridad para que los trabajos en segundo plano se ejecuten con la misma prioridad que los trabajos en primer plano. + +Si estás en un gran sistema multiusuario, ejecutar muchos trabajos en segundo plano puede consumir más recursos de los que te corresponden, y deberías considerar si hacer que tu trabajo se ejecute lo más rápido posible es realmente más importante que ser un buen ciudadano. +Por otro lado, si tienes una estación de trabajo dedicada con un procesador rápido y mucha memoria y disco, probablemente tengas ciclos de sobra y no debas preocuparte tanto por ello. De todos modos, el patrón de uso típico de estos sistemas obvia en gran medida la necesidad de procesos en segundo plano: basta con iniciar un trabajo y luego abrir otra ventana y seguir trabajando. + +\subsubsection{nice} +Hablando de buena ciudadanía, también hay un comando de shell que te permite bajar la prioridad de cualquier trabajo: el acertadamente llamado \emph{nice}. Si escribes lo siguiente, el comando se ejecutará con una prioridad más baja: + +\begin{lstlisting}[language=bash] +nice command +\end{lstlisting} + +Puedes controlar cuánto más bajo es dando a \emph{nice} un argumento numérico; consulta la página \emph{man} para más detalles\footnote{Si eres administrador del sistema y has iniciado sesión como \texttt{root}, también puedes utilizar \emph{nice} para aumentar la prioridad de una tarea.}. + +\section{Caracteres Especiales y Citas} +Los caracteres \texttt{<, >, | y \&} son cuatro ejemplos de \emph{caracteres especiales} que tienen significados particulares para el shell. Los comodines que vimos anteriormente en este capítulo \texttt{(*, ?, y [...])} también son caracteres especiales. + +En la Tabla \ref{tab6} se indican los significados de todos los caracteres especiales sólo dentro de las líneas de comandos del shell. Otros caracteres tienen significados especiales en situaciones específicas, como las expresiones regulares y los operadores de manejo de cadenas que veremos en el \hyperref[sec:Chapter3]{Capítulo 3} y el \hyperref[sec:Chapter4]{Capítulo 4}. + +\begin{longtable}[h]{p{2cm}|p{8cm}|p{3cm}} + \caption{Caracteres especiales} + \label{tab6}\\ + \hline + \textbf{Caracter} & \textbf{Significado} & \textbf{Ver capítulo} \\\hline + \endfirsthead + \hline + \textbf{Caracter} & \textbf{Significado} & \textbf{Ver capítulo} \\\hline + \endhead + \texttt{\~} & Directorio \emph{Home} & 1 \\ + \texttt{`} & Sustitución de comandos (arcaico) & 4 \\ + \texttt{\#} & Comentario & 4 \\ + \texttt{\$} & Expresión variable & 3 \\ + \texttt{\&} & Trabajo en segundo plano & 1 \\ + \texttt{*} & Cadena comodín & 1 \\ + \texttt{(} & Inicio subshell & 8 \\ + \texttt{)} & Fin subshell & 8 \\ + \textbackslash{} & Cita siguiente carácter & 1 \\ + | & Tubería (Pipe) & 1 \\ + \texttt{[} & Inicio conjunto caracteres comodín & 1 \\ + \texttt{]} & Fin del juego de caracteres comodín & 1 \\ + \textbraceleft & Inicio bloque de código & 7 \\ + \textbraceright & Fin del bloque de código & 7 \\ + ; & Separador de comandos Shell & 3 \\ + ' & Comilla simple & 1 \\ + " & Doble comilla & 1 \\ + < & Redirección de entrada & 1 \\ + > & Redirección de salida & 1 \\ + / & Separador de directorio & 1 \\ + ? & Comodín de un solo carácter & 1 \\ + \% & Identificador de nombre/número de trabajo & 8 \\ +\end{longtable} + +\subsection{Citando} +A veces querrá utilizar caracteres especiales literalmente, es decir, sin sus significados especiales. Esto se denomina \emph{entrecomillado}. Si rodea una cadena de caracteres con comillas simples, despojará a todos los caracteres entre comillas de cualquier significado especial que pudieran tener. + +La situación más obvia en la que podrías necesitar entrecomillar una cadena es con la orden \emph{print}, que simplemente toma sus argumentos y los imprime en la salida estándar. ¿Para qué sirve esto? Como verá en capítulos posteriores, el intérprete de comandos realiza bastantes procesos en las líneas de comandos, la mayoría de los cuales implican algunos de los caracteres especiales enumerados en la Tabla \ref{tab6}. \emph{print} es una forma de hacer que el resultado de ese proceso esté disponible en la salida estándar. + +\newpage + +Pero, ¿qué pasaría si quisiéramos imprimir la cadena, \texttt{2 * 3 > 5 is a valid inequality} Supongamos que escribimos esto: + +\begin{lstlisting}[language=bash] +print 2 * 3 > 5 is a valid inequality +\end{lstlisting} + +Volverías a tener el prompt del shell, ¡como si no hubiera pasado nada! Pero entonces habría un nuevo archivo, con el nombre 5, conteniendo <<2>>, los nombres de todos los archivos en tu directorio actual, y entonces la cadena \texttt{3 is a valid inequality}. Asegúrate de entender por qué\footnote{Esto también debería enseñarte algo sobre la flexibilidad de colocar redireccionadores de E/S en cualquier parte de la línea de comandos, incluso en lugares donde no parecen tener sentido.}. + +Sin embargo, si escribes + +\begin{lstlisting}[language=bash] +print '2 * 3 > 5 is a valid inequality.' +\end{lstlisting} + +el resultado es la cadena, tomada literalmente. No es necesario que cites toda la línea, sólo la parte que contiene caracteres especiales (o caracteres que crees que pueden ser especiales, si quieres estar seguro): + +\begin{lstlisting}[language=bash] +print '2 * 3 > 5' is a valid inequality. +\end{lstlisting} + +Esto tiene exactamente el mismo resultado. + +Observe que la Tabla \ref{tab6} enumera las comillas dobles ('') como comillas simples. Una cadena entre comillas dobles está sujeta a algunos de los pasos que sigue el shell para procesar líneas de órdenes, pero no a todos. (En otras palabras, trata sólo algunos caracteres especiales como especiales.) Verá en capítulos posteriores por qué las comillas dobles son a veces preferibles; el \hyperref[sec:Chapter7]{Capítulo 7} contiene la explicación más completa de las reglas del shell para las comillas y otros aspectos del procesamiento de la línea de órdenes. Por ahora, sin embargo, deberías ceñirte a las comillas simples. + +\subsection{Barra invertida} +Otra forma de cambiar el significado de un carácter es precederlo de una barra invertida (\textbackslash{}). Esto se denomina barra invertida-escapar el carácter. En la mayoría de los casos, cuando se escapa una barra invertida, se entrecomilla el carácter. Por ejemplo: + +\begin{lstlisting}[language=bash] +print 2 \* 3 \> 5 is a valid inequality. +\end{lstlisting} + +produce los mismos resultados que si rodeara la cadena con comillas simples. Para utilizar una barra invertida literal, basta con rodearla de comillas ('\textbackslash{}') o, mejor aún, con escaparla (\textbackslash{} \textbackslash{}). + +He aquí un ejemplo más práctico de cómo entrecomillar caracteres especiales. Algunos comandos Unix toman argumentos que a menudo incluyen caracteres comodín, que necesitan ser escapados para que el shell no los procese primero. El comando más común es \emph{find}, que busca archivos en árboles de directorios completos. + +Para utilizar \emph{find}, debe proporcionar la raíz del árbol en el que desea buscar y argumentos que describan las características de los archivos que desea encontrar. Por ejemplo, el comando \texttt{find . -name string -print} busca en el árbol de directorios cuya raíz es el directorio actual los archivos cuyos nombres coinciden con la cadena e imprime sus nombres. (Otros argumentos permiten buscar por tamaño del archivo, propietario, permisos, fecha del último acceso, etc.). + +Puede utilizar comodines en la cadena, pero debe entrecomillarlos para que el propio comando \emph{find} pueda compararlos con los nombres de los archivos de cada directorio en el que busca. El comando \texttt{find . -name '*.c'} buscará todos los archivos cuyo nombre termine en \texttt{.c} en cualquier lugar del directorio actual, subdirectorios, sub-subdirectorios, etc. + +\subsection{Comillas dobles} +También puede utilizar una barra invertida para incluir comillas dobles dentro de una cadena. Por ejemplo + +\begin{lstlisting}[language=bash] +print \"2 \* 3 \> 5\" is a valid inequality. +\end{lstlisting} + +produce el siguiente resultado: + +\begin{lstlisting}[language=bash] +"2 * 3 > 5" is a valid inequality. +\end{lstlisting} + +Dentro de una cadena entre comillas dobles, sólo es necesario escapar las comillas dobles: + +\begin{lstlisting}[language=bash] +$ print "\"2 * 3 > 5\" is a valid inequality." +"2 * 3 > 5" is a valid inequality. +\end{lstlisting} + +Sin embargo, esto no funcionará con comillas simples dentro de expresiones entrecomilladas. Por ejemplo, \texttt{print 'Bob\textbackslash{}'s hair is brown'} no dará como resultado \texttt{Bob's hair is brown}. Puede evitar esta limitación de varias maneras. Primero, intente eliminar las comillas: + +\begin{lstlisting}[language=bash] +print Bob\'s hair is brown +\end{lstlisting} + +Si no hay otros caracteres especiales (como en este caso), esto funciona. De lo contrario, puede utilizar el siguiente comando: + +\begin{lstlisting}[language=bash] +print 'Bob'\''s hair is brown' +\end{lstlisting} + +Es decir, '\textbackslash{}'' (comilla simple, barra invertida, comilla simple, comilla simple) actúa como una comilla simple dentro de una cadena entrecomillada. ¿Por qué? La primera ' de '\textbackslash{}'' termina la cadena entrecomillada que empezamos con 'Bob, la \textbackslash{}' inserta una comilla simple literal, y la siguiente ' inicia otra cadena entrecomillada que termina con la palabra <>. Si entiendes esto, no tendrás problemas para resolver los otros problemas desconcertantes que surgen de la sintaxis a menudo críptica del shell. + +Existe un mecanismo algo más legible, específico de \emph{ksh93}, para los casos en los que necesite entrecomillar comillas simples. Este es el mecanismo de entrecomillado extendido del shell: \texttt{\$'...'}. Esto se conoce en la documentación de \emph{ksh} como entrecomillado ANSI C, ya que las reglas se parecen mucho a las del estándar ANSI/ISO C. Los detalles completos se proporcionan en el \hyperref[sec:Chapter7]{Capítulo 7}. A continuación se muestra cómo utilizar el entrecomillado ANSI C para el ejemplo anterior: + +\begin{lstlisting}[language=bash] +$ print $'Bob\'s hair is brown' +Bob's hair is brown +\end{lstlisting} + +\subsection{Continuación de líneas} +Una cuestión relacionada es cómo continuar el texto de un comando más allá de una sola línea en la ventana de tu terminal o estación de trabajo. La respuesta es conceptualmente sencilla: basta con citar la tecla ENTER. Después de todo, ENTER no es más que otro carácter. + +Puede hacerlo de dos maneras: terminando una línea con una barra invertida o no cerrando una comilla (es decir, incluyendo ENTER en una cadena entrecomillada). Si utiliza la barra invertida, no debe haber nada entre ella y el final de la línea - ni siquiera espacios o TABs. + +Tanto si utiliza una barra invertida como una comilla simple, le está diciendo al shell que ignore el significado especial del carácter ENTER. Después de pulsar ENTER, el shell entiende que no ha terminado su línea de comandos (es decir, ya que no ha escrito un ENTER <>), por lo que responde con un prompt secundario, que es > por defecto, y espera a que termine la línea. Puedes continuar una línea tantas veces como desees. + +Por ejemplo, si quiere que el shell imprima la primera frase de \emph{The Return of the Native} de Thomas Hardy, puede escribir esto: + +\begin{lstlisting}[language=bash] +$ print A Saturday afternoon in November was approaching the \ +> time of twilight, and the vast tract of unenclosed wild known \ +> as Egdon Heath embrowned itself moment by moment. +\end{lstlisting} + +O puedes hacerlo así: + +\begin{lstlisting}[language=bash] +$ print 'A Saturday afternoon in November was approaching the +> time of twilight, and the vast tract of unenclosed wild known +> as Egdon Heath embrowned itself moment by moment.' +\end{lstlisting} + +Hay una diferencia entre los dos métodos. El primero imprime la frase como una línea larga. El segundo conserva las nuevas líneas incrustadas. Pruebe ambos y verá la diferencia. + + +\subsection{Teclas de control} +Las teclas de control (las que escribes manteniendo pulsada la tecla CONTROL (o CTRL) y pulsando otra tecla) son otro tipo de caracteres especiales. Normalmente no imprimen nada en la pantalla, pero el sistema operativo interpreta algunos de ellos como comandos especiales. Ya conoces uno de ellos: ENTER es en realidad lo mismo que CTRL-M (pruébalo y verás). Probablemente también hayas utilizado la tecla RETROCESO o SUPR para borrar errores tipográficos en tu línea de comandos. + +En realidad, muchas teclas de control tienen funciones que realmente no te conciernen - sin embargo, deberías conocerlas para futuras referencias y en caso de que las escribas por accidente. + +Quizás lo más difícil de las teclas de control es que pueden diferir de un sistema a otro. La disposición habitual se muestra en la Tabla \ref{Tab:1-7}, que lista las teclas de control que soportan las principales versiones modernas de Unix. Tenga en cuenta que CTRL-\textbackslash{} y CTRL-| (control-barra invertida y control-tubo) son el mismo carácter anotado de dos formas diferentes; lo mismo ocurre con DEL y CTRL-? + +Puede utilizar el comando \emph{stty(1)} para averiguar cuál es su configuración y cambiarla si lo desea; consulte el \hyperref[sec:Chapter8]{Capítulo 8} para más detalles. En sistemas Unix modernos (incluyendo GNU/Linux), use \texttt{stty -a} para ver su configuración de teclas de control: + +\begin{lstlisting}[language=bash] +$ stty -a +speed 38400 baud; rows 24; columns 80; line = 0; +intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = ; ; +eol2 = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; +lnext = ^V; flush = ^O; min = 1; time = 0; +... +\end{lstlisting} + +La notación \^{}X significa CTRL-X. +\newpage + +\begin{table}[h] + \center + \caption{Teclas de control} + \label{Tab:1-7} + \begin{tabular}{m{3cm}|m{2cm}|m{9cm}} \hline + \textbf{Tecla de control} & \textbf{Nombre de stty} & \textbf{Descripción de la función} \\ \hline + CTRL-C & intr & Detiene el comando actual \\ + CTRL-D & eof & Detiene el comando actual \\ + CTRL-\textbackslash{} ó CTRL-| & quit & Detiene el comando actual, si CTRL-C no funciona \\ + CTRL-S & stop & Detiene el comando actual, si CTRL-C no funciona \\ + CTRL-Q & start & Reinicia la salida a pantalla \\ + BACKSPACE ó CTRL-H & erase & Borra el último carácter. Esta es la configuración más común \\ + DEL ó CTRL-? & erase & Borra último carácter. Este es un ajuste alternativo común. para el carácter de borrado \\ + CTRL-U & kill & Borra toda la línea de comandos \\ + CTRL-Z & susp & Suspende el comando actual (ver \hyperref[sec:Chapter8]{Capítulo 8}) \\ + CTRL-R & rprnt & Reimprime los caracteres introducidos hasta el momento \\ + \end{tabular} +\end{table} + +La tecla de control que probablemente utilices más a menudo es CTRL-C, a veces llamada \emph{tecla de interrupción}. Esto detiene - o intenta detener - el comando que se está ejecutando en ese momento. Querrás usarla cuando introduzcas un comando y veas que está tardando demasiado, cuando le des los argumentos equivocados por error, cuando cambies de opinión sobre si quieres ejecutarlo, etc. + +A veces CTRL-C no funciona; en ese caso, si realmente quieres detener un trabajo, prueba con CTRL-\textbackslash. Pero no escriba simplemente CTRL-\textbackslash; ¡pruebe siempre CTRL-C primero! El \hyperref[sec:Chapter8]{Capítulo 8} explica por qué en detalle. Por ahora, basta con decir que CTRL-C da al trabajo en ejecución más oportunidad de limpiar antes de salir, para que los ficheros y otros recursos no queden en estados extraños. + +Ya hemos visto un ejemplo de CTRL-D. Cuando estás ejecutando un comando que acepta la entrada estándar de tu teclado, CTRL-D (como el primer carácter en la línea) le dice al proceso que tu entrada ha terminado - como si el proceso estuviera leyendo un archivo y llegara al final del archivo. mail es una utilidad en la que esto sucede a menudo. Cuando estás escribiendo un mensaje, terminas tecleando CTRL-D. Esto le dice a mail que su mensaje está completo y listo para ser enviado. La mayoría de las utilidades que aceptan entrada estándar entienden CTRL-D como el carácter de fin de entrada, aunque muchos de estos programas aceptan comandos como \emph{q, quit, exit,} etc. El propio intérprete de comandos entiende CTRL-D como el carácter de fin de entrada: como vimos anteriormente en este capítulo, normalmente puede finalizar una sesión de inicio de sesión escribiendo CTRL-D en el indicador del intérprete de comandos. Sólo le está diciendo al shell que su entrada de comandos ha terminado. + +CTRL-S y CTRL-Q se llaman caracteres de control de flujo. Representan una forma anticuada de detener y reiniciar el flujo de salida de un dispositivo a otro (por ejemplo, del ordenador a tu terminal) que era útil cuando la velocidad de dicha salida era baja. Están bastante obsoletos en estos tiempos de redes locales de alta velocidad y líneas de acceso telefónico. De hecho, en estas últimas condiciones, CTRL-S y CTRL-Q son básicamente una molestia. Lo único que realmente necesitas saber sobre ellas es que si la salida de tu pantalla se <>, puede que hayas pulsado CTRL-S por accidente. Escribe CTRL-Q para reiniciar la salida; cualquier tecla que hayas pulsado entretanto tendrá efecto. + +El último grupo de caracteres de control te ofrece formas rudimentarias de editar tu línea de comandos. RETROCESO o CTRL-H actúan como una tecla de retroceso (de hecho, algunos sistemas usan las teclas DEL o CTRL-? como <> en lugar de RETROCESO); CTRL-U borra toda la línea y te permite empezar de nuevo. De nuevo, la mayoría de estas funciones son obsoletas\footnote{¿Por qué se siguen utilizando tantas teclas de control obsoletas? No tienen nada que ver con el shell per se; en su lugar, son reconocidas por el controlador tty, una vieja y vetusta parte de las profundidades inferiores del sistema operativo que controla la entrada y salida a/desde tu terminal. De hecho, es el controlador tty el que entiende CTRL-D y señala el fin de la entrada a los programas que leen desde el terminal, no los propios programas.} En lugar de usarlas, vaya al siguiente capítulo y lea sobre los modos de edición del shell Korn, que están entre sus características más interesantes. diff --git a/Secciones/Capitulo10.tex b/Secciones/Capitulo10.tex new file mode 100644 index 0000000..8382808 --- /dev/null +++ b/Secciones/Capitulo10.tex @@ -0,0 +1,343 @@ +Los administradores de sistemas utilizan el intérprete de comandos como parte de su trabajo de configurar un entorno en todo el sistema para todos los usuarios. En este capítulo, discutiremos las características del shell Korn que se relacionan con esta tarea desde dos perspectivas: la personalización que está disponible para todos los usuarios y la seguridad del sistema. Asumimos que ya conoce los fundamentos de la administración de sistemas Unix.\footnote{Una buena fuente de información sobre administración de sistemas es \emph{Essential System Administration} de Æleen Frisch. Está publicado por O'Reilly \& Associates.} + +\section{Instalación del shell Korn como shell estándar} +Como preludio a la personalización de todo el sistema, queremos destacar algo sobre el shell Korn que no se aplica a la mayoría de los otros shells: puede instalarlo como si fuera el shell Bourne estándar, es decir, como \texttt{/bin/sh}. Simplemente guarde el shell Bourne real como otro nombre de archivo, como \texttt{/bin/bsh}, en caso de que alguien realmente lo necesite para algo (lo cual es dudoso), luego renombre (o enlace) su shell Korn como \texttt{/bin/sh}. + +Muchas instalaciones han hecho esto sin ningún efecto negativo. Esto no sólo hace que el shell Korn sea el shell de inicio de sesión estándar de su sistema, sino que también hace que la mayoría de los scripts del shell Bourne existentes se ejecuten más rápido, y tiene ventajas de seguridad que veremos más adelante en este capítulo. + +Como veremos en el \hyperref[sec:ApendiceA]{Apéndice A}, el shell Korn es retrocompatible con el shell Bourne excepto que no soporta \textasciicircum{} como sinónimo del carácter de tubería |. A menos que tenga un sistema Unix antiguo, o tenga algunos scripts de shell muy, muy antiguos, no necesita preocuparse por esto. + +Pero si quiere estar absolutamente seguro, simplemente busque entre todos los scripts de shell en todos los directorios de su \texttt{PATH}. Una manera fácil de hacer esto es usar el comando \emph{file(1)}, que vimos en el \hyperref[sec:Chapter5]{Capítulo 5} y en el \hyperref[sec:Chapter9]{Capítulo 9}. \emph{file} imprime <