UNIX System V Release 4 Guia Completa Bienvenido al gran mundo del sistema operativo UNIX. Si tiene experiencia con otros sistemas operativos, se sorprenderá de la inmensidad, diversidad y riqueza del entorno que ofrece el sistema UNIX. Si no tienes experiencia previa, entrarás fácilmente en el mundo de UNIX sin ideas preconcebidas. El sistema UNIX ofrece un entorno tan complejo que ni siquiera un libro de este tamaño puede cubrir completamente todas sus características y funcionalidades. No se desanime, el sistema UNIX y este libro están organizados para que los principiantes puedan comenzar con tareas simples y progresar hasta dominar el sistema por completo. Por otro lado, si está interesado en aprender más sobre el tema, o si quiere experimentar a fondo uno de los mejores sistemas operativos existentes, encontrará abundantes motivos de interés por el sistema UNIX. Ni siquiera los expertos conocen todo el sistema. En cualquier caso, acceda a un sistema UNIX y utilícelo; en poco tiempo el uso del sistema UNIX le parecerá natural y regresará a regañadientes a otros entornos. En los veinte años posteriores a su creación, el sistema operativo UNIX ha experimentado una evolución considerable hasta convertirse en uno de los entornos de desarrollo más utilizados y conocidos. Hoy en día, un número cada vez mayor de ordenadores (actualmente más de un millón), desde los más pequeños hasta los más potentes, soportan el entorno UNIX gracias a su gran flexibilidad y fiabilidad. Echemos un vistazo más de cerca a las características que han contribuido a su expansión: Herramientas de software El sistema UNIX introdujo una nueva forma de programación: cada aplicación es el conjunto de distintos componentes, cada uno de los cuales realiza una sola tarea de la mejor manera. De esta forma es posible desarrollar nuevos programas usando software existente y esto hace del sistema UNIX un entorno de trabajo particularmente eficiente. Portabilidad Puede portar su sistema UNIX a cualquier computadora mediana o grande. Hoy en día las computadoras personales tienen una capacidad de procesamiento que alguna vez estuvo reservada solo para computadoras muy costosas y el sistema UNIX representa el soporte natural para estas poderosas pero baratas máquinas. Solo fueron necesarias algunas modificaciones para adaptar el sistema UNIX al nuevo personal computer, lo que confirma su gran portabilidad. Esto no puede subestimarse ya que el desarrollo de software es un asunto tedioso y costoso. La mayoría de las aplicaciones, como los procesadores de texto, las bases de datos y los sistemas gráficos, pueden tardar muchos años en desarrollarse. Para utilizar las aplicaciones incluso después de dejar de lado el hardware en el que fueron desarrolladas, sin reescribirlas desde cero para las nuevas máquinas, es suficiente mantener el mismo sistema operativo en las nuevas computadoras. El sistema UNIX permite transportar aplicaciones sin excesiva dificultad entre computadoras personales, minicomputadoras y grandes computadoras, entre arquitecturas de sistemas antiguas y nuevas y especialmente entre diferentes versiones (releases) de sistemas UNIX. Flexibilidad UNIX es un sistema operativo extremadamente flexible y esta peculiaridad lo hace muy apreciado por los diseñadores de hardware y software, quienes lo consideran adecuado para aplicaciones de diferente naturaleza como la automatización de fábricas, los sistemas de conmutación telefónica y los juegos. Un número cada vez mayor de funciones nuevas y comandos inéditos se agregan rápidamente al sistema UNIX, y esta mejora continua ha convencido a la mayoría de los programadores a preferir el sistema UNIX a cualquier otro sistema operativo como respaldo para sus aplicaciones. Poder UNIX es uno de los sistemas operativos más simples y completos del mercado ya que cuenta con funciones y comandos predefinidos que están ausentes en otros sistemas operativos y una sintaxis clara y concisa que simplifica su uso. Multiusuario y concurrencia UNIX es un sistema multitarea de tiempo compartido que puede manejar fácilmente varias tareas en paralelo. En un sistema UNIX de un solo usuario, el programador puede escribir un archivo, enviarlo a una impresora y enviar correo a otra computadora simultáneamente. En un sistema multiusuario, UNIX permite que múltiples usuarios realicen varias tareas simultáneamente, dando a cada uno de ellos la impresión de ser el único usuario de la máquina. Elegancia UNIX es sin duda uno de los sistemas operativos más refinados, ya que, una vez familiarizados con algunos de sus conceptos básicos, los usuarios operan con sencillez obteniendo elegantes soluciones. Las personas que están acostumbradas a trabajar con UNIX y utilizan otros sistemas operativos a menudo se maravillan de cómo las cosas que parecen obvias en UNIX resultan complicadas en otros entornos de programación. Por esta razón, los desarrolladores suelen utilizar UNIX como ejemplo cuando desarrollan otros sistemas operativos. Orientación a la red Las versiones recientes de UNIX están estructuradas para un uso fácil y funcional de las redes de transmisión de datos. Las herramientas de transmisión de datos incluidas en el sistema y la fácil aceptación de controladores de bajo nivel de dispositivos adicionales son puntos fuertes del entorno en red actual, donde los usuarios de estaciones de trabajo personales comparten recursos centrales como bases de datos y dispositivos de comunicación. Las capacidades de administración de red de UNIX se vuelven cada vez más importantes a medida que aumenta la cantidad de computadoras conectadas en grupos de trabajo. Hoy en día, las extensiones de red van desde pequeñas redes de área local (LAN) hasta enlaces mundiales (NAN) que permiten la transmisión de grandes bases de datos. El sistema UNIX, con sus capacidades de multiprocesamiento (multitasking) y la amplia disponibilidad de software de comunicación, hace que la gestión de redes informáticas sea simple y fácil. Todas estas consideraciones ayudan a comprender por qué el sistema UNIX ha ganado una rápida popularidad en los últimos años y por qué seguirá desarrollando su potencial y extendiéndose aún más entre los usuarios de computadoras. 1.1 Elogios y críticas al sistema UNIX UNIX ha sido objeto, más que cualquier otro sistema operativo, tanto de elogios incondicionales como de críticas mordaces. Sus fanáticos señalan su elegancia, potencia y flexibilidad, mientras que sus detractores señalan su sintaxis escasa, nombres de comandos extraños, documentación imprecisa y complejidad. Por lo general, los expertos en sistemas UNIX se unen a la categoría de fanáticos, mientras que los novatos se unen al lado de los detractores. El sistema operativo UNIX fue desarrollado originalmente por un grupo de expertos en informática como una herramienta de desarrollo para su propio uso, ignorando así las necesidades de los principiantes en favor de la velocidad y la precisión, pero las características de simplicidad innatas de UNIX cerraron rápidamente la brecha existente entre expertos y principiante. Afortunadamente, las versiones más recientes de UNIX también se han dirigido a usuarios menos capaces, sin reducir el poder del sistema y sus otras ventajas. De hecho, la versión de UNIX SVR4 permite a casi todos los usuarios aprovechar al máximo el potencial que ofrece. Las mejoras logradas con las últimas versiones de UNIX se encuentran en las siguientes áreas: Robustez El sistema UNIX actual no requiere asistencia de software continua para seguir siendo eficiente y garantizar un alto rendimiento. Muchas operaciones que en versiones anteriores debían realizarse periódicamente, como borrar archivos de control o reiniciar el sistema, se han vuelto automáticas o innecesarias. Consistencia A lo largo de los años, la sintaxis de los comandos UNIX ha logrado una uniformidad tal que se reducen las diferencias y ambigüedades en los diferentes comandos. Si bien todavía hay varias inconsistencias, la tendencia es eliminarlos permanentemente. Agente de usuario La mayoría de las versiones de UNIX ahora tienen herramientas simplificadas (incluso sistemas expertos en algunos casos) que lo ayudan a configurar y administrar su sistema. Nuevas funciones Las últimas versiones de UNIX se han enriquecido con nuevos comandos y nuevas funciones de software. Muchos de estos están diseñados para introducir conceptos de Berkeley Software Development (BSD) y XENIX en los productos AT&T System V. Entre las diversas mejoras y novedades se encuentra una nueva organización del sistema de gestión de red; el entorno de desarrollo se ha mejorado y el soporte para compartir procesos en sistemas multiprocesador se mejora continuamente. Interoperabilidad La gran flexibilidad del sistema UNIX ahora se ha formalizado en la Interfaz binaria de aplicaciones (ABI) y en la Interfaz de programación de aplicaciones (API). Estas definiciones de entornos de desarrollo estándar en el sistema UNIX aseguran la evolución del sistema de forma controlada y planificada. Los fabricantes de software pueden estar seguros de que sus inversiones en el desarrollo de productos de software mantendrán su valor a medida que el software del sistema UNIX (API) y las máquinas que utilizan el sistema UNIX (ABI) evolucionen con el tiempo. Durante un período de tiempo más largo, el sistema UNIX avanza hacia una adhesión más estrecha al estándar internacional POSIX para sistemas operativos. El estándar POSIX proporciona un conjunto mínimo de funciones que eventualmente serán compatibles con los sistemas compatibles con UNIX en todo el mundo. Por supuesto, seguirán apareciendo más innovaciones, pero los estándares POSIX, API y ABI ayudarán a garantizar una base segura para us uarios y desarrolladores. Sistema Operativo de Tiempo de Cómputo Compartido Las últimas versiones para microcomputadoras permiten compartir máquinas y archivos entre el sistema UNIX y el sistema MS-DOS, o entre el entorno Apple Macintosh y el sistema UNIX. Compartir el sistema operativo significa poder aprovechar las capacidades de Simultaneidad de procesos (multitarea) que ofrece el sistema UNIX para ejecutar todo el MS-DOS (o Macintosh Finder) como un proceso que se ejecuta en el entorno UNIX. De esta forma, es posible ejecutar todas las funciones de baja prioridad (en segundo plano) del sistema UNIX en paralelo con la ejecución de programas en MS-DOS. Estas y otras mejoras del sistema UNIX han ayudado a disipar muchas de las críticas que se le han formulado hasta el momento. Sin duda, UNIX sigue siendo un sistema operativo potente y complejo, destinado a ser cada vez más fácil y fiable de usar. Por su historia como sistema nacido del uso experto, y con cierto aura mística, ha surgido una gran controversia y discusión en torno al sistema UNIX. 1.2 La filosofía del sistema UNIX El sistema UNIX nació esencialmente como una reacción a los sistemas operativos grandes, complejos e inflexibles disponibles a fines de la década de 1960. El objetivo principal del diseño fue obtener un sistema operativo de alto potencial, definiendo comandos que no intenten resolver todos los problemas posibles. Por el contrario, un aspecto fundamental típico de las tendencias más antiguas se refiere a la necesidad de tener comandos que realicen una sola acción, pero de la mejor manera. Por ejemplo, un comando que concatena y muestra archivos no necesita imprimirlos también. Estas tareas deben dejarse a otros programas que estén mejor capacitados para realizarlas. La filosofía de dividir el problema en aspectos simples e indivisibles ha tenido efectos significativos. En primer lugar, surgió un requisito que antes no existía: los datos producidos en salida por algunos de estos comandos deben constituir los datos de entrada de otros comandos. Por lo tanto, se definieron los conceptos de estructura de tubería, de archivos estándar de entrada y de salida estándar, conceptos que examinaremos en detalle más adelante. Segundo, debido a que desarrollar nuevos comandos y nuevas aplicaciones es menos problemático que otros sistemas operativos, el sistema UNIX está en constante evolución. Esta rapidez y facilidad de actualización y desarrollo del sistema es consecuencia directa de la forma en que ha sido concebida la estructura de sus comandos. De hecho, el sistema UNIX define una gran cantidad de comandos específicos y, si bien no es fácil aprender los nombres de funciones que en otros sistemas operativos se combinan en un solo comando, muchos usuarios coinciden en subrayar que las dificultades asociadas con el gran número de comandos se ven contrarrestados por la flexibilidad y el potencial que garantiza este enfoque. 1.3 Ventajas y desventajas del sistema UNIX actual El sistema UNIX sigue siendo objeto de controversia, a pesar de que sus características actuales de multiprogramación y concurrencia tienen una demanda cada vez mayor en el entorno de las minicomputadoras y las computadoras personales. Comparado con MS-DOS, por ejemplo, el sistema UNIX es más grande y más complejo, pero tiene como contrapartida muchas funciones que no están disponibles en MS-DOS o incluso en MS-OS/2. La filosofía original de los primeros UNIX ha ido desapareciendo gradualmente en las versiones más recientes, y ahora los nuevos comandos vienen con una gran cantidad de opciones y controles. Esta observación no debe ser engañosa, ya que los nuevos comandos pueden ser más difíciles de usar, incluso si pueden adaptarse más fácilmente a las situaciones que se presenten. En conclusión, se han conservado los conceptos clave del UNIX original, como el pipeline, mientras que se ha ampliado el potencial que ofrecen los comandos para cubrir nuevas necesidades. El sistema UNIX está principalmente orientado a terminales de caracteres y dispositivos periféricos. Se requiere un software complementario especial llamado X Window System para permitir que el sistema UNIX interactúe con terminales gráficos de mapa de bits. Esta confianza histórica en las terminales ASCII tiene la desventaja de que las herramientas y los procedimientos de UNIX están orientados a la línea de comandos, mientras que las herramientas y los menús del mouse en las terminales gráficas son raros, a diferencia de la nueva personalidad. Por otro lado, el sistema UNIX permite a los usuarios hablar con una máquina remota a través de una terminal de bajo costo y por líneas telefónicas ordinarias. Como resultado, el sistema es ideal para aplicaciones de servidor, donde la interfaz de usuario principal no está asociada con la máquina UNIX centralizada, sino que opera directamente en una terminal inteligente remota. Una arquitectura moderna está disponible para entornos de red local. El X W indow System Standard, un sistema de ventanas gráficas, tiene capacidad de integración de red: esto significa que una aplicación puede ejecutarse en una máquina en la red (generalmente una máquina de servidor rápida pero costosa) mientras que la interfaz de usuario puede ejecutarse en terminales de bajo costo, al alcance de cualquier usuario. Este esquema puede reducir significativamente el costo de instalar computadoras en un entorno de red. El sistema UNIX va en contra de la tendencia actual de hacer que los sistemas operativos sean invisibles para el usuario a través de interfaces de usuario que ocultan la vista del sistema operativo al usuario final. el Macintosh Finder, por ejemplo, es un sistema operativo que tiene funciones relativamente simples. La interfaz de usuario de ventana y menú ayuda a ocultar los comandos, el sistema de archivos y las herramientas de administración de los usuarios. En el sistema UNIX, por el contrario, cuanto mayor es el conocimiento de las funciones internas del sistema operativo, mayor es la posibilidad de aprovechar al máximo el sistema y obtener una mayor productividad del mismo. Esta situación surge principalmente por el hecho de que UNIX nació como un sistema para expertos, del cual la mayoría de los usuarios conocían la estructura interna. Ahora que el sistema UNIX se está adoptando ampliamente en todos los niveles, se ha equipado con herramientas como agentes de usuario o funciones de usuario par a aislar al usuario de los aspectos más complejos y menos inmediatos del sistema operativo. Sin embargo, aunque es posible utilizar el sistema sin tener un conocimiento profundo de sus funciones complejas, sin duda es beneficioso saber cómo funciona el sistema cuando ejecuta un comando. 1.4 Historia del sistema UNIX Aunque el sistema UNIX se originó en AT&T Bell Laboratories, una de las instituciones de investigación más grandes de los Estados Unidos, su historia es casi única en comparación con otros sistemas operativos, ya que su desarrollo se debe a las ideas creativas de las personas, así como a las necesidades de los usuarios, y no deriva directamente de decisiones burocráticas. Esto continúa siendo cierto hoy en día, por lo que el sistema UNIX puede considerarse un entorno muy favorable para la definición de nuevos conceptos de programación. UNIX fue creado por un grupo de personas de AT&T que habían seguido el desarrollo del sistema operativo MULTICS, nacido en el MIT en la década de 1960. Como precursor de los sistemas operativos de tiempo compartido, MULTICS tenía muchos conceptos típicos de los sistemas de la competencia de hoy, pero desafortunadamente era más complejo e intrincado de lo necesario, también debido a su papel innovador. En la década de 1960, AT&T se retiró casi por completo del proyecto MULTICS, dejando a un grupo de inteligentes investigadores ideas sobre cómo organizar un sistema de división del tiempo. Como ya no podían trabajar en el sistema MULTICS, estos investigadores decidieron crear un sistema operativo moderno. Los más destacados entre ellos fueron Ken Thompson y Dennis Ritchie, quienes basaron el primer borrador en un borrador de Rudd Canaday y posteriormente fueron influenciados por las ideas de otros investigadores capaces, incluidos J.F. Ossanna y R. Morris. Después de un período de discusión y ref lexión, lograron comprar un Digital PDP-7 y se pusieron a trabajar. Como ocurre con la mayoría de los mejores diseños, Thompson y Ritchie primero inventaron un juego (Space Travel) en el PDP-7. Tras esta experiencia, decidieron centrar sus esfuerzos en objetivos más satisfactorios y poco después crearon un nuevo sistema de archivos que se parecía mucho a los actuales. Posteriormente, mejoraron el sistema definiendo un entorno de proceso con programación y finalmente lo completaron en las partes faltantes con soluciones rudimentarias. La denominación UNIX nació como el proyecto era una simplificación del sistema MULTICS. A principios de la década de 1970, UNIX fue compatible con el PDP-7 y, a mediados de la década de 1970, también con el clásico y muy popular PDP-11. Muchos de los conceptos básicos del sistema UNIX actual también estaban presentes en las primeras versiones, incluido el sistema de gestión de archivos, el entorno de proceso y la estructura de la línea de comandos. La versión original estaba escrita en ensamblador, pero dado que el grupo de investigación también estaba desarrollando el lenguaje C en esos años, inmediatamente fue reescrita con este nuevo lenguaje. De hecho, en 1973, el kernel (núcleo) se recodificó en C. Hoy en día, solo unas pocas subrutinas del kernel que necesitan un alto rendimiento todavía están escritas en lenguaje ensamblador. El primer intento de escribir un sistema operativo en un lenguaje de alto nivel, por lo tanto, se remonta a esos años y la portabilidad que lo distingue es sin duda la razón principal de la popularidad que tiene UNIX. adquirido hoy. Al mismo tiempo, se definieron las herramientas de procesamiento de textos (conocidas hoy como troff), y el primer cliente del sistema UNIX se convirtió en la Oficina del Abogado de Patentes de Bell Laboratories, que comenzó a utilizar el programa troff en el otoño de 1971. UNIX inmediatamente capturó la imaginación de los investigadores de Bell Laboratories, y después de solo dos o tres años, comenzaron a aparecer alrededor de una docena de sistemas UNIX en diferentes computadoras. Con el correr de los años se realizaron frecuentes mejoras del software y AT&T decidió desarrollar el sistema en Bell Laboratories. El programa troff apareció en esta época, junto con muchas otras innovaciones. En cualquier caso, el sistema UNIX ganó el debido reconocimiento en la primera mitad de la década de 1970, con el desarrollo de ordenadores más potentes que el PDP-11 original, como el PDP-11/45 y el PDP-11/70. El sistema UNIX encontró un lugar natural en la arquitectura DEC y se vendió junto con el PDP-11. Los investigadores de Bell Laboratories comenzaron a usar máquinas UNIX para el procesamiento de textos, mientras que los ingenieros de Bell System comenzaron a usar PDP-11 habilitados para UNIX en sistemas telefónicos. Simultáneamente, AT&T distribuyó muchas copias del sistema UNIX a universidades de todo el mundo, y la generación de investigadores de la década de 1970 perfeccionó sus habilidades trabajando en UNIX. Incluso la Universidad de California en Berkeley diseñó su propia versión del sistema operativo llamado BSD (Berkeley Software Distribution) en esos años, que obtuvo una gran aceptación. A medida que AT&T centró su atención en completar y optimizar UNIX desde un punto de vista comercial, las versiones BSD se volvieron predominantes en las universidades. La compatibilidad entre las versiones de AT&T y BSD es cuestionable, y los usuarios de hoy en día suelen tomar un lado o el otro. Las versiones de _BSD mantienen la misma filosofía subyacente presente en las versiones de AT&T, aunque las mejores innovaciones de un sistema se suelen trasplantar también al otro. En la década de 1970, AT&T comenzó a cambiar el nombre de las versiones del sistema UNIX. En el pasado, cada mejora significativa del sistema producida por el grupo de investigación correspondía al lanzamiento de una nueva versión: en particular, dos de las versiones más populares lanzadas fueron identificadas como Sexta Edición y Séptima Edición. Luego de una reorganización interna del soporte de UNIX, AT&T cambió la numeración a System III y System V. Efectivamente, estas nuevas versiones son descendientes directas de la Séptima Edición y System V reemplazó a System III a mediados de la década de 1980. System IV se usó internamente en Bell Laboratories pero, al ser un producto de transición, no se extendió al exterior. Ahora, en la segunda mitad de la década de 1980, AT&T estandarizó el nombre System V y las versiones más recientes se denominan System V Release 3 y System V Release 4 y, a menudo, se abrevian como SVR3 y SVR4, respectivamente. A fines de la década de 1970 y principios de la de 1980, las versiones BSD y AT&T se portaron en casi todas las computadoras capaces de admitirlas. Esto condujo a la necesidad de unidades de disco de alta velocidad y soporte de administración de memoria integrado en la CPU, aunque las versiones experimentales de UNIX originalmente fueron concebidas para máquinas que tenían ROM, pero no discos duros. Hoy es posible adquirir versiones del sistema UNIX para las supercomputadoras más potentes, para los mainframes más utilizados y para casi cualquier minicomputadora del mercado. Las versiones de BSD dominaron como plataforma para experimentar con conceptos de red, de modo que ahora lo mejor en redes de área local está disponible para sistemas UNIX. El mayor experimento de red de área amplia, ARPANET, se orientó inicialmente hacia los sistemas UNIX. Network File System (NFS), creado por Sun Microsystems, y Remote File Sharing (RFS), creado por AT&T, son los productos finales de la evolución de esos conceptos. Ambos sistemas son actualmente redes funcionales y casi todos los entornos informáticos admiten conexiones a NFS o RFS. Muchas arquitecturas LAN basadas en PC se basaron generosamente en estas experiencias, pero UNIX aún tiene una sólida prioridad en el soporte de redes. La investigación en esta área sigue siendo muy activa en el entorno UNIX; son imaginables más innovaciones teniendo en cuenta que los sistemas multiprocesador están ganando cada vez más interés en la industria informática. Cuando la microcomputadora aumentó el rendimiento en términos de velocidad y potencia, al mismo tiempo que disminuyó los costos, entró en la esfera de acción del sistema UNIX. Las máquinas basadas en 8088 eran casi lo suficientemente potentes como para admitir el sistema UNIX, pero solo unas pocas versiones podían ejecutarse en estas computadoras. El popular sistema operativo XENIX, originalmente una versión reducida para IBM-PC que alcanzaba o excedía el límite de capacidad de la máquina, se puede explotar completamente en computadoras equipadas con un microprocesador 80286 o 80386. Ahora que muchas de las funciones de XENIX se han incluido en la línea principal del sistema UNIX, se espera que XENIX desaparezca como una línea separada en la historia de los sistemas UNIX. Cuando los sistemas SVR3 y SVR4 estuvieron disponibles para máquinas con arquitectura PC-AT por fin Desde la década de 1980, la popularidad de UNIX ha dado un gran salto adelante. Las máquinas de clase AT 80386 proporcionaron un entorno muy conveniente para el sistema UNIX; Actualmente, más de la mitad de los sistemas UNIX están instalados en estas computadoras populares. Otro paso notable se produjo con la creciente y amplia aceptación del sistema X Window como parte del sistema UNIX. X, como suele llamarse para abreviar, se prototipó como un proyecto de investigación en el MIT a mediados de la década de 1980, luego fue adoptado por un consorcio de fabricantes de sistemas UNIX, quienes consolidaron su calidad para un producto comercial y aumentaron sus características. Sun y Apollo introdujeron otros sistemas de ventanas orientados al mouse, pero X ha llegado a dominar como el estándar de la industria no patentado. Hoy en día, muchos paquetes de aplicaciones para sistemas UNIX funcionan en el entorno X. Recientemente, Bell Laboratories AT&T desarrolló una nueva versión completa denominada "Décima Edición" o "Research UNIX System" que, aunque no se comercializó, se ha distribuido ampliamente en las universidades. Con el tiempo, las innovaciones de lanzamiento de investigaciones se incluirán regularmente en los productos System V. La fusión de las tres principales variantes del sistema UNIX comenzó con las últimas versiones de SVR3 y está a punto de completarse en SVR4. Hoy, como resultado de los acuerdos entre AT&T, Sun Microsystems y Microsoft, los sistemas BSD y XENIX se están integrando en el producto System V. La mayoría del software construido para BSD o XENIX podrá usarse sin cambios con los sistemas SVR4, mientras que las variantes desaparecerá con la inclusión de sus funciones en la versión System V. El producto resultante también permitirá la compatibilidad a nivel de código de objeto entre variantes fabricadas para máquinas del mismo tipo. Mientras la integración de BSD y System V estaba en marcha, varios otros proveedores de sistemas UNIX comenzaron a preocuparse de que el sistema integrado pudiera permitir que AT&T y Sun Microsystems dominaran el mercado. Estos proveedores (principalmente IBM, Hewlett-Packard, DEC) formaron un consorcio para desarrollar una variante del sistema fuera del control de AT&T o Sun. Este grupo, denominado Open Software Foundation (OSF), ya ha desarrollado varios productos importantes del sistema UNIX. la más importante de las cuales es la especificación Motif UI. En respuesta, AT&T y otro grupo de proveedores de sistemas UNIX formaron su propio gran consorcio, UNIX International, para estandarizar y publicitar las versiones de System V en la década de 1990. Algunas empresas pertenecen a ambos grupos. Siguiendo la historia de la estimulación y competencia entre BSD y el sistema UNIX, las tensiones competitivas entre OSF y UNIX lnternational podrían producir muchos resultados positivos en el futuro. Appie Computer también adaptó SVR4 para su familia de computadoras Macintosh e incorporó con éxito Finder y la presentación e interfaz clásicas de Macintosh en el sistema UNIX, al igual que MS-DOS se incorporó a los productos Merge y Simultask. La fuerza de UNIX para superar las diferencias de hardware se destaca claramente con la aparición de computadoras con conjunto de instrucciones reducido (RISC) a finales de los 80 y principios de los 90. Las computadoras RISC implementan un concepto fundamentalmente diferente al seguido por los microprocesadores entonces dominantes, un concepto que hace que el diseño de chips de CPU sea más fácil, rápido y menos costoso. Se desarrollaron varios microprocesadores RISC en un corto período de tiempo y, debido a la dificultad y el costo de desarrollar un sistema operativo completamente nuevo para cada máquina nueva, prácticamente todas las máquinas RISC adoptaron el sistema UNIX. Incluso se han diseñado varias máquinas RISC para proporcionar el mejor rendimiento para el sistema UNIX. Como resultado, las mejores y más rápidas microcomputadoras disponibles en la actualidad son las máquinas RISC. Durante la década de 1990, los desarrollos más significativos estarán en las funciones de multiprocesamiento que permitirán arquitecturas de máquinas con múltiples chips de CPU centrales. Estas máquinas comparten otros recursos, como energía, memoria principal, discos, y permiten mayores capacidades de procesamiento a un costo menor que las máquinas adicionales. En los sistemas multiusuario, los numerosos procesos se pueden distribuir de manera eficiente entre varios procesadores, pero los sistemas de un solo usuario o los servidores en red pueden distribuir igualmente la carga adicional. Los sistemas de multiprocesamiento seguramente serán un factor importante en la vida de SVR4. En los noventa la variante OSF probablemente se convierta en una alternativa válida a la versión SVR4; eventualmente se adoptarán herramientas e ideas exitosas que se originen en cualquiera de los dos sistemas. a otro, aunque no inmediatamente y ni siquiera en la próxima versión del sistema. Por lo general, los proveedores de software adicional son los primeros en presentar características de un sistema para otro, por lo que vale la pena mantenerse informado sobre las nuevas herramientas y procedimientos que existen solo en una determinada variante de su sistema UNIX. Lo mismo sucede en otros sistemas operativos; Las innovaciones en MS-DOS, OS/2, NeXT, el entorno Macintosh e incluso las versiones IBM/6000 del sistema UNIX suelen estar disponibles como productos complementarios para el SVR1. 1.5 La versión SVR4 SVR4 es la última versión del sistema AT&T UNIX. Se llevó a cabo en la mayoría de las máquinas y es el estándar actual para la línea AT&T. Después de muchos cambios realizados, SVR4 se mejora significativamente en comparación con las versiones anteriores. Muchas de las nuevas características son principalmente de interés para los usuarios en entornos de desarrollo y administradores de sistemas, pero en muchos casos las mejoras también afectan en última instancia a los usuarios finales, lo que da como resultado aplicaciones mejores, más fáciles de usar, más rápidas y menos costosas. Algunas de las actualizaciones más importantes se describen en los siguientes puntos. ================ Capitulo 2 Introducción al uso del sistema UNIX 2.1 Acceso al sistema (login) Sistema de ventana 2.2X 2.3 Leer las noticias 2.4 Lista de archivos 2.5 Ver archivos 2.6 Eliminación de archivos 2.7 Lectura de correo 2.8 Envío de correo 2.9 Lista de usuarios activos 2.10 Cambiar su contraseña 2.11 Salir del sistema (cerrar sesión) 2.12 Perspectivas Para empezar, examinemos cómo se lleva a cabo una sesión de trabajo corta, introduciendo algunos conceptos fundamentales y presentando algunos ejemplos de interacción entre el usuario y el sistema operativo. Al final de este capítulo, podrá iniciar y cerrar sesión en UNIX sin dificultad. Supongamos que la conexión ya existe entre el terminal y la máquina en la que se carga UNIX. La mayoría de los novatos necesitan usuarios más experimentados para inicializar la máquina, pero puede hacerlo fácilmente después de aprender algunas nociones preliminares sobre cualquier sistema operativo. Si tiene una máquina en la que nunca ha trabajado antes, es una buena idea leer primero el Capítulo 25 y luego examinar el Capítulo 21. Cuando el sistema esté cargado e inicializado, puede volver a leer este capítulo. Su terminal puede ser una consola del sistema, un terminal en modo de caracteres conectado directamente a la máquina a través de un puerto RS232, o un terminal remoto conectado a través de una línea telefónica y un módem, o incluso un terminal conectado a través de una Red de área local (Local Area Network). ). No importa qué tipo de terminal uses, ya que el sistema se comporta de la misma manera para cada uno de estos terminales. Los terminales y sus configuraciones se tratan en el Capítulo 12. El acceso estándar al sistema ocurre completamente en modo de personaje y no aparecen gráficos o íconos en la pantalla. Dado que UNIX se desarrolló originalmente para terminales tontos, gran parte del sistema requiere que los terminales funcionen en modo de caracteres. UNIX utiliza el conjunto ASCII (American Standard Code for Information Interchange), por lo que terminales del tipo IBM 3270 no suelen funcionar bajo UNIX y los terminales gráficos deben tener modo ASCII. Para utilizar el Sistema X Window, la interfaz de ventana habitual, deberá utilizar la consola del sistema o un terminal inteligente conectado a una red. 2.1 Acceso al sistema (login) Una vez que el terminal está conectado a la máquina, puede ser necesario presionar la tecla RETORNO una o dos veces para activar el sistema UNIX. En este punto, aparece un aviso (inicio de sesión) en la pantalla que indica la disponibilidad del sistema para recibir sus comandos: Bienvenido al sistema AT&T 386 UNIX. Nombre del sistema: my_sys acceso: Si no ve el inicio de sesión: indicador, debe pedirle al administrador del sistema que corrija algún problema con los parámetros de su sistema. Dado que UNIX es un sistema multiusuario, inmediatamente exige poder identificarlo con absoluta certeza. De esta forma el sistema verifica tu intención de acceder a los archivos privados y asigna a la sesión de trabajo la prioridad que hayas establecido. Cada usuario que se conecta al sistema es referenciado por un identificador (login id), que generalmente corresponde a su nombre, sus iniciales o alguna otra palabra. La única restricción es que este identificador debe tener menos de ocho caracteres y contener solo letras y números. En particular, existe una diferencia entre mayúsculas y minúsculas, por lo que el identificador "GIORGIO" es diferente de giorgio. Todos los identificadores deben comenzar con una letra minúscula, de lo contrario el sistema cree que te estás conectando desde un terminal que funciona solo con letras mayúsculas y no habría correspondencia entre quién eres y lo que el sistema piensa de ti. El identificador personal debe ser único, es decir, no puede haber otro usuario e n el sistema que se identifique como usted. Si ha elegido a giorgio como identificador, responda al aviso del sistema ingresando la cadena giorgio: Bienvenido al sistema AT&T 386 UNIX. Nombre del sistema: my_sys inicio de sesión: jorge y terminar presionando el botón RETORNO. A diferencia de lo que suele suceder cuando escribe texto en un entorno UNIX, generalmente no es posible RETROCEDER ningún error que cometa en la línea de solicitud de inicio de sesión, porque el sistema aún no lo ha identificado. El uso de la tecla RETROCESO para eliminar un carácter se considera una opción de nivel de usuario. Si comete un error al escribir su identificador o contraseña, aún debe completar la operación; si comete un error en el procedimiento de inicio de sesión, el sistema le permite repetirlo por segunda vez. Después de ingresar su identificador, el sistema le solicita su contraseña: Bienvenido al sistema AT&T 386 UNIX. Nombre del sistema: my_sys inicio de sesión: jorge Contraseña: El sistema operativo UNIX pide confirmación de que vo i usted es la persona autorizada para usar el identificador especificado anteriormente, ya que generalmente es de dominio público. Esta precaución es esencial para proteger sus archivos y otros datos privados de la curiosidad de otros usuarios. Luego ingrese su contraseña y finalice la operación presionando la tecla RETORNO. A diferencia de lo que sucede cuando el sistema le pide que especifique el identificador, el sistema ahora no muestra los caracteres de la contraseña a medida que los ingresa desde el teclado. (Esta operación en la terminología de UNIX se denomina eco). Esta es una medida de seguridad adicional que evita que alguien detrás de usted descubra su contraseña. Si ingresa una identificación de usuario o contraseña incorrecta, o si no está autorizado para usar la máquina, el sistema responde de la siguiente manera: Bienvenido al sistema AT&T 386 UNIX. Nombre del sistema: my_sys inicio de sesión: jorge Contraseña: Acceso incorrecto acceso: El sistema no especifica quién, entre el identificador y la contraseña, ha generado el error, pero te da una segunda oportunidad. Escriba su identificador nuevamente, seguido de su contraseña. Una vez que el sistema ha aceptado el par identificador-contraseña, muestra un encabezado inicial y algunos mensajes: Sistema UNIX V/386 Versión 4.0 Sistema my_sys Copyright(s) 1984, 1986, 1987, 1988, 1989 AT&T Copyright(e) 1987, 1988 Microsoft Corp. Todos los derechos reservados El sistema my_sys se reducirá a la instalación del software de 6:00 a 7:00 PM esta noche. = pat noticias: nuevo_usuario Tenes correo electronico. ps Estos mensajes probablemente sean diferentes de los que ve en su sistema, pero este ejemplo es típico de un sistema UNIX multiusuario. El primer mensaje: Sistema UNIX V/386 Versión 4.0 es solo un encabezado que identifica la versión del sistema en uso. El siguiente mensaje my_sys identifica la máquina. Cada sistema UNIX tiene un nombre que lo identifica de manera única. A continuación se incluye información relacionada con los derechos de autor del software que está instalado en la máquina. Esta información puede ser sobre quién lanzó al mercado esa versión particular del sistema UNIX y qué otro software está instalado en la máquina. A veces también puede seguir una tabla más o menos larga que resume el uso del espacio en disco; a menudo se omite en sistemas grandes. Reservamos la discusión de esta información para el Capítulo 18. El siguiente mensaje constituye el "mensaje del día"; lo ingresa el operador del sistema y generalmente se usa para anunciar alguna información de interés común. La siguiente línea: noticias: nuevo_usuario representa otra característica del sistema UNIX denominada noticias, que el administrador del sistema suele utilizar para enviar información que tiene una duración superior a la contenida en el mensaje del día y, una vez leído, el aviso desaparece en el momento de la asignación. El mensaje del día, en cambio, se muestra cada vez que accede al sistema, hasta que el administrador decide cambiarlo o eliminarlo. El mensaje de noticias también especifica el asunto de la información, que en este caso se refiere al usuario (nuevo_usuario). Última línea mostrada: Tenes correo electronico. anuncia la presencia en su "bandeja de entrada" de un mensaje dirigido a usted por otro. Este mensaje aparece cada vez que inicia sesión en el sistema hasta que procesa su correo pendiente. A diferencia de lo que ocurre con el mensaje de noticias, una vez leído el correo, aparece el mensaje Tienes correo. no desaparece automáticamente cuando lo asigna al sistema. Finalmente finaliza el proceso de asignación; el sistema le da el control, muestra el indicador $ y espera su comando, que es analizado por el shell (el intérprete de comandos). Sistema de ventana 2.2X Si su inicio de sesión se ha configurado para iniciar el Sistema X Window y está utilizando un terminal inteligente o una PC, la pantalla se verá bastante diferente a la que se muestra en el párrafo anterior; en lugar de mostrar el indicador $, su pantalla se verá similar a la Figura 2.1. Por lo general, aparecerá un menú de Workspace en algún lugar de la pantalla, que se usa para controlar su sesión y elegir entre algunas opciones. Puede haber una ventana del Administrador de archivos similar a la pantalla de Macintosh o MS Windows. El Administrador de archivos facilita la navegación dentro del sistema de archivos. Probablemente verá una o más ventanas de xterm, cada una de las cuales contiene el indicador $. Cada una de estas ventanas emula una terminal y le permite usar la línea de comando normal del sistema UNIX: por esta razón, el indicador $ aparece en cada una. También verá la ventana Buzón (xbiff), que le advierte del correo entrante con una bandera levantada sobre el buzón en el icono. El sistema X Window se controla con el mouse o el teclado, por lo que su pantalla también mostrará un puntero de mouse en alguna parte; moviendo el ratón verás que el puntero cambia de posición. También podrá cambiar su apariencia desplazándose a diferentes áreas de la pantalla. Al mover el mouse y presionar el botón izquierdo (en la jerga, hacer clic), puede activar diferentes áreas de la pantalla. Por ejemplo, si mueve el puntero del mouse sobre la ventana xterm y presiona el botón izquierdo, selecciona esa ventana y los caracteres que escribe desde el teclado se ingresarán en la ventana seleccionada. El sistema de ventanas X se cubre en el Capítulo 23. Por ahora, asegúrese de que la ventana xterm esté activa con un movimiento del mouse y haga "clic" como se describe. Cuando una ventana está activa, su borde superior se destaca en un color que contrasta con los bordes de otras ventanas en la pantalla. Puede ejecutar comandos normales del sistema UNIX dentro de la ventana activa. 2.3 Leer las noticias Es recomendable leer primero las noticias de carácter general ya que pueden afectar al uso posterior del sistema. Para leer esta noticia, simplemente escriba desde el teclado: $news seguido de la tecla RETORNO. El sistema muestra el indicador $, por lo que no es necesario ingresarlo explícitamente desde el teclado. No olvide que el sistema interpreta los caracteres en minúsculas y mayúsculas de manera diferente, y que news y la mayoría de los demás comandos se ingresan solo en minúsculas. En este punto, el intérprete de comandos (el shell) ejecuta el comando de noticias, por lo que la información aún no examinada se muestra en la pantalla. Cuando ingresa el comando de noticias, la respuesta del sistema es la siguiente: $news new_user (pat) lunes 22 de junio 08:26:47 1991 ¡El sistema 'my_sys' tiene un nuevo usuario! Bienvenido 'giorgio'.... pat ps Si hay varias noticias, se mostrarán de forma sucesiva. Cada entrada comienza con una línea de encabezado que identifica la información, indica el remitente (entre paréntesis) y la fecha de escritura. Cuando se ha mostrado toda la información, el programa de noticias termina y el control vuelve al shell, que espera otros comandos. 2.4 Lista de archivos Puede tener la lista de archivos que se almacenan en su área de datos privados. El sistema UNIX tiene un excelente sistema de archivos para almacenar archivos y comandos. Después de la fase de asignación del sistema, se encuentra en un área específica del sistema de archivos, llamada directorio preferido (directorio home/), que generalmente contiene sus archivos y datos privados. Dado que cada usuario posee un directorio de inicio, no se comparten archivos entre los usuarios del sistema. Esta separación de datos hace que diferentes usuarios puedan elegir los mismos identificadores para referenciar sus archivos, sin causar problemas. El sistema de archivos se trata en el Capítulo 4. Puede enumerar sus archivos con el comando ls (listar): $ls notas PRUEBA ps Ingrese el comando ls desde el teclado inmediatamente después del indicador $ y, una vez ejecutado, el control regresa al shell que espera el siguiente comando. En este ejemplo, notamos que hay dos archivos: notas y PRUEBA. Recuerde que hay una diferencia entre minúsculas y mayúsculas, por lo que el archivo PRUEBA no coincide con el archivo de prueba. Dado que es un principiante, la cantidad de archivos a su disposición es pequeña, pero no es raro ver listados con cien archivos. No hay limitación en el número de archivos en un directorio. En muchos casos, es posible que un nuevo usuario no encuentre ningún archivo en el directorio de inicio y el resultado producido por el comando ls es ligeramente diferente: $ls ps El comando ls no muestra nada y devuelve el control directamente al shell. Este hecho demuestra una característica general del sistema UNIX: si no hay nada que decir, el sistema no dice nada. Aunque el comportamiento del sistema puede parecer demasiado conciso en esta circunstancia, la razón de su silencio se explicará en capítulos posteriores. Como la mayoría de los comandos, ls también tiene varias opciones. Por ejemplo, puede utilizar la siguiente línea: $ls-yo La opción -l (menos ele) hace que el comando ls genere una lista larga, es decir, una lista que contiene más información sobre un archivo que la que muestra la versión estándar del comando. Si desea que un comando realice más acciones de las habituales, debe indicarlo en la lista de argumentos. Cada argumento debe estar precedido por el signo - (menos) y toma el nombre de una flag u opción. Deje un espacio después del nombre del comando, pero ningún espacio debe separar el signo - de la letra que representa el argumento relacionado. El resultado del comando anterior puede ser el siguiente: $ls-yo 2 totales - rw - rw - rw - - rw - rw - rw - 1 jorge 1 jorge usuarios usuarios 138 5 de abril 19:34 INTENTAR 227 5 de abril 19:33 notas ps Este ejemplo introduce algunas consideraciones de archivo. El primer término a la izquierda, - rw - rw- rw-, especifica los derechos de acceso al archivo, mientras que george indica el propietario del archivo, que forma parte del grupo de usuarios; siga el tamaño del archivo expresado en bytes, luego una fecha del archivo y finalmente el nombre del archivo. (Estos y otros atributos de archivo se tratan en el Capítulo 4). Los argumentos en los comandos del sistema UNIX cumplen la misma función que en MS-DOS y otros sistemas operativos, es decir, modificar la ejecución del comando. Sin embargo, a diferencia de MS-DOS, los argumentos de los comandos de UNIX comienzan con un signo - (menos) en lugar de una / (barra oblicua), que tiene un significado diferente en UNIX. Los comandos generalmente tienen muchos argumentos, lo que ayuda a que el sistema sea extremadamente flexible y poderoso. Puede consultar el Manual del usuario de UNIX, el documento de referencia más importante sobre el sistema UNIX, para conocer la sintaxis exacta de todos los argumentos disponibles para cada comando. (El Capítulo 9 analiza en detalle el Manual del usuario de UNIX). 2.5 Ver archivos Su directorio de inicio contiene dos archivos cuyo contenido puede ver. El comando cat (concatenar archivos) hace esto: $cat notas Este comando destaca otro aspecto general de los comandos: los nombres de archivo son generalmente argumentos que no contienen ningún marcador en particular. El siguiente comando muestra el contenido del archivo en la pantalla: $cat notas Hola, george, bienvenido a mi sistema. Seguro que disfrutará utilizando el sistema UNIX; déjame saber cómo va tu aprendizaje pat ps Tenemos que hacer algunas aclaraciones. Primero, el comando cat muestra el contenido del archivo y luego devuelve directamente el control al shell, que espera el siguiente comando. En segundo lugar, el archivo se muestra sin encabezados especiales ni nada que no esté contenido en el archivo. Lo dicho refuerza las consideraciones hechas en el párrafo anterior sobre la naturaleza extremadamente sintética del sistema UNIX. 2.6 Eliminación de archivos El comando cat no modifica el archivo, por lo que aún está presente en el directorio. Para eliminarlo, use el comando rm (eliminar). $rm notas ps Este comando elimina el archivo y devuelve el control al shell. Al escribir el comando ls nuevamente, puede verificar que falta el archivo: $ls PRUEBA ps En el entorno UNIX, no es posible recuperar un archivo eliminado con el comando rm. Por lo tanto, dado que este comando es tan drástico, es útil que el sistema le pida confirmación de la eliminación del archivo, antes de continuar. Para hacer esto, use la opción -i (interactiva), por lo que la línea de comando se convierte en: $ rm -i notas rm: eliminar nota: (s/n)? El comando rm quiere saber si realmente está decidido a eliminar el archivo y, si esa es su intención, ingrese el carácter y del teclado, de lo contrario, cualquier otro carácter. $ rm -i notas rm: eliminar nota: (s/n)? y ps Por lo tanto, el archivo se elimina. Si desea eliminar más de un archivo con un solo comando rm -i, el sistema solicita confirmación de la operación para cada archivo. Puede interrumpir la ejecución del comando, mientras está esperando datos, y regresar directamente al shell, presionando la tecla DEL o BREAK. $ rm -i notas rm: quitar nota: (yin)? DEL ps El sistema borra del directorio todos los archivos que haya decidido borrar, respondiendo afirmativamente a la solicitud de confirmación, antes de interrumpir la ejecución del comando con DEL, mientras que los archivos que no intervienen en la operación de borrado permanecen en el directorio. Recuerde que casi cualquier comando puede interrumpirse mientras espera los datos de entrada. Puede usar esta técnica para interrumpir comandos que producen una salida demasiado larga. Piense en lo que sucede si presiona la tecla DEL mientras el shell está esperando su entrada. 2.7 Lectura de correo No olvide que al iniciar sesión en el sistema, aparece este mensaje en pantalla: Tenes correo electronico. para indicar la presencia de correo que los usuarios del sistema le han enviado. Si no hay correo no aparece el mensaje anterior. El correo electrónico funciona conceptualmente como el servicio de correo tradicional: permite la comunicación entre usuarios, cada uno de los cuales está identificado por una dirección, y cada mensaje tiene un sobre y un contenido. Puede leer el correo dirigido a usted, usando el comando de correo: $mail Esto le dice al shell que ejecute el comando de correo que busca en el buzón y muestra secuencialmente cada mensaje que contiene. $mail De Leo Lun 6 de abril 18:24 MST 1991 Hola George, bienvenido al sistema UNIX. ¿Por qué no vamos a almorzar? juntos para discutir nuestro proyecto? - león ? La primera línea que sigue al comando representa el encabezado (matasellos) y advierte que este mensaje proviene de Leo, quien lo envió el lunes 6 de abril de 1991 a las 18:24. Por lo general, no importa cuándo se envió el mensaje, pero este encabezado puede ser útil en algunos casos, como se explica en el Capítulo 14. Después de mostrar el mensaje, el programa de correo espera los datos entrantes y muestra el carácter ? , para saber qué acción tomar en ese mensaje. Puede eliminar el mensaje, solicitar otro (si existe), guardarlo en un archivo o solicitar otras acciones. Para borrar el mensaje, simplemente presione d, seguido de un retorno de carro: $correo De Leo Lun 6 de abril 18:24 MST 1991 Hola George, bienvenido al sistema UNIX. ¿Por qué no vamos a almorzar? juntos para discutir nuestro proyecto? - león ?d ps El programa de correo borra el mensaje sin dar explicaciones. Como no hay más mensajes, el programa sale y el control vuelve al shell. Si, por el contrario, tu correo no se ha agotado, cada mensaje se muestra una vez que hayas terminado de procesar el anterior. Luego puede leer cada mensaje posterior y eliminarlo de una forma u otra. Si está utilizando el sistema X Window, puede notar que la bandera del buzón se apaga tan pronto como haya eliminado el mensaje del correo; Dado que UNIX es un sistema multitarea, muchas cosas pueden suceder en su pantalla simultáneamente. También es normal que se iza la bandera en cuanto llega un nuevo mensaje postal. El comando mail tiene ayuda interactiva para recordarle todas las opciones que tiene disponibles cuando se le solicite. Si no ha eliminado un mensaje, puede ingresar el carácter ? en lugar de d, como se indica en la Figura 2.2. En el Capítulo 14, cubriremos las diferentes opciones que están disponibles con el comando de correo, pero es importante tener en cuenta por ahora el amplio conjunto de operadores que puede usar para manejar mensajes. 2.8 Envío de correo Obviamente, además de recibir correo de otro usuario, también puedes enviar mensajes. El comando mail se usa tanto para enviar como para leer correo: $mail leo Los argumentos que especifica para el comando de correo le indican qué acción tomar. En este caso hemos indicado el nombre del destinatario del mensaje. Mientras que el comando cat recibe como argumento el nombre de un archivo, ya que su función es concatenar y mostrar archivos, el comando mail posibilita la comunicación entre usuarios, por lo que como argumento es fundamental especificar el identificador de usuario (o de usuarios) a quien desea enviar el mensaje. Muchos comandos en el sistema UNIX se refieren a los usuarios por su identificador o identificación de inicio de sesión, es decir, muchos comandos esperan la identificación de inicio de sesión en lugar del nombre real del usuario. Como la mayoría de los comandos, el correo acepta más de un argumento. Puedes escribirles desde el teclado: $mail leo george para enviar el mismo mensaje a Leo y a ti mismo. Una vez lanzado el comando anterior, el programa de correo comienza a ejecutarse, el cual interrumpe para permitirte escribir el mensaje. Por ejemplo: $mail leo george Leo, gracias por la bienvenida y la invitación a comer, que acepto con mucho gusto. Hasta luego. Jorge Puede escribir un mensaje de cualquier longitud. Si comete un error tipográfico, puede corregirlo con RETROCESO. Sin embargo, una vez que presiona la tecla RETORNO, el sistema UNIX (y, en particular, el programa de correo en este caso) ha adquirido datos que ya no se pueden eliminar fácilmente a partir de este momento. Si desea interrumpir la ejecución del programa y volver al shell sin enviar ningún mensaje, presione la tecla DEL. Si no pretende interrumpir la ejecución del programa de correo sino simplemente informarle que ha terminado de ingresar el texto del mensaje, presione CTRL-D, como en el siguiente ejemplo. Aunque CTRL-D a menudo se indica con una D mayúscula, es suficiente presionar la tecla CTRL y directamente la tecla o sin presionar la tecla shift. $mail leo george Leo, gracias por la bienvenida y la invitación a comer, que acepto con mucho gusto. Hasta luego. Jorge CTRL-D Tiene correo electronico. ps El programa de correo envía el mensaje (si no hay errores) y devuelve el control al shell, para la ejecución del siguiente comando. Si no hay errores al compilar o ejecutar el comando, el sistema no muestra ningún mensaje. En el ejemplo anterior, observe que el shell muestra otro mensaje: Tiene correo. De hecho, dado que se enviaron una copia del mensaje, el shell le advierte que tiene correo retenido. Este mensaje aparece solo una vez hasta que vuelva a iniciar sesión en el sistema y puede optar por no leer el correo de inmediato (especialmente si se lo envió a usted mismo). Debido a que el programa mail envía el mensaje antes de devolver el control al shell, y el shell verifica si hay correo nuevo, el mensaje "Tienes correo". aparece en el video. Esta situación ocurre después de que el programa de correo ha terminado de ejecutarse, pero antes de que el shell muestre la solicitud de otro comando. El sistema UNIX a menudo proporciona servicios de este tipo, por lo que ocasionalmente puede leer en video algunos mensajes enviados por el shell o por otros programas que se ejecutan simultáneamente en el sistema. Dado que UNIX es un si stema multitarea, no es de extrañar que haya otros procesos ejecutándose además de su sesión. El sistema UNIX tiene muchas herramientas eficientes (los Capítulos 14 y 15 describen sus características) para la comunicación entre usuarios y entre diferentes máquinas. 2.9 Lista de usuarios activos En un sistema multiusuario es posible que otras personas además de usted estén utilizando el sistema desde diferentes terminales conectados a la máquina. Normalmente no notas la presencia de estos usuarios porque el sistema te pone en posición de pensar que eres el único que está usando la máquina. Sin embargo, existe la posibilidad de saber quién además de usted está en el sistema y tener una idea de lo que están haciendo. Otra característica típica del sistema UNIX es que los usuarios de una máquina constituyen un grupo de personas que tienen intereses comunes, como por ejemplo, la comunicación y el intercambio de archivos. Por lo tanto, en UNIX existe un delicado contraste entre la libertad de recorrer el sistema otorgada a los usuarios y las restricciones dictadas por consideraciones de seguridad. El sistema proporciona herramientas eficientes para definir el estado de seguridad de los identificadores de usuario, archivos y programas de uso común y archivos privados. (El Capítulo 22 trata este tema con más detalle). Puede averiguar quién está usando el sistema con el comando who: $quien Ingrese el nombre del comando, como de costumbre después del indicador de shell, seguido de RETURN. $quien León Jorge ps consola ttyOOs Abr Abr 7 14:05 7 16:41 El resultado del comando who aparece en la pantalla y el control vuelve al shell. A continuación, se muestra la lista de usuarios presentes en el sistema: leo y giorgio (es decir, usted) en este caso. Hay más información disponible sobre el tipo de terminal utilizado: usted está operando con el terminal remoto ttyOOs, mientras que leo está utilizando la consola del sistema que está directamente conectada a la computadora. El resto de cada línea indica la fecha y la hora en que el usuario inició sesión en el sistema: George inició sesión a las 4:41 p. m., hora local. En un sistema UNIX grande puede haber más de cien usuarios asignados a la vez, mientras que en máquinas más pequeñas puede haber solo uno. No importa; en cualquier caso, el sistema permite al usuario pensar que es el único usuario de la máquina. 2.1 O Cambiar su contraseña Antes de cerrar la sesión, al salir del sistema, puede cambiar su contraseña. El identificador de usuario y la contraseña son la clave de seguridad en el sistema UNIX. Si alguien llega a conocerlos, pueden ingresar a su sistema con un grave riesgo para sus archivos. Además, puede cambiar su contraseña, impidiéndole iniciar sesión en el sistema hasta que el administrador restablezca la situación original. Por lo tanto, mantenga su contraseña en secreto y cámbiela con frecuencia. Por supuesto, su identificador debe ser conocido por otros usuarios si desea recibir correo, pero la contraseña es personal y no debe ser comunicada por ningún motivo. Si eres un nuevo usuario de la máquina, es arriesgado esperar a que el administrador del sistema te designe un identificador y una contraseña de valores preasignados. Esto es, de hecho, una posible brecha de seguridad. za porque la mayoría de los administradores de sistemas utilizan la regla simple para definir contraseñas para nuevos usuarios para derivarla del identificador o alguna otra palabra simple que sea fácil de descubrir, por lo que es recomendable que elija rápidamente su propia contraseña privada. Si el administrador de su sistema le dio un identificador de usuario pero no una contraseña, probablemente no verá la contraseña: mensaje en la pantalla, pero puede iniciar sesión directamente en el sistema a través del inicio de sesión: mensaje. En cualquier caso, defina rápidamente una contraseña. Nadie puede descifrar tu contraseña porque se cifra instantáneamente, por lo que si la olvidas, nadie puede ayudarte a recordarla. La única ayuda que puede brindarle el administrador del sistema es eliminar la contraseña anterior y asignarle una nueva. Así que tenga cuidado de no olvidar su contraseña, adoptando métodos inteligentes para recordarla. Es conveniente elegir un término para la contraseña que sea fácil de recordar para usted, pero difícil de descifrar para los demás. El sistema generalmente requiere que la contraseña no tenga menos de seis caracteres y contenga al menos un dígito u otro carácter no alfabético. Estas reglas, que se derivan de consideraciones de seguridad, permiten componer una gran cantidad de contraseñas, lo que hace extremadamente imposible que personas no autorizadas las identifiquen. Una vez que haya elegido la nueva contraseña, puede informar al sistema mediante el comando passwd. Tenga en cuenta la ortografía particular del nombre de este comando. $contraseña passwd: Cambio de contraseña para george Contraseña anterior: El sistema no le permite cambiar su contraseña fácilmente. Primero debe ingresar la contraseña actual (antigua), que no se muestra de todos modos, para convencer al programa passwd de que está autorizado para cambiarla. Si comete un error tipográfico al ingresar la contraseña, el programa passwd sale y devuelve el control al shell, lo que le brinda una segunda oportunidad para cambiar. Cuando la contraseña finalmente se escribe correctamente, el comando passwd le solicita la nueva contraseña: $contraseña passwd: Cambio de contraseña para george Contraseña anterior: Nueva contraseña: Introduzca la nueva contraseña, que no se muestra. $contraseña passwd: Cambio de contraseña para george Contraseña anterior: Nueva contraseña: Re-ingrese nueva contraseña: Ahora el programa passwd le pide que ingrese la nueva contraseña por segunda vez, para verificar dos veces. Si las dos cadenas no coinciden, el comando passwd muestra el mensaje de error y le da la oportunidad de volver a intentarlo. $contraseña passwd: Cambio de contraseña para george Contraseña anterior: Nueva contraseña: Re-ingrese nueva contraseña: No coinciden; intentar otra vez. Nueva contraseña: No se han realizado cambios y puede ingresar su contraseña nuevamente. Si ahora presiona la tecla DEL, passwd finaliza la ejecución manteniendo la contraseña anterior. Si ingresa la misma contraseña dos veces, el sistema asume que la nueva contraseña es actual y devuelve el control al shell, que espera el siguiente comando. 2.11 Salir del sistema (cerrar sesión) Al final de la sesión de trabajo, debe completar el procedimiento de cierre de la entrevista. Una vez que cierra la sesión, UNIX libera el terminal y lo pone a disposición de otros usuarios, o para que usted lo reutilice, incluso con una ID de usuario diferente. Cerrar sesión en el sistema evita que personas no autorizadas utilicen su terminal, especialmente si el terminal se encuentra en un lugar público. Los dos factores más importantes que garantizan la seguridad del sistema UNIX son mantener seguras sus contraseñas y cerrar la sesión cada vez que abandone el terminal. Sin embargo, si la máquina está ubicada en una habitación a la que solo usted tiene acceso, estas medidas de seguridad son superfluas. El procedimiento de cierre de sesión difiere dependiendo de si su sesión se inició o no en el sistema X Window. Si está debajo de X, haga clic en el menú Área de trabajo y haga clic en Salir. Es posible que se le solicite que confirme la solicitud con una ventana temporal; si es así, haga clic en el botón Sí. Después de esto, el sistema X Window desaparece de la pantalla y puede cerrar la sesión del sistema o dejarlo en un shell normal. Introducir exit a una ventana xterm borrará la ventana del video (y del sistema); sin embargo, no borrará todo el entorno X y no se cerrará la sesión. Si está utilizando X, debe seleccionar Salir en el menú Área de trabajo para asegurarse de haber cerrado la sesión del sistema. UNIX define dos procedimientos diferentes para cerrar la sesión. El primero usa el comando exit: $salir Bienvenido al sistema AT&T 386 UNIX. Nombre del sistema: my_sys acceso: El sistema UNIX deja de ejecutar el shell, se reinicia y muestra el indicador de inicio de sesión inicial. Ahora puede apagar la terminal o iniciar sesión nuevamente. En lugar de usar el comando de salida, puede salir del sistema presionando CTRL-D, que representa el carácter de fin de archivo y que el shell interpreta como una señal de desasignación. El Capítulo 3 explica el significado del carácter de fin de archivo. Algunos sistemas UNIX hacen que el proceso de cierre de sesión sea inmediato si apaga el terminal o la consola. Los terminales que están conectados a la máquina a través de líneas telefónicas y módems suelen seguir este procedimiento. Sin embargo, si no está seguro del procedimiento adoptado por su sistema, salga explícitamente antes de colgar el teléfono o apagar el terminal. 2.12 Perspectivas En la terminal, para finalizar la línea de comando u otras líneas de texto, presione la tecla RETORNO. En la terminología de UNIX, un símbolo colocado al final de una línea de texto generalmente se denomina carácter de nueva línea. En este libro, el término nueva línea se puede usar para referirse a la clave de fin de línea. Por lo general, en las terminales, la tecla RETORNO actúa como nueva línea; en realidad, el carácter ASCII para el avance de línea es el carácter de avance de línea (LF). En la práctica, la tecla RETURN (CR + LF) tiene el mismo efecto que LF; Vea lo que le sucede a su terminal y sistema si finaliza una línea de texto con LF (cTRL-J) en lugar de RETURN. CONTROL DE SALIDA DE TERMINALES Ocasionalmente, puede encontrar que la salida de un comando consta de más líneas de las que su terminal (o su ventana xterm) puede ver; en este caso, la salida se desplazará fuera de la línea superior del video antes de que pueda leerlo. El sistema UNIX tiene dos herramientas para evitar esto controlando la salida. Un primer método usa el comando more filter que permite que la salida avance una pantalla a la vez; El Capítulo 7 analiza el comando more y su uso. Se puede emplear un segundo método cuando no haya anticipado la necesidad de usar el comando more; en este caso, puede escribir CTRL-s para detener inmediatamente la salida del video y CTRL-O para permitir que se reinicie exactamente donde lo dejó. Puede detener y reiniciar la salida tantas veces como sea necesario con este último método, pero debe tener cuidado de escribir CTRL-O al final, o su terminal aparecerá congelado. ==== Capítulo 3 Introducción al Shell 3.1 Los comandos en el sistema UNIX 3.2 La estructura de un comando 3.3 Ampliación de la línea de comandos 3.4 Variables de entorno 3.5 Protección de los argumentos de la línea de comandos 3,6 psi 3. 7 Entrada estándar y salida estándar 3.8 Carácter de fin de archivo 3.9 Redirigir la salida estándar a un archivo 3.10 Errores estándar 3.11 Combinación de comandos a través de pipeline 3.12 Filtros 3.13 Valores devueltos por comandos 3.14 El operador "acento grave" 3.15 Perspectivas El shell es el programa que espera los comandos ingresados ​​por la terminal, los recibe y los traduce en instrucciones en la sintaxis interna del sistema. El término shell en realidad indica la función que realiza, es decir, una función de pantalla o interfaz que se coloca entre la parte más interna del sistema operativo y el mundo externo. El shell realiza una gran cantidad de tareas, algunas de las más importantes y menos obvias de UNIX, y está sujeta a mejoras continuas. Muchas de las funciones que ofrece UNIX se derivan del shell, que por lo tanto puede considerarse una parte integral del sistema. En este capítulo examinamos algunas funciones de UNIX, centrándonos principalmente en las utilidades que ofrece el shell. 3.1 Los comandos en el sistema UNIX Los comandos suelen ser programas que el shell busca y ejecuta en respuesta a los comandos del teclado, como correo y quién. El shell es en realidad un medio más útil y orgánico que una simple interfaz entre el usuario y el sistema que ejecuta comandos. El shell lo ayuda a usar la máquina al ser, ante todo, un intérprete de comandos que puede expandir y modificar el comando (de acuerdo con reglas predefinidas) antes de ejecutarlo. Desde este punto de vista, los metacaracteres (comodines) y los operadores de conexión de comandos cobran especial importancia, ya que pueden generalizar y flexibilizar una línea de comandos. Por otra parte, los comandos pueden aprovechar las utilidades que el entorno de trabajo gestionado por el shell pone a su disposición para mejorar su ejecución. 3.2 La estructura de un comando La estructura de un comando generalmente incluye, además del nombre del comando, también algunos argumentos que representan los indicadores de modificación (opciones) del comando, precedidos por el signo - (menos), o nombres de archivo u otros identificadores de usuario. Los comandos toman esta forma: $pr -d notas El comando pr le permite imprimir archivos. La salida producida por un comando generalmente se envía a una terminal en lugar de a una impresora, por lo que pr es similar al comando cat. Mientras que cat, sin embargo, te permite concatenar archivos, pr se encarga de paginarlos y en columnas. En la sintaxis de comandos del sistema UNIX, las opciones siguen al nombre del comando y preceden a los argumentos principales. La línea de comando pr -d muestra el archivo de notas en el terminal a doble espacio. El argumento principal del comando es el nombre del archivo, mientras que la opción (-d en este caso, que indica doble espacio) tiene la función de modificar la función básica del comando. Sin embargo, para la mayoría de los comandos, no es necesario especificar ni la opción ni el nombre del archivo como argumentos. Se puede agregar una segunda opción al comando pr: $pr -n -d notas En este caso, pr imprime a doble espacio (-d) incluyendo la numeración de línea (-n). Recuerde que las opciones siempre preceden al nombre del archivo en la lista de argumentos de un comando. Una silueta equivalente al comando anterior puede ser el siguiente: $pr -nd notas Puede combinar opciones y precederlas con una sola El ejemplo que presentamos genera una lista a doble espacio en la terminal, con la numeración de línea consecutiva "l, 2, 3, 4, ... ". Puede usar el mismo comando para producir una salida de línea impar: "l , 3, 5, 7, ... ". $pr -n2 -d notas La opción -n del comando pr puede tener su propio argumento, que indica el intervalo entre un número de línea y el siguiente, por lo que pr - n2 cuenta líneas por dos en lugar de por una. También puede utilizar una de las siguientes formas alternativas: $pr -n2 -d notas $pr - d - n2 notas $pr - d - n 2 notas $pr - d $pr - notas dn2 - 2 notas Todas son formas equivalentes del mismo comando, ya que el sistema no considera el orden en que se escriben las opciones, ni requiere que cada opción esté precedida por el signo, o que haya espacios adicionales entre las opciones. Las siguientes líneas de comando, sin embargo, no son lo que desea: $pr - n2 - d notas $pr - notas nd2 $pr notas - na2 Debe preceder directamente la opción con el signo -, sin insertar espacios, y preceder las opciones (si existen) con los nombres de archivo. Además, debe asegurarse de que el argumento que modifica una opción, como el número 2 en nuestro caso, siga a la opción que modifica. Generalmente, cuando comete un error, el comando responde con un mensaje que lo lleva de regreso al forma correcta, aunque a veces el mensaje sea incomprensible y el comando no cumpla correctamente su función, aunque no genere consecuencias desagradables. Puede agregar un segundo nombre de archivo al comando pr $pr notas TRY La lista de nombres de archivo, separados por espacios o caracteres de tabulación, aparece en la misma línea de comando. Se debe insertar al menos un espacio para separar los argumentos. En el siguiente ejemplo: $pr - de notas TEST $gato notas $pr -d -I 2 INTENTAR la primera línea de comando tiene tres argumentos, la segunda. Los argumentos se numeran a partir del nombre del comando, pr en este caso, que se toma como argumento cero; - di representa el primer argumento y los nombres de los dos archivos constituyen el segundo y tercer argumento, respectivamente. La tercera línea del ejemplo presenta el comando pr con cuatro argumentos, aunque el número 2 está asociado con la opción -1. Los argumentos están separados por espacios, por lo que el comando: $pr -d -I 2 INTENTAR corresponde a una línea de comando pr con cuatro argumentos, dos de los cuales son opciones, uno está asociado con una opción y el último es un nombre de archivo. Muchos comandos tienen varios nombres de archivo como argumentos. Compare las diferencias entre la salida producida por el comando $pr notas TRY y la salida generada por el siguiente comando: $ gato notas PROBAR Las diferencias existentes se deben a las diferentes funciones que realizan los dos comandos. El comando cat se usa para concatenar varios archivos, de modo que los dos archivos se fusionen en uno solo en la salida, mientras que pr se ocupa principalmente del diseño de los archivos y actúa sobre los dos archivos en sucesión. 3.3 Ampliación de la línea de comandos El shell facilita la especificación de nombres de archivo como argumentos para un comando. Tres caracteres especiales, llamados comodines, pueden reemplazar todo o parte de los nombres de archivo. En el directorio que contiene las notas y los archivos TEST, el comando $gato * equivalente a notas de gato TRY. En otras palabras, el carácter * (asterisco) hace que el shell haga referencia a todos los archivos del directorio actual. El shell en realidad examina los archivos, reconstruye la línea de comando reemplazando los metacaracteres con los nombres de archivo completos y luego ejecuta el comando. El metacarácter * también se puede colocar dentro de un nombre de archivo. Por ejemplo, $gato PR * muestra todos los archivos que comienzan con PR, mientras que $gato *ANUNCIO* muestra todos los archivos que contienen AD en ellos. A diferencia de lo que sucede en MS-DOS, donde el metacarácter * solo puede reemplazar el nombre o la extensión del archivo, en el entorno de shell reemplaza cualquier secuencia de caracteres que esté presente en el comando. El segundo metacarácter es ? (signo de interrogación) que puede reemplazar cualquier carácter que aparezca en la posición correspondiente del nombre del archivo. Por ejemplo, $gato ?ENCONTRAR muestra el contenido del archivo TEST, similar al siguiente comando: $ gato ?R?VA Por el contrario, el comando $cat P?VA no puede encontrar el archivo en el directorio porque el comodín? es capaz de reemplazar sólo un carácter en el nombre del archivo. El tercer metacarácter le permite especificar una lista de caracteres que pueden reemplazar un carácter en el nombre del archivo, como el operador?, limitando el reemplazo a un conjunto seleccionado de caracteres. Los caracteres de paréntesis izquierdo y derecho ([ ]) pueden encerrar una lista de caracteres que pueden aparecer en la posición correspondiente en el nombre del archivo, por ejemplo: $cat PROV[AEO] Esto mostraría los archivos TEST, TEST, PROVO, si existen. Los corchetes actúan como el metacarácter ? en un solo carácter en la posición correspondiente; múltiples caracteres pueden coincidir con múltiples operadores de corchetes, por ejemplo: $ gato [PpTt][Rr)OV[AEO] También puede usar estos comodines en el mismo comando. Por ejemplo, $ls ??O* muestra los nombres de todos los archivos que tienen la letra O como tercer carácter. El ejemplo anterior le permite encontrar un archivo llamado PRO. En realidad, el comodín * hace que el shell reemplace todas las cadenas de cero o más caracteres. Por otro lado, el metapersonaje? reemplaza un carácter en el nombre del archivo. Por ejemplo, el comando $ls PROBAR? no puede encontrar el archivo PRUEBA, a diferencia del comando $ls INTENTAR* De manera similar, los corchetes requieren que un carácter ubicado en la posición equivalente del nombre del archivo coincida con uno de los caracteres de la lista; si no se encuentra ningún archivo con uno de los caracteres de la lista en esa posición del nombre, entonces no se expande ningún nombre de archivo en la línea de comando. 3.4 Variables de entorno El shell le permite definir las llamadas variables de entorno, es decir, cadenas de caracteres que toman el formato nombre=valor, donde nombre es cualquier secuencia de caracteres que no incluye el signo $(dólar) y no contiene espacios, mientras que valor es cualquiera seguido número de caracteres, incluidos los espacios. Muchas variables de entorno suelen estar asociadas con identificadores de usuario y varían según su sistema, el software disponible y sus necesidades. Puede inicializar una variable de entorno especificando nombre=valor en el shell: $ EJEMPLO = "hola amigos" El shell reconoce esta declaración, la interpreta como la definición de una variable de entorno y almacena su nombre y valor. Adoptamos la convención de nombrar las variables de entorno en mayúsculas, aunque no es obligatorio. Inmediatamente después del nombre, agregue el signo = (igual) sin insertar espacios, y luego el valor que necesita. Debe colocar comillas alrededor de la parte del valor de la asignación que se muestra en el ejemplo porque contiene un carácter de espacio. Volveremos sobre este concepto más adelante. Antes de usarlo, no necesita definir o declarar el nombre de la variable de entorno. El shell comprueba si ese nombre ya se ha utilizado y, en caso afirmativo, cambia el valor de la variable. Si el nombre nunca se ha utilizado, el shell lo asocia con la variable. Cuando desee obtener el valor de una variable de entorno, anteponga al nombre un signo de $ (dólar). Esta convención hace que el shell reconozca la siguiente cadena como una variable y calcule su valor; de lo contrario, el shell interpreta la cadena como una simple secuencia de caracteres. · Con el comando echo puedes mostrar el valor de una variable de entorno. $ echo $EJEMPLO El siguiente comando hace que el shell escriba el valor de la variable en el terminal. $ echo $EJEMPLO Hola gente ps Imagina lo que sucede si ingresas el siguiente comando desde el teclado: $ echo EJEMPLO Las variables de entorno pueden reemplazar los nombres de los comandos o sus argumentos. Por ejemplo: $XYZ="notas de gato" $$XYZ Hola George, bienvenido al sistema. Te esperamos para que nos enseñes a sacar el máximo partido al sistema UNIX. palmadita ps Antes de ejecutar el comando, el shell sustituye el valor asociado con el nombre de la variable en él. Puede usar este mecanismo para asignar comandos largos y de uso frecuente a una variable de entorno de longitud corta; al hacerlo, puede ingresar desde el teclado solo la variable de entorno (¡precedida de $ para que sea interpretada por el shell!) y el shell ejecuta el valor asociado. Puede usar el comando echo para mostrar cadenas de caracteres en la terminal. $ echo hola $EJEMPLO amigos hola hola gente gente ps También puede incrustar la variable de shell dentro de otra cadena de caracteres. $ echo hola$[EJEMPLO]amigos hola hola amigos ps Dado que el shell no sabe si se refiere a la variable $EXAMPLE oa la variable $EXAMPLEpeople, debe proteger la cadena EJEMPLO cuando no esté delimitada por espacios. Las llaves hacen esto cuando siguen inmediatamente al signo $. El shell generalmente ignora las variables no definidas. Piensa en lo que puede pasar si ingresas la siguiente línea de comando desde el teclado: $ echo hola$EJEMPLO amigos Siempre hay de 10 a 30 variables de entorno que están permanentemente asociadas con los identificadores de usuario. El sistema suele asignarlos cuando inicias sesión y permanecen hasta que cierras sesión. El shell utiliza algunas de estas variables permanentes, mientras que otros pueden ser utilizados por algunos paquetes de software de aplicación para satisfacer sus necesidades. Para verificar qué variables de entorno están asignadas actualmente, use el siguiente comando: $env El comando env muestra una lista completa, cuyos elementos tienen la forma nombre=valor. $env LOGDIR = /inicio/jorge INICIO = /inicio/jorge SHELL = /usr/bin/ksh CORREO= /var/correo/john EDITORES = /usr/bin/vi NOMBRE DE REGISTRO = jorge TÉRMINO=xtérmino RUTA = :/home/george/lib:/sbin:/usr/sbin:/usr/bin:/usr/X/bin:/usr/ucb TZ=MSTSMDT ps Puede tener muchas más variables de entorno que en el ejemplo anterior. Puede agregar o cambiar las variables de entorno a su gusto, pero tenga cuidado de no cambiar el valor de las variables de entorno existentes porque puede haber algún comando o aplicación usándolas. Antes de elegir un nombre de variable de entorno, compruebe si ya se ha definido antes. Si intenta mostrar el valor de una variable de entorno que no existe, el shell no muestra nada. $ eco $ AUSENTE ps El comando echo en este caso confirma que puede usar la variable de entorno para sus necesidades. 3.5 Protección de los argumentos de la línea de comandos El shell interpreta una cadena de caracteres que contiene espacios como el conjunto de múltiples argumentos porque el carácter de espacio asume el papel de separador. Consideremos el siguiente ejemplo: $ EJEMPLO = hola amigos amigos: no encontrado ps El mensaje de error que sigue a la asignación de la va Entorno reable EJEMPLO aparece en la pantalla porque el shell interpreta la cadena hola amigos como dos argumentos separados. Dado que el par nombre=valor de la variable de shell requiere que el valor sea un único argumento, el shell le asigna el valor salve. Luego, el shell intenta interpretar el siguiente argumento, amigos, como un comando para ejecutar; sin embargo, dado que no hay un comando llamado amigos, el shell infiere que el comando no es referenciable. Para solucionar esto, debe incluir el valor entre comillas. Por ejemplo: $ EJEMPLO = "hola amigos" $ echo $EJEMPLO Hola gente ps Una vez que haya citado la cadena, el shell la interpreta como el único argumento. Puede repetir este proceso para cada argumento en la línea de comando. Las comillas delimitadoras también pueden contener variables de entorno que el shell interpreta correctamente. $ EJEMPLO = "Mi ID de usuario es $LOGNAME" $ echo $EJEMPLO Mi ID de usuario es Jorge ps También puede evitar que el shell evalúe las variables de entorno, incluso si incluye sus nombres en la línea de comandos. Por ejemplo: $ EXAMPLE= 'Usar $LOGNAME para determinar mi ID de usuario' $ echo $EJEMPLO Usar $LOGNAME para determinar mi ID de usuario ps También puede delimitar los argumentos de la línea de comandos con una comilla si tiene comillas dentro de ellos: $ echo "'hola amigos'" "Hola gente" ps En este ejemplo, las comillas ya no son operadores de shell porque están protegidas por comillas, pero son parte de la cadena de caracteres que desea mostrar. 3.6 PS1 El shell usa algunas variables que no están incluidas en la lista producida por el comando env. Uno de ellos, PS1 (símbolo de indicador, nivel uno), representa el valor del indicador de shell, que hasta ahora se ha identificado con el símbolo $ (dólar). Puede verificar su valor con el comando echo. $eco $PS1 ps ps En este ejemplo, el comando echo mostró el valor de solicitud; luego, el shell lo imprimió para advertir que está esperando el siguiente comando. Puede cambiar el valor de PS 1 como lo haría con cualquier otra variable de shell. $PS1 = "hola: " Hola: Ahora el indicador de shell ya no es $, sino el valor que le asignó, es decir, hola: en este caso, pero cualquier carácter en general. Las variables de shell se evalúan cuando se ingresan desde el teclado, no cuando se ejecutan. Por ejemplo: $EJEMPLO="Ingrese el comando:" $PS1 =$EJEMPLO Ingrese el comando: EJEMPLO = hola Ingrese el comando: echo $EJEMPLO Hola Introduzca el comando: PS1 se inicializó a $EXAMPLE, pero cuando cambia $EXAMPLE nuevamente, $PSI no cambia. El comando para inicializar PS1 a $EJEMPLO se evaluó cuando a $EJEMPLO se le asignó el valor Insertar comando:, por lo que este se convierte en el nuevo valor de PS1, no en el valor de $EJEMPLO cuando se muestra $PSI. 3. 7 Entrada estándar y salida estándar Hasta ahora ha ingresado comandos escribiéndolos en el teclado y los resultados producidos se han mostrado en la pantalla. Los comandos generalmente reciben datos de entrada que, una vez procesados, producen una secuencia de caracteres de salida. Estas secuencias de caracteres de entrada y salida son comparables a los flujos de datos en el sentido de que no tienen una estructura interna bien definida. Por lo tanto, el comando recibe una larga secuencia de caracteres como entrada, incluso si algunos de ellos (¡como el shell!) actúan sobre secuencias de caracteres que terminan en LF (ASCII I O o avance de línea o nueva línea como se menciona a menudo en los manuales UNIX). El archivo de entrada de un comando se denomina entrada estándar, mientras que el archivo de salida se denomina salida estándar. Por ejemplo, el comando: $eco $PS1 escribe en la salida estándar. El shell generalmente se organiza para que la entrada estándar de un comando provenga del teclado, mientras que la salida estándar se envía a la pantalla. Sin embargo, es posible redirigir la entrada estándar y la salida estándar a otros archivos. Por ejemplo: $ notas de gato > copiar no ps El carácter > (mayor que) hace que el shell redirija la salida estándar a un archivo llamado o.copy en nuestro ejemplo. El shell crea el archivo si no existe, o lo elimina si ya existe, antes de informar los resultados de la ejecución del comando. De esta manera, puede destruir fácilmente un archivo existente, así que vuelva a verificar antes de redirigir la salida. También puede redirigir la entrada, usando el símbolo < (menor que), para que los datos provengan de un archivo en lugar de la terminal. $ correo leo < notas ps En este ejemplo, el contenido del archivo de notas representa la entrada del comando mail leo, por lo que Leo encuentra el archivo en su buzón. Obtienes el mismo efecto si mpre con el comando mail leo, pero ingresando el contenido de las notas del archivo desde el teclado. Puede combinar operaciones de redirección de entrada estándar y salida estándar. Por ejemplo: $ pr n.copia ps En este ejemplo, el shell ejecuta el comando pr que recibe el archivo de notas como entrada y almacena la salida en el archivo o.copy. El shell requiere que el nombre del comando preceda a los operadores de redirección. Puede escribir cualquiera de los siguientes comandos: $ pr > n.copy < notas $ pr >copia # n.copia $ pr >copias pr < notas no es correcto. Es una buena idea separar los operadores de redirección del nombre del comando y los argumentos con espacios, pero no es necesario. La línea de comandos también puede contener variables de entorno. $ EJEMPLO= notas $ pr < $EJEMPLO> copiar n ps El concepto de redirección de entrada/salida (E/S) tiene implicaciones muy importantes y es uno de los aspectos más generales y útiles de UNIX. La mayoría de los comandos ingresan y emiten secuencias simples de bytes que se pueden enrutar fácilmente desde un dispositivo a un archivo, a un dispositivo de almacenamiento. Algunos comandos le permiten especificar nombres de archivo directamente como argumentos en lugar de requerir que redirija la entrada estándar de un archivo al comando. Esta es una característica del comando y no está definida por el sistema operativo o el shell, por lo que no siempre se sigue. Por ejemplo, los dos comandos: $gato < notas $gato notas son equivalentes, ya que el comando cat opera en un archivo o en su entrada estándar. Como muchos otros comandos, cat le permite especificar archivos y entradas estándar en su línea de comando. Las siguientes formas también son equivalentes: $ gato notas PRUEBA copia n $ gato nota - copia # < PRUEBA Si especifica solo el signo - (menos) como argumento y no le sigue ninguna opción, el comando lo interpreta como su entrada estándar. En el segundo ejemplo anterior, el comando cat analiza el archivo de notas, examina la entrada estándar que se redirigió desde el archivo TEST y luego procesa el número de copia del archivo. Del mismo modo, el comando $ notas de gato - copia # > salida examine el archivo de notas, espere la entrada del teclado y luego procese la copia del archivo #. Dado que no ha redirigido la entrada estándar, el shell aún la considera vinculada al teclado. 3.8 Carácter de fin de archivo Si está utilizando el teclado como entrada estándar, debe informar a comandos como cat que está ingresando caracteres y luego que ha terminado de escribir. UNIX define un carácter especial que se utiliza como carácter de fin de archivo y ocupa la primera posición de la línea. Este carácter no se almacena en disco al final del archivo porque el sistema es capaz de distinguirlo automáticamente. Sin embargo, cuando usas el teclado como archivo, el sistema no sabe cuando has terminado la operación de ingreso de datos y por lo tanto debes especificarlo expresamente usando la combinación de teclas CTRL-D. Para generar este carácter, mantenga presionada la tecla CTRL en su teclado y escriba la tecla D. En la línea de comando $ notas de gato - copia # > salida cat procesa el archivo de notas, espera la entrada del terminal y lee los datos que ingresa hasta que presiona CTRL-D y luego procesa la copia del archivo #. Los tres archivos de origen se concatenan en el archivo de salida. 3.9 Redirigir la salida estándar a un archivo El operador > le permite deshacer y volver a crear un archivo existente, sin embargo, pierde el contenido anterior. También es posible, de varias formas, concatenar el resultado producido por un comando al final de un archivo ya existente. La secuencia de comandos $ pr n.copia $ nota de gato copia # > dup.note $ rm copia no ps genera el archivo dup.note, que contiene tanto el archivo de notas como el producido por el comando pr. Otra forma de lograr el mismo resultado es usar el operador > >, que hace que el shell redirija la salida estándar a un archivo, agregándolo al final del archivo. Esta secuencia de comandos: $cat nota > dup.nota $pr nota > > dup.nota ps produce el mismo resultado que el ejemplo anterior, pero usando un comando menos. Si el archivo que aparece a la derecha del operador > > no está presente en el sistema, se crea automáticamente. Tenga en cuenta que el operador > > no puede contener espacios entre los caracteres > y que no existe un operador < < equivalente para la entrada estándar. 3.10 Errores estándar Hablamos de entrada estándar y salida estándar, pero el sistema define otro archivo que comúnmente se denomina error estándar. La mayoría de los comandos utilizan el archivo de errores estándar para mostrar mensajes de error u otros resultados anómalos que no deberían aparecer en la salida estándar. De hecho, no es recomendable que los mensajes de error aparezcan junto con los resultados y, por lo tanto, el sistema los reporta en forma fidedigna. los distinguió. Si escribe intencionalmente un comando incorrecto, analice el contenido del error estándar. Por ejemplo, si intenta utilizar el comando cat en un archivo que no existe, el sistema genera un mensaje de error. $ archivo n° cat. gato: no se puede abrir no.file ps Si ahora redirige la salida estándar del comando cat, $ cat no.archivo > salida gato: no se puede abrir no.file ps el archivo de salida está vacío y el mensaje de error aún aparece en el terminal, porque está escrito en error estándar. Puede redirigir el error estándar utilizando el operador 2 > o 2 > >, si tiene la intención de crear un nuevo archivo o agregar datos a un archivo existente, respectivamente: $cat no.archivo 2 > salida salida $cat gato: no se puede abrir no.file ps Hemos utilizado la notación 2 > para hacer referencia a los canales de E/S a los que se asignan identificadores numéricos precisos: O se refiere de hecho a la entrada estándar, 1 a la salida estándar y 2 al error estándar. Estos identificadores numéricos son principalmente responsabilidad de los diseñadores de software, incluso si en nuestro ejemplo permiten el acceso al shell a nivel de usuario. 3.11 Combinación de comandos a través de pipeline Es posible que los datos de salida producidos por un comando se utilicen como datos de entrada para otro comando. Por ejemplo, es legítimo escribir: $ gato notas TRY > temp salida $pr $rm temperatura ps Si no desea crear archivos intermedios, la salida del comando cat se puede canalizar directamente a la entrada del comando pr. Incluso si la secuencia de comandos indicada en el ejemplo anterior hace su trabajo correctamente, el shell propone una solución más elegante y eficiente a través del operador de tubería: . Una línea de comando que contiene este operador se denomina canalización y el shell interpreta automáticamente el paso de un flujo de datos de un comando a otro. Por ejemplo, la línea de comando $ gato nota TRY : pr > salida ps concatene las notas y los archivos TEST y use la salida estándar de cat como entrada estándar para el comando pr. La salida estándar de pr se dirige a la terminal, pero puede redirigirla a cualquier lugar escribiendo: $ gato nota TRY : pr > salida ps Hay otras líneas de comando que le permiten lograr la misma función. Para redirigir la entrada al comando cat, puede ingresar desde el teclado: $cat - TRY salida En este ejemplo tenemos dos comandos que están separados por el operador: cat - TRY < nota y pr > salida. La salida estándar del primer comando está conectada a la entrada estándar del segundo. La operación de redirección es local a la parte afectada de la canalización, por lo que el siguiente comando no es equivalente al anterior: $ cat - TRY : pr > salida < notas Por lo general, la entrada estándar se produce al comienzo de la canalización (leyendo de izquierda a derecha en la línea de comandos), mientras que la salida estándar aparece al final o en la segunda mitad de la canalización. En cualquier caso, siempre debe iniciar una línea de comando especificando el nombre de un comando entre los disponibles. La siguiente línea de comando es incorrecta: $nota > gato - PRUEBA: pr > salida Además, el operador : solo conecta comandos, por lo que debe usar los operadores > y < para indicar la redirección de archivos de datos. También es incorrecto escribir: $ nota : cat - TRY : pr > salida a menos que su sistema tenga un comando llamado notas. 3.12 Filtros El mecanismo de canalización no se limita a solo dos comandos. Puede definir canalizaciones de cualquier longitud conectando solo la salida estándar de un comando a la entrada estándar del siguiente. UNIX tiene muchos comandos que funcionan así. Se denominan filtros, ya que toman datos de entrada, realizan operaciones de filtrado establecidas por el programa en particular y generan un resultado. El programa tr (traducir) es un ejemplo clásico de un filtro. Recibe dos argumentos de entrada, que interpreta como conjuntos de caracteres (no cadenas de caracteres); copia su entrada estándar a la salida estándar y reemplaza cada elemento del conjunto de caracteres que constituye el primer argumento con el elemento que ocupa la misma posición en el conjunto de caracteres que constituye el segundo argumento. $ echo "hola amigos" : tr a 3 Hola gente ps El comando tr se diferencia de los comandos habituales en que no requiere un nombre de archivo como entrada, sino que solo lee la entrada estándar. Una optimización del comando es la siguiente: $ echo "hola amigos" : tr ae 34 s31v4 g4nt4 ps CAMPOS Y DELIMITADORES Uno de los comandos que más se utiliza como filtro es cut. Este comando permite copiar algunas partes de las líneas de su entrada estándar a la salida estándar. Un campo de una línea es una cadena de caracteres separados por un delimitador prefijado. UNIX utiliza varios delimitadores de campo según corresponda, aunque los tres más comunes son los caracteres de tabulación, espacio y dos puntos. La notación t se usa para indicar el carácter de tabulación dentro de un texto, mientras que para crearlo tienes que presionar la tecla TAB en el teclado. La idea de dividir una línea de un archivo en campos se parece a la forma en que se numeran los argumentos de la línea de comandos del shell, incluso si en ese caso se usó el carácter de espacio como delimitador. En muchas otras circunstancias, el carácter : (dos puntos) se usa como delimitador. El comando de corte se usa para copiar solo algunos campos de una línea de entrada a la salida. Al crear una línea de comando para cortar, debe especificar qué campos copiar en la salida estándar y qué carácter usar como delimitador de campo de las líneas en la entrada estándar. Considere el siguiente archivo como un conjunto de registros de datos, cada uno de los cuales representa una línea: $cutdatafile 123:543:654:234 987:753: 123:765 435:765: 135:963 ps Cada registro en este ejemplo consta de cuatro campos que están separados por el delimitador: y el final de la línea delimita cada registro. Si debe usar el carácter: dentro de un campo, elija otro carácter como delimitador, teniendo mucho cuidado de que no aparezca ya en los datos. Puede utilizar el comando de corte para ver una parte de los datos almacenados en esta sencilla base de datos. Por ejemplo, para mostrar solo el segundo campo de cada línea, ingrese la siguiente línea de comando: $corte - f2 - d: dir1/ Nota El nombre del archivo aparece en el extremo derecho y cada directorio tiene una línea saliente asociada. La parte de la línea que precede al nombre del archivo, como 5 de abril a las 19:34, representa la fecha y la hora en que modificó el archivo por última vez. La marca de tiempo generalmente se usa cuando compara archivos o desea averiguar la fecha de escritura. La columna inmediatamente a la izquierda, que contiene 138 o 227, indica el tamaño del archivo en bytes, que va desde cero, para archivos recién creados, hasta uno o más megabytes. El sistema define la variable especial ulimit para controlar el tamaño máximo que puede tener un archivo; a menudo esta variable tiene un valor de dos megabytes. Recuerda que un directorio también es un archivo, por lo que tiene un tamaño en bytes poco utilizado. Si el objeto enumerado es un enlace simbólico, como link.dir en el ejemplo anterior, el campo de nombre más a la derecha muestra la forma particular -> (puntero a) ; el nombre del enlace simbólico aparece primero y apunta a un segundo nombre que es el objeto real. PROPIEDAD DE LOS ARCHIVOS Dado que UNIX es un sistema multiusuario, cada usuario puede crear sus propios archivos, a los que hace referencia hasta que los elimina o los pasa a otros usuarios, y se coloca en un grupo donde puede compartir archivos con otros miembros de su grupo, pero no con usuarios que pertenecen a otros grupos. El Capítulo 22 analiza los grupos en detalle. Con el comando ls -1 puede verificar qué usuario y qué grupo posee un determinado archivo: george es el propietario del archivo y usuarios es el nombre del grupo al que pertenece george. Cuando creas un archivo, el sistema lo asigna al grupo al que perteneces. Sin embargo, puede cambiar la asignación de grupo o usuario de un archivo, por lo que el usuario que aparece en la salida del comando ls -I puede no pertenecer al grupo indicado. La columna más a la izquierda en la salida de ls -1 contiene un número de un solo dígito, que representa el número de referencias que tiene el archivo. Cuando usa In para crear otro nombre de archivo, el número aumenta en uno; cuando elimina un nombre de archivo con rm, el número disminuye en uno y cuando llega a cero, el archivo se elimina. INTERPRETACIÓN DEL PERMISO DE ARCHIVO La columna más a la izquierda de la línea de salida, escriba - rw - rw - rw - , indica los permisos o derechos de acceso o las formas de usar el archivo. La posición más a la izquierda de la salida es - (guión) si es un archivo normal, d si es un directorio, 1 (elle) si es un enlace simbólico; si aparece una b o una en esa posición y es un archivo especial, usado para controlar E/S con dispositivos periféricos. Las siguientes tres posiciones en la línea de salida indican los derechos de acceso para quien tenga que hacer referencia al archivo; los otros tres que siguen indican los derechos de acceso para el grupo que usa el archivo, mientras que los últimos tres representan los derechos de acceso para todos los demás usuarios del sistema. Cada uno de estos tres grupos se divide en tres partes: acceso de lectura de archivos, acceso de escritura y acceso de ejecución. El acceso de lectura define si el propietario, el grupo o todos los demás usuarios pueden leer el archivo, por ejemplo, con cat. El acceso de escritura determina quién está autorizado para escribir en el archivo, ya sea a través del editor o redirigiendo la salida a él. El acceso de ejecución determina quién puede ejecutar el archivo como un comando, es decir, haciendo referencia a él por su nombre, como por ejemplo ls o rm. En el caso de los directorios, los significados de estos tres grupos de caracteres difieren ligeramente. El acceso de l ectura indica quién puede analizar el contenido de un directorio, por ejemplo, con ls; el acceso de escritura significa que el usuario puede crear un archivo en ese directorio, mientras que el acceso de ejecución significa que el usuario puede recorrer el directorio y profundizar en los subdirectorios. Los enlaces simbólicos tienen los permisos de los objetos a los que apuntan; los permisos de los enlaces en sí no tienen sentido. El comando ls -I muestra los derechos de acceso, especificando r para acceso de lectura, w para acceso de escritura y ex para acceso de ejecución. Por ejemplo, la secuencia de caracteres - rw - r - - - - - indica que el propietario del archivo puede leer y escribir en el archivo, las personas que pertenecen al mismo grupo que el propietario del archivo pueden leer pero no escribir en el archivo, mientras que otros usuarios no tienen acceso. La secuencia - r - - - - x - - x indica que el propietario del archivo puede leerlo, pero no escribirlo ni ejecutarlo, mientras que los miembros del mismo grupo que el propietario del archivo y todos los demás usuarios pueden ejecutar el archivo. , pero no lo lea ni nos escriba. LISTA DE PERMISOS DE DIRECTORIO Hay un cambio importante en el comando ls. Si escribe ls -1, la información relacionada con el archivo aparece en la pantalla, pero el mismo comando que se refiere a un directorio produce la lista de archivos presentes en ese directorio en la salida. $ls -I dir1 total 1 drwxrwxrwx -rw-rw-rw- -rw-rw-rw- ps 2 jorge 1 jorge 1 jorge usuarios usuarios usuarios 64 18 abr 12:43 dir2 O 17 abr 17:42 hola O 17 abr 17:42 hola Esta es la información más importante sobre el contenido de un directorio. Para obtener información sobre los derechos de acceso al directorio en sí, puede usar el comando cd para hacer referencia al directorio principal y ejecutar el comando ls -l, como hicimos en el ejemplo anterior para el directorio dir2. Para obtener información sobre el directorio dirl cuando se encuentra en el directorio preferido, haga lo siguiente: $ cd .. $ls-jorge El comando ls tiene una forma más eficiente de lograr los mismos resultados. tati, sin necesidad de cambiar de directorio. $ls -Id dir1 drwxrwxrwx 3 jorge usuarios 80 18 abr 12:43 dir1 ps Use ls -d (listado de directorios) para obtener el nombre de un directorio ectory en lugar de su contenido. Al agregar también la opción -1 a este comando, puede verificar el estado del directorio. CAMBIO DE PROPIEDAD DE LOS ARCHIVOS El sistema UNIX proporciona varios comandos que le permiten administrar la propiedad y los derechos de acceso a archivos y directorios. Si posee un archivo, puede dárselo a otro usuario con el comando chown (cambiar propietario). $ls -I notas - rw - rw - rw - 1 Jorge $ chown notas leo $ls -I notas -rw-rw-rw- 1 león usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas El comando chown recibe como argumentos un archivo o una lista de archivos y, como último argumento, el identificador de usuario al que se le quiere asignar el archivo, que ya debe estar definido en el sistema. Una vez que el archivo ha sido asignado a otro usuario, no puede usar el comando chown para recuperarlo. Utilice el comando chgrp para cambiar el grupo propietario de un archivo, si es propietario de ese archivo y pertenece a ese grupo: $ls -I notas -rw-rw-rw- 1 Jorge Papelera de notas $chgrp $ls -I notas -rw-rw-rw- 1 Jorge usuarios227 5 de abril 19:33 notas bin227 5 de abril 19:33 notas Además, cuando le ha dado el archivo a otra persona, ya no puede hacer referencia a él y, por lo tanto, recuperarlo. Por supuesto, si está autorizado para leer el archivo, puede hacer una copia con el comando: $ notas de gato > mis.notas o con un comando similar. Cuando crea un archivo, automáticamente se convierte en su propietario. CAMBIO DE PERMISO DE ARCHIVO Finalmente, puede cambiar los derechos de acceso de un archivo de su propiedad usando el comando chmod (modo de cambio). Un archivo puede tener tres categorías de derechos de acceso: usuario, grupo y otros, que se indican respectivamente mediante u (usuario), g (grupo) y o (otro) y que corresponden a las tres categorías que se enumeran mediante ls -1 dominio. Cada categoría de usuarios puede tener acceso de lectura, escritura o ejecución al archivo, y esta situación se indica respectivamente con los caracteres r, w y ex. Puede usar esta notación para definir un comando chmod: $ls -I notas - rw - rw - rw - 1 jorge usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas $chmod -w notas $ls -I notas - r - - r - - r - - 1 Jorge $chmod +w notas $ls -I notas - rw - rw - rw - 1 Jorge ps En el primer caso, especificamos el argumento -w para chmod, que elimina el derecho de acceso de escritura al archivo. El segundo ejemplo agrega el derecho de acceso de escritura al archivo nuevamente. El uso del carácter + (signo más) como bandera es una excepción al uso normal de - , pero puedes entender su significado: el signo - te permite quitar el derecho de acceso, mientras que el signo + lo restaura. Puede cambiar más de un derecho de acceso con el mismo comando, anteponiendo una o más letras al carácter - o +, por ejemplo: $ chmod -w+x notas $ls -I notas - r - xr - xr - x 1 jorge usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas $chmod -wx notas $ls -I notas - r - - r - - r - - 1 Jorge ps En todos estos ejemplos, chmod cambió el derecho de acceso para las tres clases de usuarios. También puede realizar cambios para cada clase individual agregando una letra antes del signo - o +. $ls -I notas - rw - rw - rw - 1 jorge $ chmod u - w notas $ls -I notas - r - - rw - rw - 1 Jorge $chmod go+ wx notas $ls -I notas -r--rwxrwx 1 jorge ps usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas usuarios227 5 de abril 19:33 notas La sintaxis del comando chmod consta de la clase de usuario (u, g o o), seguida de la acción a realizar (- o +), seguido del derecho de acceso para cambiar (r, w o x). La lista de nombres de archivo o directorios para cambiar completa la línea de comando. El comando chmod también puede tomar un argumento numérico que indica la clase de usuario y el derecho de acceso para cambiar como una secuencia de bits. $chmod 0466 notas Sin embargo, esta notación es más propensa a errores que las anteriores. El número 0466 está en notación octal. Además, el comando chmod puede asignar los valores s y t, así como r, w y x para acceder a los derechos. Los derechos de acceso s y t son utilizados por algunos programas ejecutables, pero no por usuarios individuales, para cambiar el entorno de ejecución y, en algunos sistemas, pueden verse como resultado del comando ls -1. 4.1 Perspectivas O Muchas de las características interesantes del sistema de archivos están asociadas con la ejecución de comandos, como los derechos de acceso. Algunas de estas funciones mejoran la relación entre el nombre de un archivo en un directorio y el almacenamiento físico real de los datos en el disco (u otros medios). El sistema le permite definir otros sistemas de archivos en cualquier ubicación dentro de la jerarquía de directorios. Incluso puede configurar el sistema para usar una red de área local para permitir que un archivo resida en un disco en otra máquina. Muchos de estos aproximadamente Las características están asociadas con la gestión y administración del sistema, conceptos que trataremos en los Capítulos 12, 23 y 24. ADMINISTRADOR DE ARCHIVOS DEL SISTEMA X WINDOW Si el sistema X Window está disponible en su sistema, puede usar el Administrador de archivos en lugar de las funciones de línea de comandos descritas en este capítulo. Para ver un ejemplo de la vista Administrador de archivos, vuelva a la Figura 2.1; el Administrador de archivos OPEN LOOK aparece en la parte inferior izquierda del video. Muchos paquetes X incluyen una aplicación como esta. Para obtener más información sobre la gestión de ventanas en X, consulte la primera parte del Capítulo 23. El Administrador de archivos le permite navegar por el sistema de archivos, seleccionar un subconjunto de archivos en un directorio para realizar una operación como copiar o eliminar y abrir subdirectorios. Los contenidos del directorio se muestran en el área inferior de la ventana del Administrador de archivos, la ruta absoluta necesaria para acceder a cada directorio aparece en una línea de componentes en el centro de la ventana; véase la figura 2.1. Aparece un icono junto al nombre de cada componente del contenido de un directorio, que hace referencia a la función o naturaleza del objeto: los directorios aparecen como carpetas de archivos, los archivos tienen una esquina doblada y los programas ejecutables muestran una ventana con bordes. También pueden aparecer muchos otros tipos de iconos. Con un clic del botón izquierdo del mouse en un objeto, el objeto se selecciona para realizar alguna acción que luego se puede seleccionar desde los menús en la ventana Administrador de archivos, arriba a la izquierda. Con un doble clic con el botón izquierdo del ratón sobre un objeto, ese objeto se abre. Si el objeto es un directorio (carpeta), el contenido del directorio reemplaza el contenido actual de la ventana y el directorio aparece en la lista en el centro de la ventana del Administrador de archivos; otros objetos provocan acciones diferentes. Aparecen nuevas ventanas si selecciona un procesador de texto o si inicia un programa. Cuando una aplicación finaliza o se cierra con la opción Salir del menú Ventana, la ventana de la aplicación desaparece. Alternativamente, para moverse por el sistema de archivos, en lugar de hacer doble clic en los iconos de las carpetas, puede escribir un nombre de ruta en la línea del directorio en la parte superior derecha y luego hacer clic en el elemento Coincidir en el menú para saltar a ese directorio. Puede seleccionar un subconjunto de archivos en el directorio seleccionado escribiendo un patrón de nombre de archivo comodín (operadores * ? []) en el cuadro Patrón y luego haciendo clic en Coincidir. Puede acceder a operaciones más complejas del sistema de archivos a través de los menús Archivo..., Ver..., Editar. Estos menús le permiten preestablecer el orden en que se muestran los archivos, examinar los permisos y otros atributos de los archivos y crear archivos y directorios. LOS COMANDOS basename Y dimame El sistema UNIX define algunos comandos para derivar nombres de archivos y directorios a partir de rutas completas y viceversa. Por ejemplo, puede tener una variable de entorno que contenga un nombre de ruta completo y solicitar saber solo el nombre de un archivo en particular. $echo $EDITOR /usr/bin/vi $MIEDICIÓN = 'nombre base $EDITOR' $ echo "Mi editor es $MYEDIT" mi editor es vi ps Utilice el comando basename para obtener el último componente de la ruta completa en la salida estándar, que generalmente indica el nombre de un archivo despojado de su directorio. El comando dirname, por el contrario, devuelve solo la parte del directorio, sin el nombre del archivo. $EDDIR = 'dirname $EDITOR' $ echo "Mi editor $MYEDIT está en el directorio $EDDIR" Mi editor vi está en el directorio /usr/bin ps Puede utilizar estas herramientas de gestión de rutas de acceso de muchas formas cuando hablemos de la programación de shell en el Capítulo 8. ARCHIVOS ESPECIALES (ARCHIVO DISPOSITIVO) Hemos cubierto archivos, enlaces simbólicos y directorios de uso común, pero el comando ls también destaca un tercer tipo de archivo, llamado archivo especial o simplemente dispositivo. El sistema UNIX proporciona una interfaz estándar entre los dispositivos y el sistema operativo que está estructurada como un archivo normal, de modo que las operaciones de E/S del hardware siguen reglas similares a las que se manejan al escribir un archivo. No es un archivo de disco como los que hemos mencionado, sino un nombre de ruta especial que hace referencia al canal de E/S del hardware. Al igual que con la redirección de E/S estándar a un archivo normal, puede redirigir fácilmente la salida a dispositivos de nivel de shell. Este es un tema de particular interés para aquellos que desarrollan y crean sistemas operativos y en este contexto solo se da una breve introducción. El comando tty (de Teletype Corporation, un teletipo que alguna vez se usó como terminal) devuelve el nombre de ruta asociado con su terminal. $tty /dev/ttyOOs ps Puede acceder a su terminal a través del archivo /dev/ttyOOs; la entrada estándar al shell, ch y está esperando sus comandos (shell de inicio de sesión) está vinculado a este archivo cuando inicia sesión en el sistema. Los nombres de las rutas de los dispositivos varían según el sistema y cambian a medida que se conecta al sistema desde diferentes terminales, así que use el comando tty si necesita determinar desde qué dispositivo se está conectando. El directorio /dev contiene muchos otros dispositivos (archivos de dispositivos) además de terminales. Puede usar este nombre de ruta como de costumbre dentro del sistema de archivos. $ls - I /dev/ttyOOs crw - rw - rw - 1 jorge usuarios 7, 2 19 de abril 13:21 /dev/ttyOOs ps El primer carácter de la línea de salida, e, indica que no se trata de un archivo o directorio normal, sino de un archivo de caracteres especiales, diseñado para transferir datos, carácter por carácter, como un terminal, un módem o una impresora. Otro tipo de archivo especial es el dispositivo de bloque, indicado con la letra b (bloque) en la primera posición, que permite transferir grandes cantidades de datos simultáneamente, como unidades de disco y algunos dispositivos de cinta. Puede utilizar esta unidad periférica como un sistema de archivos. Los archivos del dispositivo tienen derechos de acceso como todos los demás archivos y el usuario actual hace referencia a algunos. En el ejemplo que hemos discutido, puede leer y escribir en el archivo, lo que le permite recibir y transferir datos en su terminal, y otros usuarios pueden leer el archivo, es decir, seguir su sesión de trabajo si lo desean. Para hacer esto, ingrese la siguiente línea de comando: $gato - < /dev/ttyOOs Intente esto nuevamente en su terminal, escribiendo: $gato - < 'tty' Puede escribir algunos caracteres, luego presione la tecla SUPR para detener la ejecución del comando cat y devolver el terminal a la situación normal malo. Mira lo que sucede con esta otra versión del comando: $gato - > 'tty' EL MENSAJE DE COMANDO En el ejemplo anterior, podría leer y escribir directamente en un archivo de dispositivo que representa su terminal. Si los derechos de acceso enumerados por el comando ls - I 'tty' muestran que otros usuarios pueden leer y escribir en el archivo de su dispositivo, entonces pueden seguir su sesión o escribir directamente en su terminal redirigiendo E/S. Esta situación presenta un riesgo de seguridad potencial, ya que otros usuarios pueden interceptar su E/S. Sin embargo, el administrador del sistema, o el propio sistema a través del software, en ocasiones decide enviar un mensaje directamente a su terminal. Esto puede ocurrir cuando el sistema se apaga y el administrador quiere avisarte para que puedas guardar archivos y descolocarlos sin problemas. Los comandos wall (escribir para todos los usuarios) y write (escribir mensaje entre usuarios) utilizan la E/S directamente a su terminal para las comunicaciones. El Capítulo 14 analiza estos comandos extensamente. Puede controlar el acceso de otros usuarios a su terminal simplemente cambiando los derechos de acceso en el archivo de su dispositivo. Puede hacer esto directamente con el comando chmod, pero el sistema define explícitamente un comando para permitir o prohibir mensajes como este. Utilice el comando mesg (mensaje) para permitir o impedir que otros usuarios escriban o lean desde su terminal. Este comando toma un solo argumento, y o n para aceptar o rechazar mensajes, respectivamente. Por ejemplo: $ls - I /dev/ttyOOs crw-rw-rw- 1 Jorge $ mensaje no $ls - I /dev/ttyOOs crw-r- -r- - 1 jorge $mensaje $1s - I /dev/ttyOOs crw-rw-rw- 1 Jorge users7,2 20 de abril 18:37 /dev/ttyOOs users7,2 20 de abril 18:38 /dev/ttyOOs users7,2 20 de abril 18:37 /dev/ttyOOs ps El comando mesg en realidad cambia los derechos de acceso en el archivo de su dispositivo. OTROS ARCHIVOS ESPECIALES Además de los dispositivos tty externos, hay muchos otros archivos de dispositivos en el directorio /dev. Uno de los más interesantes es /dev/null, que representa un contenedor de tamaño infinito que se utilizará para redirigir los resultados que se eliminarán. Por ejemplo: $cat /etc/contraseña > /dev/null La salida del comando cat se cancela en este caso. Otro archivo de dispositivo de particular interés es /dev/kmem (memoria kernel), que es una representación de la memoria real presente en la máquina. Los programas especiales como los depuradores pueden leer /dev/kmem para verificar cómo el sistema está usando la memoria en cualquier momento. Sin embargo, los usuarios regulares no pueden analizar (¡o escribir!) /dev/kmem, porque iniciar sesión en el sistema es una brecha de seguridad. Además, todos los periféricos conectados al sistema, como puertos de terminal, puertos de impresora y unidades de disco, están representados simbólicamente en el directorio /dev. ENLACES SIMBÓLICOS Como se mencionó anteriormente, la introducción de enlaces simbólicos complica enormemente el sistema de archivos UNIX; en el sistema los enlaces simbólicos son amplios mente presente. Varios enlaces simbólicos pueden apuntar al mismo archivo, y un enlace puede apuntar de un sistema de archivos (uno que no tiene límite de 14 caracteres) a otro (que puede tener un límite de 14 caracteres); por lo tanto, no se pueden aplicar las antiguas reglas estrictas de la jerarquía del árbol de directorios. En SVR4, la organización de todo el sistema (es decir, a partir del directorio raíz /) es muy compleja y, al moverse por el sistema de archivos, es necesario tener en cuenta los enlaces simbólicos y tratarlos con cuidado. Muchos programas que atraviesan el sistema de archivos, como find, no siguen de forma predeterminada los enlaces simbólicos, lo que requiere un manejo muy especial. Por ejemplo, si tuviera un enlace que apuntara a un directorio, como link.dir en los ejemplos anteriores, podría hacer un cd a ese directorio y el comando pwd apuntaría correctamente a la ubicación del directorio, como se muestra a continuación: $ cd enlace.dir $contraseña /home/giorgio/enlace.dir ps Esto da la impresión de que el enlace simbólico es realmente un directorio y que link.dir es su directorio actual; en realidad, uno de los propósitos del enlace simbólico es crear esta impresión. En realidad, link.dir no es un directorio y su directorio real actual es dirl, asumiendo que lo apunta link.dir; sin embargo, estos dos comandos son equivalentes: $ cd /home/juan/dir1 $ cd /home/george/enlace.dir ps Sin embargo, la salida de pwd es diferente en los siguientes dos casos: $ cd /home/juan/dir1 $contraseña /home/jorge/dir1 $ cd /home/george/enlace.dir $contraseña /home/giorgio/enlace.dir ps El ejemplo demuestra cómo es posible llegar a una sola ubicación en el sistema de archivos a través de diferentes rutas. Si no tiene esto en cuenta, puede suponer que estos diferentes caminos conducen a ubicaciones realmente diferentes y hacen cambios en un destino aparente, causando daños a los demás. Por lo general, los comandos pwd y cd están integrados en el shell, lo que nuevamente ayuda a dar la impresión de que el sistema de archivos realmente tiene la jerarquía que usa para navegar a través de él, mientras que con los enlaces simbólicos, pueden existir muchas otras versiones (tal vez haya más de uno). enlace simbólico a un archivo o directorio). En muchos casos, esto simplifica las cosas, porque siempre ve la versión del sistema de archivos que está utilizando; sin embargo, existe una representación del sistema de archivos real o de destino que respeta la jerarquía estricta. Dado que los enlaces simbólicos son punteros, deben apuntar a algo real, y ese es el sistema de archivos de destino compuesto por archivos y directorios reales. Todos los programas comunes de shell (sh, csh, ksh) implementan pwd devolviendo la ruta que usó para llegar a un directorio en particular, no la ruta real. Por el contrario, el programa /usr/bin/pwd no sigue esta convención de shell y siempre devuelve la ruta real al directorio de trabajo actual, como se muestra aquí: $cd enlace.dir $contraseña /home/giorgio/enlace.dir $/usr/bin/pwd /home/jorge/dir1 ps Si está navegando por el sistema de archivos para examinarlo, a menudo use /usr/bin/pwd para verificar en qué directorio se encuentra realmente. EXAMEN DEL SISTEMA DE ARCHIVOS En este capítulo, nos hemos centrado principalmente en el directorio de inicio y los archivos y directorios que crea en él para satisfacer sus necesidades. Por supuesto, esto es solo una parte del sistema de archivos, lo que en general da como resultado una estructura enorme y diversa. Hay más de 6500 archivos y 850 directorios en los sistemas SVR4 completos, aunque alrededor de una cuarta parte de ese total son herramientas de administración del sistema y alrededor de una décima parte del conjunto de desarrollo de software, que es posible que no esté instalado en su sistema. Aproximadamente 800 archivos son comandos, los enlaces simbólicos son aproximadamente 350. Además, los usuarios individuales y el software de aplicación pueden aumentar considerablemente los valores indicados. Muchos de estos archivos realizan funciones particulares dentro del sistema y su falta, o el incorrecto cumplimiento de los derechos de acceso a las necesidades reales, genera serios problemas y resultados extremadamente variables. Cuando ocurren situaciones anormales, es difícil encontrar y solucionar el problema sin realizar una operación de recarga del sistema. Por lo general, debe tener mucha confianza al cambiar o eliminar un archivo que no está en su directorio de inicio, y no debe tener ninguna duda al cambiar los derechos de acceso de un archivo en su sistema. Por otro lado, profundizar en el sistema de archivos puede ser una fuente de gran diversión y conocimiento del funcionamiento interno del sistema. Solo unos pocos archivos no son legibles, pero pueden llegar a serlo si las consideraciones de seguridad no son de suma importancia en su máquina. A partir del directorio "raíz", hay varios archivos y subdirectorios importantes, como se muestra a continuación: $ls-FI compartimiento@ bota/ tienes que etc/ exportar/ casa/ casa 2/ Instalar en pc lib@ perdido + encontrado/ mnt/ tu optas proe/ sbin/ shlib/ estar de pie/ tmp/ tu/ unix• usuario/ varios ps Estos pocos directorios proporcionan puntos de entrada a toda la jerarquía subyacente; desde aquí puede examinar todo el sistema de archivos. La Tabla 4.1 contiene un resumen de los principales archivos y directorios en los sistemas SVR4; si va a explorar el sistema de archivos, consulte esta tabla para obtener información sobre cada directorio encontrado. REORGANIZACIÓN DEL SISTEMA DE ARCHIVOS EN SVR4 Toda la organización del sistema de archivos de SVR4 ha cambiado profundamente desde SVR3 y versiones anteriores, principalmente debido a las necesidades de los sistemas en red o sistemas distribuidos. Algunas partes del sistema son específicas de una máquina en particular, como ciertos archivos de auditoría o archivos de historial de la máquina, mientras que otras pueden compartirse entre diferentes máquinas del mismo tipo y otras pueden compartirse entre casi todas las máquinas, independientemente de la versión de UNIX. sistema utilizado. Esto ha llevado a situaciones en las que muchas partes conocidas del sistema, lógicamente agrupadas en un subárbol de un directorio según su función, ahora residen en diferentes directorios. El sistema de archivos ha pasado de ser una organización funcional a una determinada por la máquina que en un entorno heterogéneo en red es responsable del mantenimiento y uso del archivo. Esta reorganización fue necesaria para admitir completamente una versión en red del sistema UNIX; si tiene experiencia con sistemas UNIX anteriores, tendrá que volver a aprender la ubicación de cada archivo y directorio. Por otro lado, los enlaces simbólicos en el sistema apuntan los nombres antiguos a las nuevas ubicaciones; si navega por el sistema de archivos y examina su contenido, tenga cuidado de no confundir los archivos reales con enlaces simbólicos que se presentan como si fueran el sistema de archivos real. Utilice /usr/bin/pwd con frecuencia para comprobar dónde se encuentra realmente en la nueva organización. CONVENCIONES PARA NOMBRES DE ARCHIVOS Y DIRECTORIOS El sistema UNIX sigue algunas convenciones relativamente estándar con respecto a la denominación de directorios; algunas convenciones nuevas se introducen en SVR4. Por lo general, las diferentes aplicaciones y los propios usuarios también siguen estas convenciones en sus propios directorios, aunque las reglas no se aplican fuera de los directorios del sistema. Los nombres de directorio bin (binario), sbin (bin independiente), lib (biblioteca), src (fuente), man (manual}, usr (usuarios), etc. (etcétera) se usan comúnmente. La mayoría de los programas ejecutables residen en el directorio bin, la mayoría de las bibliotecas de desarrollo y otro material de soporte residen en el directorio lib, la mayoría del código fuente para aplicaciones y comandos se encuentran en el directorio src, gran parte de la documentación reside en man, la mayor parte del material de usuario reside en un directorio home o usr, y la mayor parte del material de soporte reside en el directorio etc. Puede ver muchos de estos nombres si solicita ver el contenido del directorio "raíz". El directorio /usr/hin contiene la mayoría de los comandos, /bin suele ser un enlace simbólico a /usr/bin, muchos de los comandos restantes están en los directorios /sbin y /usr/sbin. Por lo general, los directorios sbin contienen los principales comandos de administración, los directorios bin contienen los comandos de usuario. Muchos sistemas pueden incluir otro directorio, /usr/local o /Iocal/hin para contener comandos que no forman parte del sistema UNIX oficial, pero que se han agregado a esa máquina específica. El directorio /etc contiene una gran cantidad de archivos y herramientas de software que se utilizan para administrar su sistema UNIX. Por ejemplo, /etc/rc2.d es un directorio que contiene los archivos que se utilizan cuando se carga el sistema, mientras que /etc/passwd es un archivo que contiene la lista de usuarios autorizados para acceder a la máquina. Las partes del sistema operativo UNIX que componen el kemel están contenidas en /etc/conf; este material se usa para actualizar el núcleo cuando agrega nuevo hardware a la máquina que requiere controladores de dispositivos periféricos. La versión actual de kemel cargada cuando se inicializa la máquina está en el directorio /stand; se guarda una copia en /unix para compatibilidad con software anterior, pero actualmente no se usa como kernel de inicialización. Nunca debe editar o eliminar manualmente el contenido de estos directorios, incluso si ocupan una gran cantidad de espacio en disco. El directorio /shlib (bibliotecas compartidas) contiene bibliotecas de subrutinas cargadas dinámicamente para admitir muchas aplicaciones y partes adicionales del sistema operativo UNIX. El Conjunto de desarrollo de software reside principalmente en /usr/ccs y sus subdirectorios, parcialmente en /usr/include y /usr/lib. A menudo /lib es un colega mención simbólica a /usr/lib. El directorio /dev contiene archivos especiales que administran las conexiones a dispositivos externos, /tmp se usa en aplicaciones como almacenamiento de archivos temporales, especialmente en el desarrollo de software. También puede usar /tmp para sus archivos temporales. Estos archivos se eliminan cuando se vuelve a cargar el sistema. /var/tmp también es un directorio para archivos temporales y no se vacía durante la inicialización en algunos sistemas. Los directorios privados de usuarios individuales generalmente residen en el directorio /home, pero algunos sistemas pueden usar /usr o /u en su lugar. El código fuente completo del sistema UNIX generalmente se encuentra en el directorio /usr/src y los subdirectorios relacionados, aunque rara vez está presente en las microcomputadoras. El directorio /usr/lib/uucp incluye soporte para el subsistema de comunicación uucp, /usr/share/lib/terminfo contiene descripciones de las funciones específicas de los terminales que se pueden conectar al sistema. Si está presente, /usr/man contiene la documentación del sistema, incluido el texto del Manual del usuario de UNIX. El directorio /usr contiene muchos otros objetos, muchos de los cuales son enlaces simbólicos a directorios en /var (variable), que contienen objetos que están sujetos a cambios en el curso de las operaciones de administración de la máquina. Muchos libros de registro, directorios de spool y otras variables están contenidos en /var. El subárbol /export está diseñado para contener archivos y directorios que se comparten o exportan a otras máquinas en la red. El paquete de compatibilidad BSD, si está instalado, reside en /usr/ucb y contiene comandos ejecutables; puede agregar este directorio en su RUTA para usar los comandos BSD. El archivo /usr/ucblib contiene material de soporte para el paquete de compatibilidad BSD. Las herramientas y el material de soporte del sistema X Window pueden residir en /usr/X, o en /usr/bin/Xlt, o en /usr/lib/Xl 1. Los menús y formularios de administración del sistema generalmente se almacenan en /usr/admin y /usr/vmsys; estos subárboles pueden ser muy grandes si la máquina incluye todas las herramientas de gestión previstas en SVR4. Finalmente, los desarrolladores de aplicaciones construyen una parte de la jerarquía de directorios solo para sus aplicaciones; a menudo se usa /install, /opt o /usr/add-on, de lo contrario, cada aplicación puede tener su propio esquema. Como resultado, su sistema puede tener muchos más directorios que los mencionados hasta ahora. Inspeccione a través de su propio sistema y estudie su estructura; encontrará muchos de estos archivos y directorios en los próximos capítulos. ===== Capítulo 5 Procesamiento de textos con vi y emacs 5.1 Editores de aprendizaje 5.2 El editor de texto de pantalla completa vi 5.3 Edición de textos con el editor vi 5.4 El editor de emacs 5.5 Perspectivas El sistema UNIX tiene muchos editores entre sus componentes estándar que difieren mucho entre sí y generalmente están optimizados para realizar un subconjunto particular de tareas de procesamiento de textos. ¡Ninguno de ellos son verdaderos procesadores de texto como los que se encuentran en otros pequeños sistemas o personas! porque en el entorno UNIX existe un conjunto bien definido de herramientas de software que realizan el procesamiento de textos o el formateo de documentos. Además de los editores estándar, existen muchos procesadores de texto en el mercado que seguramente satisfarán sus necesidades, pero en este libro solo trataremos las herramientas más utilizadas. vi (visual) es un editor que se originó en las versiones de BSD pero que se ha incluido en las versiones de System V durante muchos años. El otro editor principal, emacs, se usa ampliamente y es compatible con muchos sistemas; sin embargo, no se incluye en las versiones estándar. Debe comprarse por separado, pero hay varias versiones disponibles de forma gratuita. Una de las mejores es la versión gnu emacs distribuida por la Free Software Foundation. Otros editores, como el venerable ed (editor) y sed (editor de flujo) se describen en el siguiente capítulo. Las técnicas de procesamiento de texto, como muchas otras características del sistema UNIX, introducen muchos conceptos innovadores que encuentran una aplicación práctica en la actualización y filtrado de cadenas de caracteres, siendo los archivos de texto simples secuencias de caracteres. Entre estos conceptos, sin duda el más significativo es la definición de expresión regular que trasciende el procesamiento de texto y afecta a todo el entorno de programación. Este capítulo presenta las técnicas básicas para usar editores comunes para crear, editar y examinar archivos. En el siguiente capítulo se presentan conceptos y herramientas más avanzados y rápidos para el procesamiento de textos. 5.1 Editores de aprendizaje Las herramientas de procesamiento de texto en el entorno UNIX tienen una interfaz de usuario muy concisa y rápida de usar que favorece al experto más que al principiante. La mejor técnica para aprender a manipular textos es practicar intensamente en un archivo pequeño, porque es necesario adquirir habilidades y automaticidad que no se pueden aprender simplemente leyendo los manuales. Observe el trabajo de un usuario experto y pida explicaciones cuando vea que se están realizando operaciones desconocidas. Si no:μ puede obtener ayuda de expertos, la mejor manera de proceder es experimentar paso a paso a medida que lee el manual y asimilar progresivamente las nuevas funciones a medida que pueda dominar lo que aprendió anteriormente. Si le parece que un editor no puede satisfacer sus necesidades, la razón suele residir en su incapacidad para utilizar todo su potencial. Si es nuevo en el sistema UNIX, puede ser mejor comenzar con emacs en lugar de no vi. La experiencia muestra que incluso teniendo en cuenta las preferencias personales para uno u otro editor, emacs es más fácil de aprender, más fácil de usar y más configurable que vi. Sin embargo, las diferencias reales en el uso son pequeñas, por lo que si su sistema tiene usuarios expertos en vi o no tiene emacs instalado, vi es totalmente aceptable. 5.2 El editor de texto de pantalla completa vi El editor vi es un editor de texto de pantalla completa que muestra una ventana en el archivo completo contenido en un búfer interno. El cursor de la pantalla siempre está en una posición en la línea en uso, o en la línea actual, y muchas operaciones se realizan en esa posición. Cuando el cursor se mueve a una nueva posición en el archivo, la página de video se vuelve a mostrar para que siempre aparezca la línea actual. Sin embargo, vi no es un procesador de texto de formato de texto ni un sistema de gráficos, pero, dado que es independiente del tipo de terminal, puede usarlo desde una consola del sistema o desde un terminal remoto. El editor vi se deriva del editor ex y parte de su documentación se refiere a algunos comandos ex, sin embargo, actualmente ex no se usa con tanta frecuencia, por lo que trataremos principalmente con vi. PREPARACIÓN DEL TIPO DE TERMINAL Para ejecutar vi desde diferentes terminales, debe informar al programa del tipo de terminal con el que está trabajando almacenando esta información en la variable de entorno TERM (terminal). El editor vi, como muchas otras aplicaciones, lee esta variable de entorno cuando se inicia y adapta su salida al tipo de terminal que se utiliza. La mayoría de los sistemas no definen automáticamente TÉRMINO cuando inicia sesión a menos que esté operando desde una consola del sistema. sin embargo, el $TERMINO=ansi $ TÉRMINO de exportación La declaración ansi en minúsculas es correcta para terminales ANSI estándar o similares; se prevén otros valores para los terminales más habituales. Si comete un error al declarar la variable TERM, las aplicaciones de formato de pantalla podrán mostrar secuencias extrañas de caracteres de formas completamente impredecibles. El segundo comando del ejemplo anterior, export TERM, permite que el shell de inicio de sesión y todos sus subshells utilicen la variable TERM. Puede poner estos dos comandos en su archivo .profile, de modo que TERM siempre se inicialice cuando inicie sesión sistema. El archivo .profile y el procedimiento utilizado para inicializar la variable TERM se analizan en el Capítulo 8. El editor vi y otros programas de formato de pantalla leen la variable TERM y luego buscan una base de datos terminfo para obtener una descripción simbólica del terminal especificado. En los sistemas SVR4, esta base de datos se encuentra en el directorio /usr/share/lib/terminfo (también conocido como /usr/lib/terminfo), que contiene un subdirectorio para cada carácter inicial (letra o número) de las abreviaturas del tipo de terminal que son utilizados por los programas de gestión de vídeo. Por ejemplo, el directorio /usr/share/lib/terminfo/a contiene una lista de terminales cuyos nombres comienzan con a, como ansi, mientras que el directorio /usr/share/lib/terminfo/2 contiene una lista de terminales cuyo nombre comienza con 2, igual que el terminal HP 2626. Puede verificar si la descripción de su terminal está incluida en la base de datos inspeccionando los archivos en el directorio terminfo. Las versiones anteriores del sistema operativo utilizan un esquema de base de datos diferente para los terminales y la descripción de todos los terminales se puede encontrar en el archivo /etc/termcap. Si el directorio /usr/share/lib/terminfo está presente en la máquina, reemplaza la base de datos /etc/termcap para el editor vi y otras aplicaciones que necesitan manejar video. Los sistemas con microprocesador 80386 o 80486 basados ​​en el bus AT utilizan la declaración TERM=AT386 para usuarios de consola. En el sistema X Window debe declarar TERM = xterm, mientras que para una terminal remota, la declaración generalmente funciona TÉRMINO =ansi (estándar ANSI}. LANZAMIENTO DEL EDITOR vi El shell puede iniciar el editor vi con una línea de comando que toma una lista opcional de nombres de archivos como argumentos. $vi antiguo.archivo $vi mosaico nuevo $vi archivo.nuevo archivo.antiguo $vi Todos estos son ejemplos de comandos válidos. Si el archivo en cuestión no existe, créelo en vi: este es el método normal para crear nuevos archivos en un sistema UNIX. Si proporciona una lista de nombres de archivo como argumento, vi los trata secuencialmente uno por uno, cargando el primero en el búfer de texto cuando se inicia el programa. Los comandos están disponibles para procesar alternativamente un archivo u otro, pero vi no puede procesar varios archivos simultáneamente. Los comandos vi acceden al archivo actual. Si no especificó ningún nombre de archivo como argumento cuando inició vi, vi funciona bien, pero al final del trabajo tendrá que declarar un nombre de archivo para poder escribir texto desde el búfer al sistema de archivos. Con todos los comandos de los ejemplos anteriores, vi comenzaría con la primera línea del archivo como la línea actual. El editor vi acepta muchos otros argumentos de la línea de comandos, así como nombres de archivo. Por ejemplo, puede usar la opción + seguida de un número de línea para comenzar en ese número como la línea actual. Este comando $vi + 45 archivos antiguos define la línea 45 del archivo old.file como la línea inicial actual, mientras que el siguiente comando $vi + $archivo.antiguo comienza con la línea actual en la última línea del archivo. Si escribes en su lugar $vi +/cadena archivo.antiguo vi busca en el archivo old.file la primera aparición de una cadena y, si existe, asume la línea correspondiente como la línea actual. Después del carácter + puede especificar cualquier comando vi: el comando se interpretará antes de iniciar la ejecución. La Figura 5.1 muestra una pantalla de video típica durante una sesión de edición con un archivo corto. Normalmente vi llena toda la pantalla con el contenido del archivo de texto que está examinando, dejando la línea final libre para cualquier mensaje; sin embargo, si el archivo es corto o si llega al final del archivo, vi llena la parte no utilizada de la pantalla con líneas vacías que comienzan con el carácter - (tilde). Cuando ejecuta vi sin especificar el archivo o especificando un archivo inexistente, aparecerán líneas con un carácter de tilde a la izquierda a lo largo del video, lo que indica que el búfer no contiene texto. Las líneas de texto en el búfer interno están numeradas desde el uno hasta el final del archivo, aunque los números de línea normalmente no aparecen en la pantalla. El cursor de la pantalla aparece sobre un carácter de texto que se muestra en la pantalla; la línea que contiene el cursor es la línea actual, el carácter que contiene el cursor está en la posición actual n en la línea actual. Muchas operaciones de edición afectan la línea actual o la posición del cursor; le proporciona comandos para mover el cursor y cambiar la línea actual. MODALIDAD vi El editor vi tiene tres modos de ejecución diferentes (o modos), que son diferentes estados en los que puede estar en diferentes momentos. Puede cambiar de un modo a otro para realizar diferentes operaciones de edición. En el modo de comando, puede ingresar comandos directos al editor, cambiar la línea actual, salir de la sesión. En el modo de inserción, o modo de texto, puede ingresar texto directamente en el archivo. Normalmente, inicia vi en el modo de comando, pero puede cambiar al modo de inserción para agregar texto y luego cambiar de modo a medida que edita el texto. Esto puede ser una fuente de errores porque es fácil olvidar qué modo está en uso en un momento dado. Si ingresa comandos y está en modo de texto, estos caracteres se vuelven parte del contenido del archivo, mientras que si ingresa algún texto y está en modo de comando, puede causar cambios inesperados en su archivo. El comando interno establecido muestra el modo actual; este comando se describe más adelante en este capítulo . Por ahora, puede activar la visualización del modo actual usando el comando :establecer modo de presentación Un tercer modo de ejecución, llamado modo de última línea, le permite ingresar líneas de comando en la línea inferior de la pantalla. El carácter: (dos puntos) introducido en modo comando provoca la transición al modo última línea; como puede ver, el comando set del ejemplo anterior también es un ejemplo del uso del modo de última línea. Puede ingresar la última línea solo desde el modo de comando; si está en modo texto, el carácter : se introduce como texto en el búfer. Cuando cambia al modo de última línea con el carácter: (y otros caracteres de comando), el cursor salta a la última línea de la pantalla donde se le solicita que ejecute su línea de comando. En el caso de nuestro ejemplo anterior, ingrese la línea de comando set showmode para activar la visualización del modo actual. CAMBIO DE MODO El modo de última línea se usa para insertar una sola línea de comando en la línea final del video; ejecutado el comando vi sale del modo de última línea y vuelve al modo de comando, por lo tanto, el modo de última línea es de corta duración; por el contrario, los otros dos modos permanecen activos hasta que solicite explícitamente un cambio de modo. Cuando está en el modo de inserción, puede cambiar al modo de comando presionando la tecla ESCAPE, generalmente marcada como Esc en los teclados más populares. Puede cambiar del modo de comando al modo de inserción utilizando uno de los comandos de manejo de texto que se muestran más adelante en este capítulo. Cada modo funciona de manera diferente y tiene su propio conjunto de comandos. Los comandos en el modo de última línea aparecen en la última línea a medida que los ingresa, los comandos en el modo de inserción no se muestran en absoluto. Consulte la Tabla 5.1 para obtener un resumen de los principales comandos vi, que se tratan en los siguientes párrafos. SALIR DE LA SESIÓN vi Para salir de vi y volver al shell puedes usar el comando :q (salir) :q Este comando se ejecuta solo si no ha modificado el archivo desde el último registro anterior. Si usa el comando después de actualizar el archivo pero antes de ponerlo en el disco, vi no lo ejecuta y muestra el siguiente mensaje: :q Sin escritura desde el último cambio (:¡salir! anula) Puede obligar a vi a salir y abandonar todos los cambios realizados en el archivo en la sesión actual agregando un ! (signo de exclamación) al :q, por ejemplo: :q! Tenga en cuenta que si fuerza el cierre de vi de esta manera, se perderán todos los cambios realizados en el archivo desde la última vez que se guardó. REGISTRO DE ARCHIVOS El modo de última línea proporciona comandos para leer y escribir archivos entre sistemas de archivos y el búfer de texto vi. El comando :w reescribe el archivo procesado en el disco; utilizará este comando de forma rutinaria antes de finalizar la sesión vi, teniendo en cuenta que el archivo en el disco se sobrescribe. El búfer interno se mantiene intacto, por lo que puede volver a escribir sus cambios cuando sea necesario. Es aconsejable volver a escribir el archivo con frecuencia durante una sesión de edición para evitar errores de edición de texto involuntarios, ya que vi no proporciona grabaciones automáticas ni copias de seguridad. Puede cambiar el nombre del archivo para una operación de escritura especificando una ruta de acceso completa después de .w, por ejemplo: :w otro.archivo Este comando crea un nuevo archivo con el nombre otro.archivo en el directorio actual y escribe el búfer en el archivo, luego le informa el tamaño del archivo escrito, por ejemplo: :w otro.archivo "otro.archivo" 4 líneas, 96 caracteres Este mensaje aparece en la última línea en lugar del comando :w. Si el archivo other.file ya existe, vi muestra el siguiente mensaje en lugar de realizar la operación de escritura: :w otro.archivo "otro archivo" El archivo existe: use "w! other.file" para sobrescribir De esta forma evitará reescribir un archivo por error. Puede obligar a vi a reescribir el archivo de todos modos agregando un ! al w, como se muestra en el mismo mensaje de error. Si no tiene permiso de escritura para ese archivo, muestra el siguiente mensaje en lugar de escribir: :w! otro.archivo "otro.archivo" Permiso denegado En este caso, deberá cambiar los permisos de acceso al archivo o escribir el búfer con un nombre de archivo diferente. Todos los mensajes de error aparecen en la línea inferior de la pantalla y se superponen al comando :. Puede escribir solo una parte del archivo indicando una serie de líneas con la operación w; después de : ingrese el número de la primera línea que desea escribir, seguido de una coma, luego el número de la última línea que desea escribir y finalmente el comando w, por ejemplo: :5,30w otro archivo Solo las líneas cinco a treinta se escriben en el archivo other.file, el búfer interno permanece sin cambios. Puede combinar las operaciones w write y q output, por ejemplo: :wq Esto escribe el archivo y luego regresa al shell. En el modo de comando, también puede usar el comando ZZ (Z mayúscula) como sinónimo de :wq para escribir el archivo y volver al shell. LECTURA DE ARCHIVOS El comando r es similar a w, excepto que lee un archivo en el búfer interno después de la línea actual. También en esta operación te da información sobre el archivo, por ejemplo: :r otro.archivo "otro.archivo" 6 líneas, 158 caracteres El comando se puede utilizar para cargar el archivo indicado en un búfer vacío o para insertar el contenido del archivo en el texto del búfer actual. Si ingresa un número de línea antes de la r, como en el ejemplo: :6r otro.archivo le leerá el archivo después de la línea indicada en lugar de después de la línea actual. Ejecutar el comando r mueve la línea actual después de la última línea leída. INTERCAMBIO DE ARCHIVOS Si ingresó vi con una lista de nombres de archivo, el comando :n (siguiente) cierra el archivo actual y lo intercambia con el siguiente archivo en la lista de nombres. Si el archivo actual no se ha escrito después de modificarlo, aún puede forzar el intercambio de archivos con el comando :n!. Si desea saber el nombre del archivo actual, puede usar el comando en modo de última línea :f (archivo), o el operador CTRL-G para mostrar el nombre y el tamaño del archivo actual. ACTUALIZACIÓN DE PANTALLA Si la pantalla se distorsiona o se distorsiona por algún motivo, el operador de modo de comando CTRL-L hace que la pantalla se actualice con el contenido actual del búfer. Esto es útil cuando los mensajes del sistema de la consola perturban la vista de una sesión de edición. SHELL EN FUNCIONAMIENTO ¡El personaje! toma varios otros significados en el modo de última línea. Puedes usar :! comando o tubería para suspender temporalmente vi y ejecutar un comando o canalización en una subcapa; al final del comando o canalización, el control regresa A usted. Por ejemplo, este comando: :!ls ejecuta ls en el directorio actual. Para acceder al shell teniendo que realizar múltiples operaciones, puedes usar el siguiente comando: :sh Se suspende la ejecución de vi y se muestra el aviso de PSI. Puede ingresar comandos de shell; cuando desee finalizar las operaciones de shell, puede escribir exit o presionar CTRL-D y el control regresa a vi. 5.3 Procesamiento de textos con el editor vi Ahora conoce las operaciones básicas de vi y puede comenzar a usar los muchos comandos disponibles a medida que practica el procesamiento de texto real en sus archivos de prueba. ERROR DE RECUPERACIÓN Uno de los comandos más importantes es el operador u (deshacer). El editor almacena el contenido anterior al último cambio realizado en el archivo; por lo tanto, puede deshacer este último cambio en cualquier momento y recuperar el contenido anterior con u. Si has realizado una serie de cambios, solo podrás recuperar el más reciente. Pruebe el comportamiento del comando u y vea qué sucede cuando ejecuta dos comandos u sucesivos. CAMBIO DEL MODO COMANDO AL MODO INSERCIÓN Muchos comandos cambian del modo de comando al modo de inserción. Puede mover el cursor a una posición particular en el archivo, ingresar al modo de inserción y luego ingresar todo el texto que desee, incluidas las líneas nuevas. Solo debe recordar presionar la tecla ESC para volver al modo de comando cuando haya terminado de ingresar el texto agregado. El comando o (abrir) abre una nueva línea de texto después de la línea actual y coloca el cursor al comienzo de la nueva línea, mientras que el operador O mayúscula (letra O) abre una línea encima de la línea actual. El carácter a (añadir) le permite activar el modo de inserción a partir del carácter ubicado después del cursor y el operador A mayúscula le permite insertar texto al final de la línea actual. El operador i (entrada) permite insertar texto a partir de la posición anterior a la ocupada por el cursor y activa el modo de inserción a partir del principio de la línea actual. Cuando esté en el modo de inserción, el texto a la derecha del cursor se moverá hacia la derecha a medida que ingrese texto adicional. Para volver al modo de comando, use la tecla Esc. MODO INSERCIÓN En vi, muchas funciones que están disponibles en el modo de inserción son intuitivas. Cuando está en el modo de inserción, todo el texto que escribe va al archivo, incluidos los caracteres de retorno de carro que le permiten insertar nuevas líneas de texto. Si comete un error tipográfico, la tecla +- mueve el cursor hacia atrás una posición, borrando uno o más caracteres en la línea actual, al principio de la línea; sin embargo, no permite que vi retroceda con la tecla +- desde el comienzo de la línea. Para editar una línea que precede a la actual, debe ingresar al modo comando, reposicionar el cursor sobre el texto con el error y luego realizar la edición. Puede presionar la tecla CTRL-w para eliminar la palabra actual sin salir del modo de inserción. Un error común es tratar de ingresar comandos mientras está en modo de inserción sin presionar primero la tecla Esc; incluso los usuarios experimentados de vi cometen este error o al revés, es decir, intentan ingresar texto en modo comando. El segundo error es más destructivo porque, a medida que escribe, puede realizar muchos cambios no intencionales en el archivo. Estos cambios normalmente no se pueden deshacer con el operador u, ya que el comando deshacer solo puede recuperar el último cambio realizado. Para evitar los problemas asociados con estos errores, escriba con frecuencia el archivo en el disco con el comando :w, cuando esté seguro de que es correcto. SE MUEVE EN EL TAMPÓN El modo de comando se usa principalmente para navegar a través del búfer de texto y para cambiar al modo de inserción de varias maneras para editar el texto del archivo. Puede cambiar la posición de la línea actual, lo que a menudo implica volver a mostrar la pantalla para que la línea actual quede centrada en el video. También puede mover el cursor dentro de la línea actual. Las ediciones o las entradas de texto que realice en el búfer se realizarán en la línea actual, en la posición actual del cursor. El operador w (palabra) mueve el cursor hacia adelante al principio de la palabra que sigue a la actual, mientras que el operador b (atrás) mueve el cursor hacia atrás al principio de la palabra que precede a la actual. La barra espaciadora mueve el cursor hacia adelante un carácter, mientras que la tecla +- lo mueve hacia atrás una posición. RETURN mueve el cursor al principio de la siguiente línea y el carácter - (menos) lo mueve al principio de la línea anterior a la actual. El carácter - mueve el cursor al principio de la línea actual, mientras que $ lo mueve al final y la línea actual. Todos estos operadores de desplazamiento pueden estar precedidos por un argumento numérico o un contador de repeticiones. Por ejemplo, el comando 5w mueve el cursor al principio de la quinta palabra que sigue a la actual, y 6 - lo vuelve a mover al principio de la sexta línea que precede a la actual. El operador H mueve el cursor a la primera línea de la pantalla, mientras que L lo mueve a la línea inferior de la pantalla. Puede moverse a una línea en particular en el búfer con G (ir) precedido por el número de línea deseado. La última línea del archivo se identifica con el símbolo lógico $, por lo que puede usar $G o simplemente G para moverse al final del búfer. Algunos comandos en el modo de última línea también se pueden usar para navegar por el archivo. Para pasar a la primera línea del archivo, puede escribir :1, mientras que para pasar a la última línea del archivo, obviamente se usa :$. La línea actual en el archivo se identifica con el símbolo lógico. (punto). Puede determinar el número de la línea actual con el comando de última línea igual a punto, por ejemplo: ... -- En respuesta, muestra el número de línea actual en la parte inferior de la pantalla. Similarmente :$= muestra el número de la última línea del archivo. Presionando CTRL-F avanzas en el archivo una pantalla completa, mientras que si presionas CTRL-B te posicionas en la pantalla que precede a la de la línea actual. La pantalla se vuelve a mostrar durante estos movimientos. Los teclados de muchos terminales incluyen teclas de control del cursor y generalmente también responden a estas teclas además de los operadores de movimiento del cursor descritos. Aún deberá verificar la consistencia del comportamiento de su versión de vi con su terminal. Si su terminal no permite el uso de las teclas de control del cursor, debe usar las teclas de letras h para mover un carácter a la izquierda, I para mover un carácter a la derecha, j para mover una línea hacia abajo a la misma posición del cursor, k para mover una línea hacia arriba a la misma posición del cursor. BUSCAR TEXTO Una variante del modo de última línea le permite buscar cadenas de texto en el archivo; la búsqueda comienza desde la posición actual del cursor y continúa hasta el final del archivo, posiblemente reiniciando desde el principio. si la cadena no se encuentra, la búsqueda finaliza volviendo a la posición actual del cursor. Use I (barra oblicua) seguida de una cadena para buscar. El comando: /cadena cadena de búsqueda en el archivo. Cuando ingresa I, el cursor se mueve a la última línea del video (la línea actual no se modifica) y la cadena que ingresa se muestra a continuación. Cuando presiona RETURN comienza la búsqueda; si se encuentra una cadena coincidente, vi muestra la parte del archivo en la pantalla con el cursor en la cadena encontrada. Puede buscar hacia atrás en el archivo con el carácter?; la búsqueda avanza hacia atrás a partir de la posición actual del cursor, finalmente se reinicia desde el archivo del archivo y continúa hacia atrás hasta volver a la línea actual. Una vez que una cadena con I o ? puede repetir la búsqueda de otra aparición de la misma cadena escribiendo I o ? y volver; puede invertir la dirección de búsqueda sin limitación. La cadena ingresada es recordada por vi para búsquedas posteriores, pero si ingresa I o ? sin haber especificado una cadena antes, señala el hecho: EL Sin expresión regular anterior La cadena de búsqueda puede tener una estructura mucho más compleja que una cadena de texto simple; Veremos esto cuando tratemos con expresiones regulares en el próximo capítulo. EDICIÓN DE TEXTO Varios operadores activan el modo de texto y le permiten cambiar el texto existente. El comando r (reemplazar), seguido de un solo carácter, reemplaza el carácter en la posición actual del cursor con el carácter especificado, dejándolo en el modo de comando, porque el reemplazo es solo para un carácter. El operador R le permite reemplazar cualquier número de caracteres, comenzando en la posición actual del cursor, dejándolo en el modo de inserción. Solo puede reemplazar el texto hasta el final de la línea actual, mientras que las nuevas líneas introducidas con RETURN se agregan al archivo después de la línea actual. Cuando regresa al modo de comando presionando la tecla ESC después de una operación R, los caracteres restantes a la derecha en la línea actual que no se han sobrescrito permanecen sin cambios. El comando C (cambiar) funciona de manera similar a R, pero se cambia toda la línea incluso si cambió un solo carácter antes de volver al modo de comando. El comando cw cambia la palabra actual, mientras que 6cw cambia seis palabras consecutivas, el operador cc le permite cambiar el contenido de la línea actual, 6cc le permite cambiar seis líneas consecutivas. El El operador J (join) une dos líneas de texto eliminando el carácter de nueva línea que separa la línea actual de la siguiente. Si por el contrario desea dividir una línea en dos, debe mover el cursor al punto donde desea dividir, entrar en modo insertar y presionar RETURN. BORRANDO TEXTO También hay operadores que le permiten eliminar partes del texto. El operador x elimina el carácter actual, mientras que 6x elimina seis caracteres consecutivos que comienzan en la posición actual. El operador dd elimina la línea actual, mientras que 6dd elimina las siguientes cinco líneas, así como la línea actual. Puede eliminar una sola palabra con dw o cinco palabras consecutivas con Sdw. El comando D elimina desde la posición del cursor hasta el final de la línea actual. También puede usar el modo de última línea para borrar una serie de líneas indicando los números de la primera y la última línea. Por ejemplo, con el comando: :3,5d se eliminan las líneas tres a cinco. OPERACIONES REPETITIVAS El operador. (punto) repite, en la posición actual del cursor, la última modificación realizada tanto al agregar como al eliminar y reemplazar texto. MOVER Y COPIAR TEXTO El editor admite algunos búferes de tránsito internos que puede usar para transferencias de bloques de texto en el archivo actual. Además del búfer de texto principal, hay un búfer de tránsito predeterminado; puede definir otros búferes de tránsito utilizando un nombre de un carácter. Cuando realiza una operación con uno de estos búferes, lo hace referencia por su nombre. Estas operaciones se conocen como terminología yank y put in vi; en otros entornos, a menudo se denominan operaciones de cortar y pegar o copiar y pegar. Todas estas operaciones funcionan sobre bloques de líneas completas; para guardar (tirar) parte de una línea, debe dividir la línea en dos y guardar la parte que desee. Puede transferir un fragmento de texto al búfer de tránsito con el comando Y (yank), que puede estar precedido por una serie de líneas para guardar. Por ejemplo, el comando 7 años transfiere la línea actual y las siguientes seis líneas al búfer de tránsito predeterminado. Puede cambiar la posición del cursor y luego usar el comando p (poner) para colocar las líneas de texto copiadas previamente en el archivo después de la línea actual. La letra P mayúscula le permite insertar líneas en el archivo, antes de la línea actual. Estas son operaciones de copiar y pegar, porque yank no altera el texto, simplemente lo copia en el búfer de tránsito predeterminado. Para realizar una operación de pegado lindo, puede eliminar un bloque de líneas con un comando como 7dd; esto elimina la línea actual y seis líneas subsiguientes del búfer principal. Las líneas eliminadas se almacenan en el búfer de forma predeterminada, por lo que después de una eliminación como esta, puede cambiar la posición del cursor y usar p o P para pegar el material nuevamente en el archivo. Cuando ejecuta una operación de pegado, el material no se borra del búfer de tránsito, por lo que puede copiar el mismo material varias veces en el archivo. Sin embargo, tan pronto como realice otra operación de cambio, el material en el búfer de tránsito se perderá y será reemplazado por el cambio más reciente. El búfer transitorio predeterminado también se usa para el comando u; el contenido anterior del texto que se está editando se almacena cada vez en el búfer transitorio predeterminado, simplemente cópielo de nuevo a su ubicación original. Cada modificación permanece en el búfer de tránsito predeterminado hasta que realice cualquier otra operación que modifique el texto que se está editando. Puede almacenar texto de forma más permanente en un búfer definiendo su propio búfer de tránsito con un nombre de un carácter, precedido por ". Este comando 7"aY transfiera siete líneas al búfer llamado a; se pueden definir hasta 26 buffers al mismo tiempo, cada uno con un nombre diferente. El texto almacenado en su búfer de tránsito se puede transferir al archivo, después de la línea actual, con un comando como el siguiente: "ap MOVER Y COPIAR TEXTO UTILIZANDO NÚMEROS DE LÍNEA El modo de última línea también permite mover y copiar bloques de líneas definidos por números de línea. Puedes usar, por ejemplo: :3,5m9 para mover las líneas 3 a 5 después de la línea 9; las líneas se eliminan de su posición original. Del mismo modo, puede utilizar :3.5t9 para copiar las líneas 3 a 5 después de la línea 9, pero sin borrar las líneas originales de su ubicación inicial. Puede copiar o mover una sola línea, usando un solo número, por ejemplo: :5m9 Los números de línea también se pueden expresar con direcciones usando expresiones regulares completas, como veremos en el próximo capítulo. 5.4 El editor de emacs El editor de emacs es popo lare casi como vi, pero no es parte del sistema UNIX estándar. Sin embargo, está disponible para todas las versiones de UNIX para cualquier máquina, y una nueva versión está disponible con cada nueva versión del sistema. El editor de emacs se diferencia de vi en la filosofía pero, como vi, no es un procesador de textos en el sentido moderno de la palabra. Al igual que vi, emacs le permite usar cualquier terminal, aunque algunas versiones de emacs no usan la base de datos de terminales /usr/share/lib/terminfo, pero tienen un archivo de descripción de terminal en /usr/share/lib/emacs/terminals o / usr/lib/emacs/terminales. Hay otros directorios en emacs, que pueden diferir ligeramente entre versiones, como el directorio /usr/share/lib/emacs que contiene la lista de macros disponibles y otras cosas. CONCEPTOS BÁSICOS DE emacs Cuando se ejecuta, el editor de emacs difiere fundamentalmente de vi en que no hay distinción entre el modo de comando y el modo de inserción, pero cualquier carácter que ingrese desde el teclado termina en el texto en la posición actual del cursor. En otras palabras, emacs siempre está en modo de inserción y, además, el término modo adquiere un significado diferente porque no se refiere al estado del comando del editor, sino al estado de activación actual de las opciones. Por ejemplo, cuando el editor muestra la numeración de líneas del archivo que se está editando, se usa para decir que el modo de numeración de líneas está activo. Los comandos para mover el cursor, leer o escribir archivos, abrir nuevas líneas y otras utilidades están representados por secuencias de teclas especiales, la primera de las cuales es ESC o CTRL. Por ejemplo, para salir de emacs y pasar el control al shell, utilice la combinación de teclas CTRL-X seguida de CTRL-c. En la terminología de emacs, estas teclas CTRL se indican con la notación AxAc (a veces también C-xC-c), donde el carácter - (o C-) que precede a los otros caracteres significa mantener presionada la tecla CTRL mientras se escriben los siguientes caracteres. Si desea ejecutar un comando en su lugar, presione la tecla Esc seguida de un carácter, como en el caso de Esc-M (tecla Esc seguida de la tecla M) que muestra las opciones actuales de emacs. En la terminología de emacs, estas secuencias de escape se indican con la letra M (meta) seguida del carácter correspondiente, como en el caso de M-d que equivale al comando ESC-D, mientras que cualquier secuencia de caracteres que no empiece por Esc o CTRL indica un fragmento de texto para almacenar en el archivo. En general, el editor de emacs usa comandos CTRL para llamar a varias funciones en líneas individuales o caracteres individuales; metacomandos para operar en palabras o frases; En cambio, los comandos CTRL-meta identifican combinaciones más complejas de ambas operaciones. La Tabla 5.2 resume los comandos de emacs. Muchos usuarios prefieren el estilo simple de emacs al de vi, aunque el conjunto de comandos definido en el entorno de emacs es menos nemotécnico que los comandos vi, y aprender las características de emacs es más complicado que el de vi. LANZAMIENTO de emacs Para iniciar el editor de emacs, use el siguiente comando, donde la especificación del archivo es opcional: $ emacs antiguo.archivo Este comando solo toma un nombre de archivo como argumento y, si se especifica, el archivo se escribe en el búfer principal de emacs. El argumento opcional + n, donde n es un número, hace que emacs coloque el cursor en la línea n. Después de la operación de carga, es posible leer otros archivos en los búferes adicionales de emacs y esto permite al usuario actualizar simultáneamente hasta 12 archivos. El comando "x"f (f significa archivo) hace posible leer un archivo nuevo en un búfer nuevo, a diferencia del comando -x"r (r significa lectura), que lee un archivo en el búfer actual de solo lectura. El comando -xi (insertar) lee un archivo en el búfer en la posición actual del cursor, sin alterar ningún contenido actual del búfer. Estos comandos, antes de ejecutar su acción, le piden al usuario el nombre del archivo para leer. La Figura 5.2 muestra una pantalla típica producida por emacs, después de que el programa se ha cargado con el archivo /etc/profile; esta imagen puede diferir ligeramente de otras versiones de emacs. La parte superior de la ventana gráfica muestra la línea actual y las líneas adyacentes del archivo que está procesando. Puede cambiar el tamaño de la ventana y mostrar u ocultar los números de línea con los comandos de emacs, usando la secuencia "x"m (modo de cambio), discutida más adelante. La parte inferior de la pantalla muestra el nombre de emacs, seguido del nombre del archivo o búfer actual y las opciones o modos en vigor (en este caso Fundamental). El porcentaje de archivos en pantalla se muestra a continuación; en el caso de archivos pequeños, Ali se indica para indicar que el archivo completo aparece en la la pantalla. Los guiones a la izquierda significan que el archivo no ha sido modificado desde que inició la operación de edición; dos caracteres * también aparecen tan pronto como se cambia el contenido del búfer. La línea inferior de la ventana contiene información de emacs, reservada para mostrar mensajes y comandos especiales. Entre otros mensajes, varias versiones de emacs le advierten en esta línea si tiene correo en espera. La mayoría de las versiones de emacs generalmente admiten algún comando especial que permite leer el correo en un búfer de texto o enviar el contenido de un búfer como correo. DIVISIÓN DE PANTALLA El editor de emacs puede dividir la pantalla en dos ventanas para que pueda trabajar con el contenido de dos búferes simultáneamente, mientras que es posible trabajar con 12 búferes diferentes al mismo tiempo. Si solicita leer un segundo archivo en un segundo búfer con el comando AxAf, puede dividir la pantalla en dos ventanas separadas usando el comando Ax2; en este caso, emacs le pide que especifique el nombre o el número del segundo búfer para mostrarlo en el video. Puede volver a una sola ventana con Axl y, en este caso, emacs le solicita que especifique qué búfer conservar en el video. Tenga en cuenta que cuando muestra u oculta un búfer, permanece en la memoria interna de emacs, por lo que no cierra el archivo ni deshace los cambios. Antes de devolver el control al shell, emacs espera a que confirme cualquier búfer o descarte los cambios. El editor señala cuál de los dos búferes está actualmente activo; la línea de información en la parte inferior de la pantalla muestra el nombre y el número de búfer de la ventana activa. Puede activar la otra ventana con el comando ·xo (otro) o cambiar completamente los búfer mostrados con ·xl> (búfer). ESCRITURA DE ARCHIVOS Después de realizar cambios en el búfer, puede escribirlo con el comando ·x·w (escribir). emacs le solicita confirmación mostrando en la parte inferior de la pantalla: Escribir archivos: y esperando la introducción de la ruta al archivo para escribir. Puede presionar RETURN para volver a escribir el búfer en el archivo actual o ingresar el nombre de otro archivo. Para volver a escribir el búfer actualmente activo en el archivo actual, use el comando ·x·s (guardar); también puede cancelar la operación de escritura con el comando -g. SALIR DE emacs Si desea salir de emacs y regresar al shell, use el comando ·x·c (dosis). Si intenta salir antes de escribir los archivos, emacs le solicita confirmación antes de volver al shell y perder los cambios. SOLICITUD DE TEXTO DE AYUDA Muchas versiones de emacs tienen extensos textos de ayuda; el comando li (ayuda) invoca el subsistema de ayuda. Después de li, puede ingresar a? u otro comando li para obtener información de ayuda para usar el subsistema de ayuda. Como alternativa, puede utilizar clave hc para obtener una breve descripción de cualquier secuencia de caracteres de comando; se puede obtener una descripción más completa con la tecla -hk La inversa, es decir, la secuencia de caracteres necesaria para ejecutar una función, se puede obtener, si conoce el nombre exacto del comando, con el comando hw El tiempo dedicado a aprender a usar las funciones de ayuda de emacs está bien invertido. MOVER LA POSICIÓN DEL CURSOR En emacs, cuando el cursor aparece sobre un carácter, la posición actual que se maneja es la anterior a la posición del cursor, por lo que el texto que ingresa se inserta frente al cursor. Tenga en cuenta este comportamiento al usar emacs. En el entorno de emacs existe un gran conjunto de operadores que permiten modificar la posición actual del cursor. El comando -f (adelante) mueve el cursor un carácter hacia adelante, mientras que b (atrás) lo mueve hacia atrás una posición. El operador -n (siguiente) mueve el cursor a la línea siguiente, -p (anterior) lo mueve a la línea anterior, el comando -a mueve el cursor al principio de la línea actual, mientras que -e (final) lo mueve hasta el final de la línea actual. El comando M-< mueve el cursor al principio del búfer, mientras que M·> lo mueve al final. La opción M-f mueve el cursor hacia adelante una palabra, M-b lo mueve hacia atrás una palabra, el comando -v mueve el cursor hacia adelante una página y M-v mueve el cursor hacia atrás una página. La mayoría de estos comandos toman un argumento numérico para repetir la acción varias veces, y estos argumentos se especifican comenzando con la tecla ESC, luego el número y finalmente la opción deseada. Por ejemplo, para avanzar ocho palabras, presione ESC, luego 8, luego Esc y finalmente f. BORRANDO TEXTO Dado que cada carácter que escribe termina en texto en la posición actual, no hay problema para insertar texto con emacs, pero necesita comandos específicos para eliminar texto. La tecla +- borra el caracter que s i está a la izquierda del cursor, mientras que -d (eliminar) elimina el carácter en la posición actual del cursor. El comando -k (matar) elimina la línea actual a partir de la posición a la derecha del cursor, o concatena la línea actual con la línea siguiente si el cursor está al final de la línea. Si el argumento especificado es 0, se elimina todo el texto entre el comienzo de la línea y la posición ocupada por el cursor, mientras que un argumento mayor que 0 indica cuántas líneas se eliminan a partir de la posición ocupada por el cursor. Un argumento menor que 0, por otro lado, indica el número de líneas que se eliminan antes del cursor. MARCAR EN emacs Los comandos más complejos de transferencia y eliminación de texto involucran símbolos llamados marcas; emacs le permite especificar hasta 12 marcas, una para cada búfer de texto. Puede colocar una marca en la posición actual del cursor con el comando M-BARRA ESPACIADORA; la marca no se muestra en la pantalla en muchas versiones de emacs. Cuando mueve el cursor, la marca permanece en la posición de colocación; a continuación, puede transferir o eliminar el texto entre la marca y la posición actual. Cuando cambia emacs a otro búfer, la marca en el búfer anterior permanece en su lugar y puede colocar otra marca en el búfer activo actual. Dado que las marcas no se muestran en la pantalla, es fácil olvidar dónde están; puede intercambiar la posición de la marca y el cursor con el comando -x-x; para volver a la posición original del cursor y restaurar la marca, ejecute -x-x por segunda vez. MOVER Y COPIAR TEXTO EN emacs Cuando se elimina parte de un búfer de texto, emacs lo guarda en una pila de eliminación; esta pila contiene el texto de las últimas ocho operaciones de eliminación realizadas. Para transferir texto, generalmente marca el inicio del bloque, mueve el cursor al final del bloque y luego elimina el bloque con -w. En realidad, el texto no se pierde, por lo que puede mover el cursor a la ubicación donde desea que vaya el texto y escribir el comando -y para insertar el último bloque eliminado en la posición actual del cursor. Para eliminar un fragmento de texto, simplemente muévalo a la pila de eliminación con -w y olvídese. El comando -y también es útil para reparar cualquier error al eliminar texto, ya que el texto se guarda en la pila después de la operación de eliminación. En emacs también hay un comando específico para este propósito. El comando M-w recopila el texto entre la marca y la posición actual del cursor y lo coloca en la pila, pero no modifica el búfer actual; se utiliza junto con el comando -y para copiar bloques de texto de un lugar del archivo a otro o de un búfer a otro. BÚSQUEDA Y REEMPLAZO DE CADENAS DE TEXTO El editor de emacs admite operadores de búsqueda que son particularmente eficientes para ubicar cadenas de texto o expresiones regulares en el búfer actual. El comando -s (buscar) establece la acción de búsqueda; emacs requiere ingresar la cadena de búsqueda, usando la sintaxis de expresiones regulares. La búsqueda avanza desde la posición actual del cursor hasta el final del archivo. El comando l> (hacia atrás) busca hacia atrás desde la posición actual del cursor hasta el principio del archivo; de nuevo, emacs requiere la cadena de búsqueda. Cuando se encuentra una cadena coincidente, puede proceder a buscar la siguiente aparición de la misma cadena con otra -s (búsqueda) o -r (reversa); si no ingresa una nueva cadena, se reutiliza la cadena anterior. Cuando llegue al final del archivo, puede reiniciar la búsqueda desde el principio del archivo con otra -s; puede interrumpir una búsqueda en curso con -g. Se aplica un procedimiento similar para realizar la sustitución de cadenas que coincida con expresiones de búsqueda regulares. La operación comienza con el comando: M - x reemplazo de cadena Después de M-x debe ingresar la cadena de reemplazo, luego presione RETURN; emacs requiere que ingrese la cadena para buscar y la que reemplazará. La sintaxis sigue siendo la misma que para las expresiones regulares; ingrese la cadena para reemplazar y RETURN, la cadena de reemplazo y RETURN nuevamente. Esta operación debe hacerse con cuidado, porque implica reemplazar todas las apariciones de la primera cadena con la segunda. Con el comando: M - x confirmar-reemplazar seguido de la misma secuencia de operaciones, emacs implementa un mecanismo de sustitución interactivo; una vez que se ha encontrado la cadena requerida, se requiere su confirmación para llevar a cabo el reemplazo. Presione y si desea realizar el reemplazo de la cadena actual encontrada; de lo contrario, escriba n para evitar ese reemplazo. En ambos casos, emacs busca la siguiente aparición de la cadena, si existe. También puede presionar R para i Haga que emacs reemplace todas las apariciones restantes de la cadena contenida en el archivo sin más indicaciones, o puede escribir -g para cancelar la operación y volver a las operaciones normales de emacs. SHELL EN FUNCIONAMIENTO Como muchos otros comandos, emacs le permite suspender temporalmente su ejecución mientras hace otras cosas en el entorno de shell. Al introducir M-!, emacs solicita una línea de comando para ejecutar y espera hasta que se completa el comando; luego restaura la pantalla y reanuda su ejecución. Puede solicitar un shell interactivo para ejecutar con: carcasa mx Cuando sale del shell, emacs reanuda la actividad. El comando M-: (meta - tubería), seguido de una línea de comando, usa el texto entre la marca y el cursor como entrada estándar para el comando; el búfer permanece sin cambios. También puede ingresar la salida de un comando de shell en el búfer actual y reemplazar la región actual, con AuM-:, seguida de una línea de comando. 5.5 Perspectivas En un entorno UNIX la operación de edición es muy compleja. Cubriremos algunas características especiales en esta sección, antes de pasar a la discusión de las expresiones regulares en el próximo capítulo. NOTAS SOBRE EL ENTORNO DEL SISTEMA X WINDOW Las figuras 5.1 y 5.2 están tomadas de un VDT ​​que funciona con el sistema X Window. En la configuración básica de X, la pantalla tendrá barras de desplazamiento, o scroll bars, como se muestra a la derecha de las Figuras 5.1 y 5.2. Sin embargo, los editores vi y emacs no están implementados de manera que aprovechen al máximo las barras de desplazamiento, que son manejadas por el sistema X Window en lugar de por los editores. Como resultado de esto, puede mover los contenidos de la pantalla manipulando las barras (como se explica en el Capítulo 23), pero estos movimientos no tendrán influencia en la línea actual utilizada por los editores. En la práctica, cuando cambia la ubicación de desplazamiento en la barra de herramientas y luego ingresa un carácter para el editor, X volverá a mostrar la pantalla en la línea actual utilizada por el editor. Las barras se utilizan mejor para copiar una región de texto en la posición actual del editor. Para lograr esto en vi, ingrese el modo de texto en el punto donde desea copiar el material, mueva el control deslizante para mostrar el texto deseado, luego ejecute la copia a través de X Tools. Si está en modo texto correctamente en el editor, X insertará el material en la posición actual y la pantalla se actualizará. Por las mismas razones que las anteriores, no puede cambiar el tamaño de una ventana X mientras se está ejecutando cualquier editor; si lo hace, los editores no se ajustarán al nuevo tamaño y la información en pantalla será ilegible. El procedimiento adecuado para cambiar el tamaño de la ventana debe realizarse antes de iniciar un editor, para que el editor pueda ajustarse correctamente al nuevo tamaño de la ventana. LAS OPCIONES DE vi El editor vi tiene muchas opciones que alteran su comportamiento habitual y que puedes especificar de dos formas. El comando :set, cubierto anteriormente cuando hablamos sobre :set showmode, es un ejemplo de cómo usar casi 50 opciones, más showmode. Todas las opciones disponibles se pueden ver desde el comando :establecer todos Cuando desee cambiar una opción, especifique el nombre de la opción después del comando :set para activarla y preceda su nombre con no para desactivarla. estos comandos :establecer modo de presentación :establecer modo noshow activar y desactivar respectivamente la opción showmode. Algunas de las opciones toman un argumento, como el caso de :establecer ventana = 1O que establece el tamaño de la ventana lógica en diez líneas de alto. Puede experimentar con las opciones de vi en su terminal para adquirir experiencia sobre cómo personalizar el editor según sus preferencias personales o las necesidades de su terminal. Algunas de las opciones más utilizadas son la opción concisa, para mostrar mensajes de error más concisos de lo habitual, autoindent, para sangrar una línea en la misma columna inicial que la anterior, y number, para mostrar la numeración de líneas del archivo. La opción de tabulador cambia el número de posiciones que se mueve el cursor después de presionar la tecla TAB, mientras que la opción de ignorar mayúsculas y minúsculas desactiva los caracteres en minúsculas y mayúsculas durante las operaciones de búsqueda de cadenas con expresiones regulares. Hay muchas otras opciones disponibles. Las opciones activadas con la línea de comando :set son válidas solo para la sesión de edición actual; cuando sale del editor vi con :q, las opciones se pierden y debe reiniciarlas la próxima vez que se ejecute vi. Sin embargo, existen dos mecanismos en el entorno vi que le permiten mantener las opciones permanentemente activas, de modo que cuando inicia vi, el editor mismo se configura de acuerdo con sus instrucciones. Primero, la variable de entorno EXIN TI puede almacenar el comando set, que se ejecuta cuando ejecuta vi. Por ejemplo, este comando $EXINIT ='establecer numero tabstop = 4 ignorecase' ; exportar EXINIT configure vi con el número de opciones, ignorecase y tabulado inicializado en cuatro espacios. Normalmente, asignará el valor deseado a la variable de entorno EXINIT en su archivo .profile, que activa las opciones especificadas cada vez que inicia sesión en el sistema. En segundo lugar, puede colocar estos comandos en un archivo llamado .exrc (ex ejecutar comandos), ubicado en el directorio INICIO, que los lee e interpreta cuando se ejecuta. El comando map permite otra forma de usar la variable EXINIT y el archivo .exrc. Puede usar este comando para vincular cada tecla a una función vi o un conjunto de funciones, configurando así un entorno vi en el que puede realizar acciones complejas con solo unas pocas pulsaciones de teclas. Desafortunadamente, esta función utiliza un lenguaje de programación oscuro y difícil, por lo que es útil principalmente para los expertos en vi. FILTROS DE TEXTO EN EL ENTORNO vi Puede agregar la salida estándar de cualquier comando a su búfer actual escribiendo: :r !comando Esto lee y devuelve la salida estándar del comando a su archivo en la línea actual. Del mismo modo, este comando :w !comando devuelve el archivo al comando de entrada estándar. También puede filtrar una parte del archivo actual a través de una canalización, escribiendo: :3,56 !comando Este comando redirige las líneas de la línea 3 a la línea 56 a la entrada de comando estándar, elimina las líneas del búfer y las sustituye por la salida de comando estándar. Una sencilla herramienta de formato fmt le permite agrupar líneas cortas de texto en líneas de longitud razonable, por ejemplo: :1,$ !fmt Puede verificar su comportamiento con un archivo de prueba. MODOS PRINCIPALES EN emacs El editor de emacs tiene varios modos principales independientes que permiten el manejo eficiente de varios tipos de texto; hay modos específicos para programas C, para documentos fuente troff, programas LISP y muchos otros. Por lo general, emacs infiere qué tipo de archivo está tratando a partir del nombre del archivo y configura los modos apropiados; la sangría, el anidamiento, la división de líneas y otras funciones cambian su comportamiento según el modo actual. La lista exacta de modos disponibles depende tanto de la versión de emacs que esté usando como de la personalización del editor para su instalación; consulte a su experto local en emacs sobre qué modos están disponibles. Los expertos encuentran muy conveniente la configuración del modo automático, pero los principiantes pueden confundirse. Puede obligar a emacs a usar un modo particular para tratar un archivo insertando una cadena de comando de modo en la primera línea del archivo. El comando de modo debe ir precedido y seguido por la cadena -* - (guión, asterisco, guión), de la siguiente manera: -*- nroff -*- Esta línea proporciona una forma adecuada de editar documentos de origen nroff. La cadena puede aparecer en cualquier parte de la primera línea del archivo; luego puede incluirlo como un comentario en el idioma de origen del archivo: \" -•- nroff -•- MODOS MENORES EN emacs El editor de emacs también tiene modos menores, que se utilizan para configurar varias opciones y preferencias. El comando M-x selecciona un modo; puede ingresar un nombre de modo después del comando, y ese modo se activará o desactivará. Cubrimos aquí solo algunas de las formas más importantes; tenga en cuenta que los nombres de los modos varían mucho de un sistema a otro (consulte a su experto en emacs si necesita más información). save mode configura emacs para guardar automáticamente el contenido del búfer en el disco después de alcanzar un número mínimo de caracteres especificado por el modo savetype. El archivo guardado tiene un nombre diferente al del archivo original, por lo que no tiene que preocuparse de que emacs sobrescriba automáticamente su archivo después de cometer un error; si su archivo se llama archivo, el archivo guardado se llamará #archivo#. Active el modo de conexión automática si desea utilizar la función de ajuste automático: el editor de emacs agrega una nueva línea cuando ajusta más caracteres que fillcol en una línea; con este modo activo, emacs divide inteligentemente la línea al final de las palabras. El modo de sobrescritura hace que los caracteres existentes en el archivo, desde la posición del cursor, se sobrescriban y reemplacen con caracteres ordinarios que normalmente se ingresarían en el archivo; este modo se utiliza para cambiar un archivo existente más rápidamente. El modo de número fijo activa o desactiva la numeración de líneas. Los modos de alto y ancho le permiten especificar las dimensiones de la ventana de video; es útil para el sistema X Window. Hay muchas otras formas de realizar eso difieren en las distintas versiones de emacs. ARCHIVO DE PERSONALIZACIÓN emacs Cuando se inicia emacs, lee el archivo .emacs en su directorio HOME; este archivo contiene un conjunto de secuencias de caracteres, ya que también se pueden ingresar desde el teclado. El programa ejecuta estos comandos antes de acceder al video y pasar el control al usuario; puede usar el archivo .emacs para personalizar los modos y el entorno de emacs. MACROS EN Emacs El editor de emacs tiene excelentes herramientas de extensión y personalización: macros compuestas por una serie de comandos normales de emacs, que a su vez pueden contener llamadas a otras macros predefinidas. Muchas versiones comerciales de emacs incluyen muchas macros, que van desde el corrector ortográfico automático hasta herramientas que reasignan el teclado para terminales específicas. Son posibles extensiones casi ilimitadas del sistema emacs; algunos "asistentes" de emacs inician sesiones enteras desde el editor, usando herramientas tan personales que el shell normal y los comandos apenas son visibles. Consulte la documentación de su versión particular de emacs si desea crear y usar macros. MACROS DE TECLADO Una forma de macro, la macro de teclado, es muy fácil de crear y usar; le permite configurar una secuencia de teclas, que puede nombrar como una macro. Cuando usa ese nombre, emacs ejecuta la secuencia completa almacenada como una macro; esto es muy conveniente cuando tiene que realizar acciones repetitivas en una sesión de edición. Para comenzar a almacenar una pulsación de tecla como una macro, use el comando: (CTRL-x abrir paréntesis). Todos los caracteres introducidos hasta el final del almacenamiento: (cTRL-x paréntesis de cierre) se almacenan como parte de la macro. Tenga en cuenta que los caracteres que escribe se reproducen almacenados en la macro durante la entrada. Después de completar una definición de macro, puede ejecutarla con "xe (ejecutar); este comando solo puede ejecutar la última macro definida. Si desea tener más de una macro de teclado definida simultáneamente, debe nombrar las macros, por ejemplo: A x teclado-macro-nombre Las macros de teclado se pierden cuando sale de emacs, a menos que sus definiciones estén incluidas en el archivo .emacs. Otra característica útil de emacs son los mapas de teclas; puede "reenlazar" su teclado para reajustar casi todas las teclas utilizadas para los comandos. Muchos usuarios realizan grandes cambios en el mapeo de teclas en sus archivos .emacs según sus preferencias. Consulte la documentación de su versión de emacs para aprender a configurar mapas de teclas. ======================================================================== Capítulo 6 Expresiones regulares y procesamiento de textos 6.1 Conceptos básicos de expresiones regulares 6.2 El comando grep 6.3 Los comandos fgrep y egrep 6.4 Búsquedas de expresiones regulares en vi 6.5 Sustituciones en vi 6.6 El editor sed 6.7 El editor ed 6.8 Perspectivas En el sistema UNIX, el procesamiento de texto se basa en el concepto de expresión regular, una descripción formal de cadenas de texto que permite potentes operaciones de comparación de cadenas. Las operaciones I y ? de las herramientas de búsqueda en vi son mucho más poderosas y flexibles que las que se mostraron en el capítulo anterior. Usando expresiones regulares en vi, puede buscar eficientemente muchas cadenas diferentes con el mismo comando y hacer coincidir cada una. También puede realizar operaciones complejas de búsqueda y reemplazo de cadenas con expresiones regulares. Las expresiones regulares están permitidas no solo en vi, sino también en todos los demás editores estándar, y también en el shell. Puede pensar en los metacaracteres de shell como una forma simplificada de las expresiones regulares discutidas aquí. Desafortunadamente, la sintaxis de expresiones regulares en shell no es idéntica a la forma utilizada en vi; incluso los usuarios experimentados pueden confundirse. En este capítulo, presentamos el concepto de expresiones regulares, analizamos los comandos que las tratan directamente y luego regresamos a vi y otros editores para ilustrar cómo las expresiones regulares pueden mejorar sus características. 6.1 Conceptos básicos de expresiones regulares En vi, siempre que utilice la notación /cadena para buscar una cadena coincidente, puede reemplazar el término cadena con una expresión regular. En realidad, la cadena de caracteres es la forma menos compleja de una expresión regular. REPRESENTACIÓN DE UN PERSONAJE Una expresión regular consta de una secuencia de operadores que identifican los caracteres individuales que deben coincidir. Para cada carácter dentro de una cadena, se puede usar una expresión para representarlo. El caracter . (punto), por ejemplo, es uno de los operadores más utilizados en expresiones regulares y reemplaza un carácter solo. La expresión regular a.e coincide con todas las cadenas que comienzan con la letra a, terminan con la letra e y contienen cualquier carácter dentro. Por lo tanto, esta expresión regular coincide con la cadena ade, así como con a# e o aSe, pero no con la cadena abdc, que incluye dos caracteres entre una # c. En este caso, debe usar las expresiones regulares a ..c, a ... o ..... sin embargo, las dos últimas también coinciden con muchas otras cadenas que probablemente no le interesen. Cuando se utilizan expresiones regulares, es importante especificar exactamente el conjunto de cadenas que deben coincidir y no otras. REPRESENTACIÓN DE UN CONJUNTO DE CARACTERES Los operadores [y] (corchetes de apertura y cierre) representan un conjunto de caracteres, cada uno de los cuales puede considerarse la cadena que se debe buscar. La expresion [a B C] representa cualquiera de los caracteres a, b o e, mientras que la siguiente expresión regular [Automóvil club británico] es igual a la letra a minúscula o mayúscula. Este tipo de expresión, es decir, un conjunto de caracteres entre corchetes, identifica un solo carácter en el archivo de búsqueda y, para componer una cadena de varios caracteres, es suficiente asociar un número de expresiones regulares igual al número de caracteres que forman arriba de la cuerda. Por ejemplo, la expresión [aA][bB] coincide con cualquiera de las cadenas ab, aB, Ab o AB, pero no con BA. Dado que cada secuencia de caracteres entre corchetes corresponde a un solo carácter, la construcción anterior representa una cadena de dos caracteres. En un comando de búsqueda de cadena en ed, la siguiente línea de comando /[aA][bB] busca la primera aparición de una de las cuatro posibles cadenas coincidentes. Puede definir expresiones regulares de cualquier nivel de complejidad, pero no olvide que cada secuencia de caracteres entre corchetes coincide con un solo carácter. REPRESENTACIÓN DE UNA SERIE DE CARACTERES El operador de corchetes puede hacer coincidir la expresión regular con un carácter que pertenece a un conjunto de caracteres ordenados alfabética o numéricamente. Por ejemplo, para hacer referencia a todas las apariciones de números en un archivo, podría escribir: [0123456789) Una forma más contraída es la siguiente: [0-9) El carácter - (menos) identifica, si se usa dentro del par de corchetes, un conjunto de caracteres. Para hacer referencia a cualquier carácter alfabético, en mayúsculas o minúsculas, puede utilizar la siguiente expresión: [A-Za-z] PROTECCIÓN DE OPERADORES DE EXPRESIÓN REGULAR Para hacer referencia directa al operador especial [, evitando que vi lo interprete como el comienzo de una expresión regular, debe precederlo con el carácter "\" (barra invertida). Por ejemplo, /\ [ De esta forma encuentra la primera presencia del personaje [en el búfer. Debe proteger cada operador de expresión regular de esta manera para evitar interpretaciones especiales. SÍMBOLOS ESPECIALES DE INICIO Y FIN DE LÍNEA Puede anclar su expresión regular al principio o al final de una línea para especificar el carácter que debe aparecer al principio o al final de la línea. Use un carácter ^ para indicar el comienzo de la línea y un carácter $ para el final de la línea. Por ejemplo: /^Palabra identifica la cadena Word solo si aparece al principio de una línea. Como, /palabra$ coincide con Word solo si va seguido directamente de una nueva línea. Para evitar los significados especiales de estos caracteres y para identificar los caracteres "^" y "$" literalmente, debe, como en otros casos, protegerlos con el carácter "\". Por ejemplo: /\$25 identifica la cadena $25. Tenga en cuenta que dado que las expresiones regulares no extienden su efecto a través de varias líneas, expresiones como las siguientes: /hola^adiós /hola$adiós son reconocidos por vi como sin sentido, y los caracteres ^ y $ se tratan como caracteres normales en lugar de caracteres especiales de inicio o fin de línea. CONSTRUCCIÓN DE EXPRESIONES REGULARES COMPLEJAS Las expresiones regulares que hacen referencia a un solo carácter se pueden combinar para construir cadenas más largas, como se muestra a continuación: /[O-9](0-9](0-9) Este comando encuentra la primera secuencia de tres dígitos numéricos. Puede agregar el operador * (asterisco) para indicar cero o más ocurrencias de la expresión regular anterior. Por ejemplo, para encontrar una secuencia de dígitos de cualquier longitud, podrías escribir: /[O-9)[0-9]* Dado que el carácter * indica cero o más ocurrencias de la cadena, el siguiente comando /[0-9]* identifica el inicio de cada línea y no obtiene el resultado solicitado. En cambio, un número primo [O-9] requiere que aparezca al menos un dígito en la cadena antes de los dígitos opcionales. En cambio, el siguiente comando identifica una línea completa del archivo: /^.*$ Esto se puede leer de la siguiente manera: comenzando al principio de la línea (^) considera cada carácter (.), repetido cualquier número de veces (*), hasta encontrar el final de la línea ($). A continuación, puede definir expresiones regulares de cualquier complejidad utilizando esta técnica de composición de bloques. LA CADENA MÁS ALTA IDENTIFICADA Una regla importante a tener en cuenta es que las expresiones regulares coinciden con la cadena más larga posible. Supongamos que tiene la siguiente cadena. abc1234def y usar el comando /[0-9)[0-9)* La expresión identifica todos los dígitos 1234, ya que la notación [0-9]* identifica todos los dígitos contenidos en la cadena en cuestión. 6.2 El comando grep El sistema UNIX tiene un programa de filtro que escanea un archivo en busca de cadenas especificadas como expresiones regulares. Este es el comando grep (expresión regular global e impresión) que lee el estándar de colocación o una lista de archivos especificados como argumento y devuelve a la salida estándar todas las líneas que contienen la cadena especificada como primer argumento. Por ejemplo, esta línea de comando $ grep un archivo_string busque a_string en el archivo. Tenga en cuenta que una_cadena puede ser cualquier expresión regular y que, en su forma más simple, la expresión regular puede ser una simple secuencia de caracteres. $ grep amigos old.file Hola gente ps Cada línea del archivo que contiene la cadena especificada en el comando grep se envía a la salida estándar. Puede usar cualquier expresión regular para hacer coincidir una cadena, por ejemplo: $ grep "^[a-z)12" otro.archivo La línea anterior coincide con cualquier línea que comience con una letra minúscula y tenga los dígitos 1 y 2 como segundo tercer carácter Delimite la expresión regular de búsqueda entre comillas para evitar que el shell interprete los caracteres de corchetes antes de grep. El programa grep también puede seleccionar cualquier línea del archivo que no contenga la cadena especificada como argumento, siempre que aparezca la opción -v en la línea de comando. El siguiente ejemplo: Y $ grep -v amigos viejo.archivo otra línea una tercera línea ps muestra cada línea de old.file que no contiene la cadena people. El comando grep tiene muchas otras opciones: por ejemplo, la opción -e (recuento) produce solo el número de líneas que contienen la cadena dada, como podría lograrse con una canalización entre la salida de grep y el comando wc - 1; la opción -n (número) agrega a la salida producida el número que ocupa la línea en el archivo fuente, mientras que la opción -i (ignorar) ignora la distinción entre letras mayúsculas y minúsculas al buscar cadenas. Uno de los usos más importantes de grep es buscar una cadena en particular en varios archivos. Si tiene muchos archivos en un directorio y no puede recordar qué archivo contiene qué material, grep o dell y sus variantes resuelven tu problema. Si incluye más de un nombre de archivo en una lista de argumentos para grep, el nombre del archivo al que pertenece la línea se indica al principio de cada línea de salida: $ grep un * file.test1: otra línea file.test2: una tercera línea ps De esta forma podrás conocer de inmediato el archivo que te interesa. 6.3 Los comandos fgrep y egrep Hay otras dos versiones del comando grep que optimizan las operaciones de búsqueda en algunos casos especiales. El comando fgrep (grep fijo) acepta, en lugar de una expresión regular, solo una cadena fija como elemento de búsqueda; El comando egrep (grep extendido) define un conjunto más completo de operadores de expresiones regulares que el comando grep y es una versión optimizada para búsquedas más complejas, pero más lenta que grep. En la mayoría de los casos, la versión original de grep es un buen compromiso entre las diferentes necesidades de investigación. El comando egrep acepta operadores de expresiones regulares adicionales que difieren ligeramente de los operadores grep. Además del operador *, que se usa para indicar cero o más ocurrencias de una construcción de un solo carácter, egrep también proporciona el operador + (más) para especificar una o más ocurrencias de un carácter. Por ejemplo, si usa el comando grep, puede escribir [0-9)(0-9]* para denotar una secuencia de dígitos de cualquier longitud. El mismo resultado también se obtiene con egrep, pero en este caso también puedes escribir [0-9]+ Del mismo modo, el operador ? (signo de interrogación) indica cero o una aparición del constructo. En egrep, el operador | (tubería) indica una de dos expresiones regulares. Por ejemplo, este comando A[0-9]?a|b hace referencia a una línea que comienza con un dígito opcional y tiene la letra a o b como segundo carácter. Como otro ejemplo, ^a|b hace referencia a una línea que comienza con a o b. El comando egrep también usa el operador de paréntesis para agrupar expresiones regulares de varios caracteres. Por ejemplo $ egrep archivo "([0-9]+ab)*1234" busca cualquier cadena que contenga de forma recursiva una construcción que comience con una secuencia de uno o más dígitos, seguida de ab, y continúe con una secuencia de uno o más dígitos, seguida de ab, etc., hasta que la cadena 1234 coincida. En la línea de comando también está la opción -f nombre.archivo (f significa archivo) que en egrep le permite especificar la expresión regular a través del archivo especificado en la opción, simplificando así la misma línea de comando, mientras que en fgrep el archivo contiene la lista de cadenas para buscar. El comando grep, o su tipo, se usa ampliamente como una herramienta rápida y poderosa para buscar cadenas de caracteres en un archivo de texto. Cuando lo use, intente especificar la expresión regular más precisa que satisfaga sus necesidades, ya que el comando grep puede generar resultados enormes si los términos de búsqueda se especifican de manera demasiado amplia. 6.4 Búsquedas de expresiones regulares en vi Los operadores de búsqueda de última línea I y ? le permiten especificar la cadena de búsqueda con cualquier expresión regular; una cadena particular de caracteres no es más que una forma simplificada de una expresión regular. Cuando use un editor, intente usar expresiones regulares; cuanto más aprenda cómo funcionan, más rápidas y eficientes serán sus operaciones. 6.5 Sustituciones en vi Puede realizar operaciones sofisticadas de búsqueda y reemplazo en cadenas, utilizando expresiones regulares para definir las coincidencias que desea identificar. La operación de última línea :s (sustituir) le permite especificar una expresión regular para la búsqueda y una nueva cadena para reemplazar la cadena coincidente. Después de :s, ingrese el delimitador /, la expresión regular a eliminar, otra /, finalmente la nueva cadena de reemplazo, como se muestra a continuación: :s/potente/flexible Esto reemplaza la nueva cadena, flexible, en la primera aparición de la cadena (o expresión regular}, poderosa, en la línea actual. La primera parte del comando de reemplazo se puede especificar como cualquier que expresión regular, la segunda parte debe ser precisa cadena para insertar en lugar de la expresión regular. El comando anterior reemplaza solo la primera aparición de la expresión regular en la línea actual, incluso si la posición del cursor está después de la cadena identificada; Los comandos de reemplazo afectan a toda la línea actual, independientemente de la posición actual del cursor en la línea. Para reemplazar todas las apariciones de la expresión regular en la línea actual, debe agregar una I final al comando, seguida de g (global}, como en el siguiente ejemplo: :s/antiguo.re/nuevacadena/g Este comando busca y reemplaza todas las apariciones en la línea actual . Puede eliminar una cadena con este comando, simplemente especificando una cadena vacía como reemplazo, como se muestra aquí: :s/el// La terminación I no es obligatoria, pero puede usarla para mayor claridad. Puede usar los operadores especiales - y $ en expresiones regulares para designar el principio o el final de la línea. Para agregar una cadena al final de una línea, puede usar el comando: :s/$/nuevo texto al final Para agregar una cadena al comienzo de una línea, use el comando: :stl nuevo texto al principio No se requiere una / final a menos que necesite agregar una g. SUSTITUCIONES UTILIZANDO LA CADENA IDENTIFICADA A veces puede ser necesario indicar una cadena en la sección de búsqueda del comando :s, sin tener que reemplazarla; por ejemplo, si necesita agregar una palabra a una cadena de dígitos, no puede usar: :s/[O-9][0-9)*/nueva_cadena porque la cadena new_string elimina y reemplaza la secuencia de dígitos, mientras que usted quería agregarla. El operador especial&, utilizado en la sección de reemplazo, le permite referirse a la cadena identificada con la sección de búsqueda. Por ejemplo, dada la cadena abc1234def y el comando :s/[O-9][0-9]*/&nueva_cadena El resultado será: abc1234new_stringdef El operador & reemplazó la cadena identificada en la línea de salida. Como de costumbre, puede incluir un & real en su salida, protegiéndolo con \. SUSTITUCIONES DENTRO DE UN GRUPO DE LÍNEAS Normalmente, el comando :s cambia solo la primera aparición de una cadena en la línea actual; puede especificar un rango de líneas dentro de las cuales desea que tenga lugar la misma acción, con los números de línea inicial y final después de :. Por ejemplo: :3.7s/antiguo/nuevo Esto reemplaza la primera aparición de la cadena antigua con la nueva cadena nueva en las líneas 3 a 7; para reemplazar todas las apariciones de la expresión regular en las mismas líneas, debe agregar la g final, por ejemplo: :3.7s/antiguo/nuevo/g Para reemplazar todas las ocurrencias de una cadena en el archivo, use :1,$s/viejo/nuevo/g Aquí, el $ se interpreta como la última línea del archivo. Tenga en cuenta los dos significados diferentes de $ en vi: uno, dentro de una expresión regular indica el final de la línea; el otro, como dirección de línea indica la última línea del archivo. Incluso el. tiene dos significados: significa cualquier carácter cuando se usa en una expresión regular, mientras que significa la línea actual cuando se usa en una dirección de línea. DIRECCIONES DE LÍNEA También puede operar en una sola línea, en lugar de un alcance de líneas, especificando un solo número de línea, por ejemplo: :34s/antiguo/nuevo Esto reemplaza la cadena especificada en la línea 34 del archivo únicamente. También puede usar números de línea lógicos, por ejemplo: :.s/viejo/nuevo que reemplaza en la línea actual e :$s/viejo/nuevo que reemplaza en la última línea del archivo. También se permiten expresiones aritméticas simples; puede especificar un ámbito de líneas antes y después de la línea actual proporcionando una dirección relativa, por ejemplo: :. -4,.+6s/antiguo/nuevo Esto realiza la sustitución en un rango de 11 líneas, comenzando 4 líneas antes de la línea actual y terminando 6 líneas después de la actual. También puede usar el $ en estos cálculos, por ejemplo: :. -4.$-2s/viejo/nuevo Si hay algún error en estas expresiones aritméticas, te avisa si el resultado no es una dirección válida, por ejemplo: :.,$ + 2s/viejo/nuevo No hay tantas líneas en el búfer Utilice estas expresiones aritméticas con precaución, porque un resultado legal aún puede no ser lógicamente correcto para sus propósitos, y estos operadores de sustitución no solicitan confirmación antes de actuar. DIRECCIONES POR CONTEXTO CON EXPRESIONES REGULARES El $ como dirección es un ejemplo de una dirección por contexto. Además de enrutar por números de línea (no es demasiado fácil, ya que vi no muestra los números de línea de forma predeterminada), puede especificar líneas con una expresión regular; vi encuentra la primera línea que coincide con la expresión regular y la trata como la línea direccionada. Por ejemplo, puede reemplazar la primera aparición de una cadena después de la línea actual con: :/antiguo/s//nuevo En este caso, vi trata la primera expresión regular como un operador de búsqueda, coloca la línea actual en la línea donde encuentra la primera coincidencia y luego realiza el reemplazo. También puede buscar hacia atrás, por ejemplo: :?antiguo?s//nuevo Tenga en cuenta que cuando existe una expresión regular actual, como la definida aquí con /old/, la reutiliza hasta que se define una nueva. Por esta razón, el comando de los ejemplos anteriores no necesita una expresión regular en la parte de búsqueda; la expresión actual antigua se asume por defecto. Por supuesto, si la cadena a reemplazar no coincide con la expresión regular actual, debe especificarla. Por ejemplo, para encontrar la primera línea que contiene old y en esa línea reemplazar la cadena nice, haga tienes que usar :/viejo/s/hola/adiós Después de esta operación, la expresión regular actual es hermosa, en lugar de antigua como en los otros ejemplos. También puede definir el ámbito de las direcciones utilizando el formato de expresión regular, por ejemplo: :/hola/,/adios/s/viejo/nuevo/ En este caso, busca vi desde la línea actual hasta que encuentra una coincidencia para la cadena bello, luego realiza sustituciones hasta que encuentra una línea que contiene adiós. Esta forma de direccionamiento es más difícil de controlar que los números de línea; sin embargo, refleja la noción de que en los sistemas UNIX todo el procesamiento de edición se puede realizar sin numeración de línea; por esta razón, a menudo se hace referencia a vi como un editor de contexto. 6.6 El editor sed El comando sed (editor de flujo) tiene algunas características de vi en modo de última línea, y algunas de grep; si bien es un programa de filtro como grep, permite al usuario realizar cambios en los archivos. El comando sed no es interactivo como vi, sino que lee el archivo de entrada línea por línea y envía las líneas una por una a la salida estándar. En cada línea leída, sed aplica una operación de reemplazo de la forma de la utilizada por vi en el modo de última línea; si el resultado de la búsqueda es positivo, se produce la sustitución y la línea se escribe modificada; de lo contrario, la línea se escribe sin cambios. Una gran ventaja de sed sobre vi u otros editores es que las líneas se leen, modifican y escriben una por una; dado que no hay un búfer de memoria interna para todo el archivo, sed puede editar archivos de cualquier longitud, incluso aquellos que son demasiado grandes para vi u otros editores. El comando sed es muy útil para manejar archivos de más de un megabyte. La mayoría de los editores de texto no pueden manejar archivos de este tamaño, generalmente está limitado a 256 000 bytes. Puede ejecutar el comando sed de la misma manera que ejecuta el comando grep, aunque no puede usar el operador de sustitución global. Este comando $ sed "s/hola/hola/" en.archivo reemplaza la primera instancia de hola en cada línea del archivo in.file con la cadena hola y vuelve a escribir la línea actualizada en la salida estándar. $ echo "1234hola5678" : sed "s/hola/hola/" 1234hola5678 ps Delimite el comando replace entre comillas para protegerlo de las interpretaciones de shell. Como de costumbre, la cadena de búsqueda puede ser una expresión regular. El comando sed tiene muchas otras funciones. Por ejemplo, el siguiente comando puede eliminar todas las líneas que contengan la cadena hola: $ sed "/hola/d" en.archivo En este ejemplo, el comando busca en el archivo in.file la cadena hola y, si la encuentra, elimina la línea que la contiene. El mismo resultado se obtiene con $ grep - v guardar en.archivo Para eliminar solo la cadena salve de la línea, sin eliminar la línea por completo, puede usar esta forma alternativa: $ sed "s/hola//" en.archivo Al igual que vi, el programa sed también acepta una dirección de línea o un conjunto de direcciones si desea limitar la búsqueda a solo una parte de un archivo. Este comando sed "3.7s/hola//" en.archivo elimina la primera instancia de salvo entre las líneas 3 y 7 del archivo y deja el resto de la línea sin cambios. También puede usar una dirección de contexto en lugar de un número de línea. sed "/hola/,/hola/s/malo/bueno/g" en.archivo Este comando busca la primera instancia de la cadena hola, cambia todas las instancias de la cadena malas a buenas, hasta que encuentra la cadena hola o finaliza el archivo. En este ejemplo, si existe otra instancia de hola después del encuentro de hola, la sustitución comienza nuevamente hasta la siguiente instancia de hola. PROGRAMAS SED COMPLEJOS De hecho, sed es incluso más eficiente que todo lo que hemos descrito hasta ahora. Si coloca el comando en un archivo en lugar de en una línea de comando, puede especificar la opción -f en la línea de comando sed. $ sed - f comando.archivo a.archivo En este comando, los operadores de expresiones regulares se almacenan en el archivo command.file, mientras que, si no usa esta notación, sed funciona de la forma habitual. Con un solo comando, como se indica en los ejemplos anteriores, el uso del archivo de comandos no da como resultado una mejora drástica en la eficiencia, aunque las expresiones regulares complejas a veces se pueden corregir más fácilmente si se almacenan permanentemente en un archivo. Sin embargo, el archivo de comando tiene una función más importante: puede definir la entrada de varias líneas para sed, de modo que se pueda realizar una serie de operaciones en cada línea de entrada antes de que sed la envíe. Por ejemplo, puede crear un archivo llamado command.file que contenga la siguiente lista de comandos: s/hola/hola/ s/hola a todos/noche/ Ahora, si corres $ echo "1234hola5678" | sed -f comando.archivo la salida se convierte 1234nocheparatodos5 confirmación de sus intenciones. Si presiona q nuevamente, y termina sin volver a colocar los cambios que indicó en el archivo. TRATAMIENTO DE LÍNEAS DE TEXTO Muchas operaciones en modo comando involucran líneas individuales en un archivo de texto. Puede moverse dentro de un archivo saltando de una línea a otra, pero la mayoría de los comandos actúan en la línea actual. En el modo de comando, la línea actual se indica con el carácter. (punto), mientras que la última línea del archivo está marcada con el carácter $(dólar). En el entorno UNIX, a la hora de escribir texto, es raro tener disponible la numeración de líneas, y para tenerla hay que solicitarla expresamente a ed, que lleva un registro de la línea actual en todo momento. PANTALLA DE LÍNEA ACTUAL Para mostrar la línea actual, use el comando p (imprimir) presionando la tecla p (minúsculas), a diferencia del comando de solicitud que se inicia presionando la tecla P (mayúsculas). $ed antiguo.archivo 260 pag hasta luego ......... jorge Cuando lee un archivo en ed, la línea actual es la última línea del archivo. $ed antiguo.archivo 260 pag hasta luego ......... jorge 6 $= 6 El operador = (igual) permite conocer el número de una línea, en particular la notación. = devuelve el número de la línea actual, mientras que $ = muestra el número de la última línea del archivo. En este ejemplo, el archivo tiene seis líneas. La mayoría de los comandos ed operan en una línea o conjunto de líneas que preceden al comando mismo. Si no indica explícitamente el alcance del comando, se asume que es la línea actual. En lugar del comando p, puede escribir .p, $p o 6p. Dado que los caracteres de punto y dólar tienen el mismo significado en este ejemplo (ambos indican la línea 6), las tres especificaciones del comando p son idénticas. Para hacer referencia a un conjunto de líneas, especifique el primer y último número de línea, separados por una coma, como en el modo de última línea vi. $ed antiguo.archivo 260 1.2p HOLA. León, ¿qué estás haciendo? estudié duro el sistema UNIX y debo informarles que lo he encontrado El número de la primera línea debe ser menor que el segundo. También puede usar caracteres de punto o dólar en estas rutas de línea. $ed antiguo.archivo 260 3,$p divertido. El sistema operativo UNIX parece ser mucho más poderoso que cualquier otro sistema operativo para computadoras pequeñas y estoy seguro que es de gran ayuda en la solución de sus problemas. hasta luego ......... jorge De manera similar, puede usar expresiones aritméticas simples en enrutamientos de línea. $-2,$p que cualquier otro sistema operativo para computadoras pequeñas y estoy seguro que es de gran ayuda en la solución de sus problemas. hasta luego. ....... Jorge Para visualizar el expediente completo, puede utilizar el formulario contratado, pág. CAMBIO DE LÍNEA ACTUAL También puede cambiar la línea actual mientras opera en modo comando. El carácter de nueva línea lo hace avanzar una línea, mostrando el contenido de la línea actual, mientras que el comando - (menos) seguido de un retorno de carro lo hace retroceder una línea. También puede hacer referencia directamente a una línea, que toma e como la línea actual. .= 6 2 el sistema UNIX y debo informarles que lo he encontrado .= 2 La línea actual se convierte en la línea 2 que muestra ed. También se permite el uso de expresiones aritméticas simples. MODO INSERCIÓN Cuando cambia del modo de comando al modo de inserción, puede ir a una línea que precede o sigue a la actual, según la opción que especifique. De hecho, use el comando i (entrada) para ingresar al modo de inserción antes de la línea actual y el comando a (agregar) para activar el modo de inserción después de la línea actual. Cuando está en el modo de inserción, el indicador no aparece y todos los caracteres que escriba se insertarán en el archivo. Para volver al modo de comando después de terminar de escribir, escriba el carácter de punto en una línea. $ed nuevo.archivo ?archivo nuevo a Hola gente otra linea una tercera línea . ,pag Hola gente otra linea una tercera línea Si está en el modo de inserción y no escribe un carácter de punto en una línea, puede insertar cualquier número de líneas. Para corregir una línea que contiene un error, debe volver al modo comando y realizar los cambios necesarios, como se indica en los siguientes párrafos. Los comandos iy a también pueden estar precedidos por direcciones de línea: 14a hace que e agregue las siguientes 14 líneas al archivo. ELIMINACIÓN DE LÍNEAS El comando d (eliminar) elimina una o más líneas del archivo. Si no especifica ninguna opción, d elimina la línea actual. ,pag Hola gente otra linea una tercera línea 2 otra linea d ,pag Hola gente una tercera línea Esto elimina del búfer la línea 2. El comando d también puede eliminar un conjunto de líneas. CANCELACIÓN DE ERRORES El programa mma ed recuerda el último comando que ingresó, por lo que solo puede deshacer el último cambio que realizó en el archivo, como en vi. El comando u (deshacer) restaura el contenido del búfer, como se muestra en este ejemplo: ,pag Hola gente una tercera línea tu ,pag Hola gente otra linea una tercera línea Si vuelve a escribir u, la línea deshecha se borra nuevamente, ya que la operación de deshacer con u fue el último cambio que realizó. ,pag Hola gente otra linea una tercera línea tu ,pag Hola gente una tercera línea De esta manera, puede realizar muchos cambios, incluso si el comando u solo rehace la última operación que realizó. BUSCAR CADENAS Como sede de vi, ed admite operaciones completas de búsqueda y reemplazo de expresiones regulares. Usando el operador de búsqueda I (barra oblicua), el programa ed puede seleccionar cualquier secuencia de caracteres presente en una línea, por ejemplo: /cadena Comenzando en la línea actual, el programa busca hacia adelante a través del archivo hasta que encuentra la primera línea que contiene la cadena. Tenga en cuenta que: no se utiliza, a diferencia del modo de primera línea de vi. Si la búsqueda falla, ed comienza de nuevo al principio del archivo y continúa buscando hasta llegar a la línea actual. Cuando la búsqueda es exitosa, finaliza la búsqueda y muestra la línea que contiene la cadena, como se muestra aquí: /Seguro otro sistema operativo para computadoras pequeñas y estoy seguro que es La línea mostrada se convierte en la línea actual; ed no muestra el número de línea. Si no existe ninguna cadena del tipo especificado en todo el archivo y muestra el indicador de error ?. También puede buscar hacia atrás desde la línea actual usando el ? (Signo de interrogación). ?cadena A partir de la línea actual, el programa busca hacia el principio del archivo y se detiene cuando encuentra la cadena. Si la búsqueda falla, el programa va al final del archivo y continúa la búsqueda hacia la línea actual. Dado que ed recuerda la última expresión regular, puede repetir la búsqueda de cadenas simplemente escribiendo el carácter I o ?. (dependiendo de la dirección deseada), seguido de un retorno de carro. REEMPLAZO DE PARTES DE TEXTO El programa ed tiene el comando s (sustituir) que le permite reemplazar una cadena con otra; la sintaxis es la misma que el comando equivalente en vi. El comando s toma como argumentos un número de línea o un rango de números de línea si tiene la intención de reemplazar en varias líneas. Por ejemplo: pag que cualquier otro sistema operativo para computadoras pequeñas y estoy seguro 4.6s/seguro/convencido que cualquier otro sistema operativo para ordenadores pequeños y estoy convencido La línea actualizada se muestra para verificar si los cambios presupuestados se han trasladado. Este ejemplo muestra el reemplazo de la primera aparición de la cadena sure en cada una de las líneas 4 a 6. Puede usar expresiones regulares complejas para la parte que se eliminará en la operación de reemplazo, pero asegúrese de verificar el resultado, ya que los pequeños errores en la expresión regular puede hacer que ed identifique una cadena diferente a la deseada. Puede eliminar una cadena con este comando; simplemente especifique una cadena nula como cadena de reemplazo: 2.5s/la// Así que agregue otro carácter I al final del comando de reemplazo. En general, si la barra de cierre está ausente, muestra la línea que se ha actualizado, de lo contrario, no muestra nada. Las expresiones regulares ^ y $ designan el inicio y el final de la línea, respectivamente. Para agregar una cadena al final de una línea, use el siguiente comando: s/$/nuevo texto al final Para agregar una cadena al comienzo de una línea, use el siguiente comando: $/^/nuevo texto al principio REEMPLAZOS GLOBALES Normalmente, el comando s modifica solo la primera aparición de una cadena que aparece en una línea. Puede agregar la opción al final del comando de reemplazo para obligar al comando sa a realizar un reemplazo de propósito general en cada aparición de la cadena en la línea (o en un conjunto de líneas si especifica el rango de números de línea). s/texto antiguo para eliminar/texto nuevo para agregar/g Esto cambia cada aparición de la cadena en la línea actual. Para realizar el cambio en cada aparición de la cadena que aparece en todo el archivo, use el siguiente comando: 1,$s/texto antiguo/texto nuevo/d Puede usar una dirección de contexto en lugar de un número de línea; el carácter $ del ejemplo anterior representa una dirección de contexto. /hola/,/hola/s/viejo/nuevo/ El programa y busca a partir de la línea actual y realiza el reemplazo en la parte comprimida del archivo entre las cuerdas hola y hola. Esta técnica de direccionamiento es más complicada que la simple notación de número de línea, pero confirma que en el entorno UNIX la operación de escritura se puede realizar sin una numeración de línea explícita. Por esta razón, ed se denomina editor de contexto. MOVER Y COPIAR LÍNEAS El comando m (mover) le permite transferir una línea o conjunto de líneas de una ubicación en el archivo a otra, esta operación también se conoce como cortar y pegar. Por ejemplo, para mover la línea actual al final del archivo, escriba: .m$ El comando m también recibe como argumento una dirección de línea o un conjunto de líneas. Este comando: 3,5 m1 transfiere las líneas 3, 4 y 5 inmediatamente después de la línea 1. Para copiar una línea de una ubicación a otra sin borrarla, use el comando t. 2,4 billones de dólares De esta forma, las líneas entre 2 y 4 se copian al final del archivo. ABRIR UNA CARCASA: ¡EL OPERADOR! Finalmente, puede salir de ed, para ejecutar otros comandos en el entorno de shell, ingresando el carácter ! desde el teclado, seguido del comando que desea ejecutar. !cat archivo antiguo Cuando el comando se completa y muestra el carácter ! y volver a la acción. Para suspender temporalmente la sesión de ed y crear un shell interactivo, puede escribir: !sh Este shell se llama subshell, ya que su sesión de edición original aún está activa y esperando que finalicen las operaciones administradas por el subshell antes de recuperar el control. Puede interrumpir la ejecución del subshell presionando CTRL-D o salir y así regresar a la sesión de ed. Hemos presentado hasta ahora solo algunas de las utilidades disponibles por ed, pero tendremos la oportunidad de profundizar en ellas y examinar otras nuevas en los siguientes capítulos. 6.8 Perspectivas Insistimos en el concepto de que para aprender el uso de editores en un entorno UNIX es recomendable practicar frecuentemente con el editor de su elección. Además, observe a un experto en el trabajo y no tenga miedo de hacerle preguntas cuando lo vea realizando operaciones que son demasiado complicadas o demasiado rápidas para usted. Finalmente, pase el mayor tiempo posible consultando la documentación de uso y aplicando nuevas ideas. ARCHIVOS DE GUIÓN PARA ed El editor vi es un programa totalmente interactivo y, como tal, requiere que la salida se dirija a la terminal y que la entrada provenga de la terminal, por lo que no utiliza los archivos de entrada y salida estándar como otros programas. El editor ed, por otro lado, normalmente usa entrada estándar y salida estándar y le permite usar archivos con procedimientos particulares (scripts) para realizar automáticamente operaciones de edición en archivos cuyo contenido conoce y para los cuales puede prefigurar la secuencia de comando necesaria para los cambios deseados. El siguiente archivo representa un procedimiento de edición simple: $ gato ed.script /Encuentrame/ a Saludos HOLA w q ps Si inserta estos comandos de forma interactiva en ed, obtiene el siguiente resultado: la línea actual se inicializa en la línea que contiene la cadena findme (/findme/); después de esta línea, en el modo de inserción, (a) se insertan las cadenas salve y ciao; vuelve al modo comando (.); se escribe el archivo (w) y finalmente se sale del editor (q). El siguiente comando $ ed -s antiguo.archivo < ed.script ps realiza las operaciones que ha almacenado en el archivo ed y actualiza el archivo old.file evitando la entrada manual de cambios. Esta técnica de actualización de archivos aparece en varios procedimientos de shell (scripts de shell), pero solo es útil si conoce los cambios exactos que desea realizar en el archivo antes de definir el procedimiento en ed. Para suprimir la salida de información por ed durante el procesamiento de un procedimiento, especifique la opción -s (silencio) en la línea de comando. BÚSQUEDA CON EXPRESIONES REGULARES EN emacs El editor de emacs admite operadores de búsqueda adicionales que son particularmente eficientes para ubicar cadenas de texto especificadas con expresiones regulares en el búfer actual. El comando -M-s (CTRL-meta CTRL-s) le permite buscar la expresión regular cuya introducción requiere emacs, usando la misma sintaxis ya vista para ed, con algunas extensiones de operadores particulares de emacs. El comando anterior busca hacia adelante, para buscar hacia atrás use el comando similar -M-r. Cuando se encuentra la cadena solicitada, puede continuar la búsqueda de otra ocurrencia de la misma cadena con los comandos -s (búsqueda) o -r (reversa) para búsquedas hacia adelante o hacia atrás, respectivamente; emacs reutiliza la última expresión regular definida. Se aplica un procedimiento similar para realizar la sustitución de cadenas a las que hacen referencia las expresiones regulares. Usando el comando M-x reemplazar-regexp (seguido de una nueva línea) emacs pregunta por la cadena a buscar y la a reemplazar. Este comando reemplaza todas las instancias ance de la expresión regular con su cadena de reemplazo; si desea que emacs solicite su confirmación antes de reemplazar la cadena encontrada, debe usar: M-x consulta-reemplazar-regexp Cuando se encuentra la primera aparición de la expresión regular, emacs deja de esperar una respuesta: presione y si desea reemplazar, de lo contrario, presione n; en ambos casos, emacs busca la siguiente aparición de la cadena, si existe. También puede escribir R para hacer que emacs reemplace todas las apariciones restantes de la cadena en el archivo sin más indicaciones, o puede escribir ~g para cancelar la operación y volver al entorno normal de emacs. ============================================================================ Capítulo 7 - Otros comandos de propósito general 7.1 El medio ambiente en más detalle 7.2 El comando de banner 7.3 El comando claro 7.4 El comando de fecha 7.5 La cal. 7.6 El comando de calendario 7.7 Los comandos más, cola, cabeza 7.8 Los comandos cmp y diff 7.9 El comando dircmp 7.10 Los comandos sort y uniq 7.11 Los comandos de cortar y pegar 7.12 El comando unirse 7.13 Operaciones de base de datos en archivos de texto 7.14 Perspectivas Hasta ahora, hemos cubierto las funciones básicas del shell de UNIX y la interfaz de usuario, así como los comandos más utilizados. UNIX en conjunto admite más de 800 comandos ejecutables y en este capítulo examinaremos con más detalle los más conocidos y algunas herramientas de software independientes que pueden facilitar el uso del sistema UNIX y que se utilizan en los procedimientos de shell (shell scripts) para automatizar tareas particulares. Para obtener más detalles sobre el significado y la definición de los procedimientos de shell, lea atentamente el Capítulo 8. 7.1 El medio ambiente en más detalle Cuando ejecuta un comando, el sistema crea un entorno de ejecución al que pasa algunas de las variables de entorno, como es el caso de los editores descritos en el Capítulo 5 que utilizan la variable de entorno TERM. No todas las variables de entorno están disponibles para el comando que ejecuta, pero el shell le asigna un entorno inicial que se puede pasar a las subrutinas llamadas, y solo aquellas variables de entorno que se declaran exportadas se pueden usar más abajo en el nivel. Este es un subconjunto de todas las variables de entorno que ha declarado. Si escribe el comando $export sin argumentos, el sistema muestra una lista de variables de entorno del tipo exportado a las que puede agregar una nueva variable de entorno especificándola como argumento para el comando de exportación: $ TERM export De esta manera, la variable de entorno TERM puede ser utilizada por sus comandos y subrutinas. El comando de exportación permite múltiples variables en la línea de comando, como: $export TERM EDITOR HISTFILE $ La exportación solo funciona para los programas subyacentes; bajo ninguna circunstancia se puede exportar una variable de entorno al entorno principal del comando. LA VARIABLE DE RUTA Una de las variables de entorno más importantes es la variable PATH. Cuando ejecuta un comando indicando su ruta completa, como por ejemplo $ /usr/bin/vi el shell busca el comando a ejecutar comenzando desde la raíz de la jerarquía de directorios, mientras que, si no indica una ruta completa, como por ejemplo $ vi el shell no sabe dónde buscar el programa ejecutable. La variable PATH almacena una lista de directorios en los que el shell busca el comando que especificó sin especificar la ruta completa. Veamos un ejemplo típico de una variable PATH: $ echo $PATH :/home/giorgio/bin:/sbin:/usr/sbin:/usr/bin:/usr/X/bin:/usr/ucb $ La variable PATH puede diferir, pero la sintaxis es común a todos los sistemas UNIX. PATH corresponde a una pequeña base de datos, cuyos elementos están separados por el carácter: (dos puntos). Cuando especifica un comando sin un nombre de ruta completo, el shell busca cada directorio PATH, examinándolos a su vez de izquierda a derecha, hasta que encuentra un comando con ese nombre Si dicho comando no reside en ninguno de los directorios especificados, el shell muestra un mensaje de error; por el contrario, si la búsqueda fue exitosa, ejecuta el comando. $xxx xxx: not found $ Puede definir varios comandos con el mismo nombre en su máquina, pero debe colocarlos en directorios diferentes. La selección de directorios en PATH ocurre en orden posicional, por lo que el tipo de comando elegido para ejecutar depende del orden en que se escanean los directorios. El ejemplo anterior indica que /home/george/bin precede a /sbin y ambos directorios pueden contener comandos que tienen el mismo nombre. Es posible que la variable PATH de algunos usuarios no incluya el directorio /home/george/bin, sino solo /usr/bin, por lo que solo se puede ejecutar la versión de vi contenida en este directorio. En última instancia, los usuarios pueden controlar el conjunto de comandos que tienen disponibles cambiando su variable PATH. La mayoría de los comandos ejecutables normales se encuentran en uno de los directorios /sbin, /usr/bin o /usr/sbin de su variable PATH. Puede agregar otros directorios, para optimizar la ejecución de comandos o para almacenar sus comandos privados. Si ha instalado el sistema X Window o software de aplicación adicional, como un procesador de textos o un sistema de gestión de bases de datos, el directorio de ubicación de estas aplicaciones también puede estar incluido en su PATH. Asimismo, si desea utilizar las herramientas BSD provistas en SVR4, deberá agregar el directorio /usr/ucb a su PATH; colóquelo en primer lugar si desea que las versiones BSD de los comandos anulen sus equivalentes de System V, en último lugar si desea que los comandos de System V tengan prioridad. Como ya se señaló, los componentes individuales del PATH están separados por:, La presencia de un carácter adicional: en la variable PATH, como al principio del ejemplo anterior, se refiere al directorio actual en su ubicación actual. La diferencia entre $ PATH =/sbin:/usr/bin:/usr/sbin y $ PATH = :/sbin:/usr/bin:/usr/sbin consiste en el hecho de que solo la segunda variable hace referencia primero al directorio actual, sea cual sea. Puede hacer que el shell busque el directorio actual después de todos los demás directorios con el siguiente comando: $ PATH =/sbin:/usr/bin:/usr/sbin: En este caso hemos añadido otro carácter: al final de PATH. La variable PATH generalmente se inicializa y se hace referenciable cuando inicia sesión y solo actualiza su contenido si desea cambiar su valor predeterminado. 7.2 El comando banner UNIX proporciona muchos comandos de uso general y, aunque algunos de ellos tienen un uso limitado, cada uno tiene su lugar en el sistema. Uno de los más simples e inmediatos es el comando banner que informa sus argumentos en caracteres ampliados en la salida estándar. $banner hola mundo # # #### # ## # # # # # # # ###### # # # # # # # # # # ###### # # # # # # # # # #### ###### # # # # # # # # ##### #### ## ## # # ## # # # # # # ## # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # #### # # ##### #### El comando banner tiene en cuenta automáticamente el tamaño de la página para que el mensaje ampliado sea siempre comprensible. A menudo se utiliza en algunas funciones de impresión para distinguir entre diferentes tipos de información. Por ejemplo, este comando muestra la identificación del usuario: $ banner $LOGNAME $ 7.3 El comando clear El comando clear es una herramienta simple para borrar el video y obtener el mensaje $ en la primera línea: $clear El comando no acepta argumentos, debería funcionar bien en la mayoría de las terminales. 7.4 El comando de fecha Los comandos de gestión de fecha y hora disponibles en el entorno UNIX tienen una resolución que oscila entre un milisegundo y un año. La mayoría de los sistemas tienen un chip que realiza funciones de reloj/calendario y, por lo general, la fecha y la hora se configuran correctamente durante la carga. Cada archivo está asociado a la fecha y hora de la última actualización; también hay un comando específico para mostrar el día y la hora actuales. $date miércoles 27 de mayo 18:12:56 EDT 1990 $ De forma predeterminada, el sistema muestra la fecha y la hora actuales según las convenciones locales, la zona horaria y cualquier horario de verano; también puede adaptar el formato de salida de fecha a sus necesidades o conveniencia. El sistema puede determinar el inicio y el final del horario de verano, pero puede confundirse en caso de cambios en la ley de aplicación. El comando de fecha se usa a menudo para fechar trabajos: también se puede usar para cambiar la fecha y la hora del sistema. Dado que muchas actividades internas del sistema dependen de la precisión de la fecha y la hora, siempre deben cargarse correctamente. El Capítulo 20 analiza la introducción de la fecha y la hora en el sistema y el cambio del formato de la salida del comando de fecha. 7.5 El cal. El comando cal (calendario) cae en la categoría de comandos útiles, pero no esenciales. Sin argumentos, el comando genera el calendario del mes actual en la salida estándar. $cal mayo de 1990 D L Ma Mi J V S 1 2 3456789 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 $ Si se especifica el año como único argumento, es decir, un valor numérico entre 1 y 9999, cal muestra el calendario completo. Tenga en cuenta que 92 se refiere a 92 AD, no a 1992. El comando cal también toma dos argumentos: en orden, mes y año. La siguiente línea de comando $ cal 9 1752 muestra el calendario correspondiente al mes de septiembre del año 1752, teniendo en cuenta la aplicación de la reforma del calendario. 7.6 El comando calendar El comando calendar proporciona una agenda simple que puede usar para realizar un seguimiento de sus citas. Si el directorio actual contiene un archivo llamado calendario, el sistema busca en el archivo líneas que contengan la fecha de hoy o de mañana. En la práctica, puede insertar nuevas citas en el archivo de calendario, una por línea, y ejecutar el programa de calendario al menos una vez al día para recordar los eventos más importantes del día. $calendar Cita con médico el 28 de mayo para revisión $ El comando calendar acepta diferentes formatos de fecha, además del mostrado en el ejemplo anterior, para los cuales es válida la indicación 5/28, a diferencia del formato europeo, es decir, 28/5, que no se interpreta correctamente. Puede configurar el sistema para ejecutar el calendario cada vez que inicie sesión para ver qué actividades están programadas para el día. El archivo de calendario generalmente se encuentra en su directorio de inicio. 7.7 Los comandos more, tail, head Ya hemos hablado sobre el programa more, que muestra la salida del bloque en la pantalla, cambiando entre ellos solo después de presionar la tecla de retorno. El comando pg (localizador) es similar a more, pero no tan común. Por lo general, representa el último comando en una canalización o, cuando se usa solo, tiene una lista de nombres de archivos como argumentos. $ more /etc/profile /etc/inittab Después de mostrar una pantalla completa, el programa deja de mostrar el aviso - -More--(%). Para ir a la siguiente pantalla, simplemente presione la barra espaciadora o f (f); si ingresa un número antes de f, más avanza por tantas pantallas. También puede volver atrás en la visualización de un archivo con CTRL-B (hacia atrás); ingresando un número antes de CTRL-B puede retroceder ese número de pantallas. Con RETURN en lugar de la barra espaciadora, puede avanzar una línea a la vez en lugar de una pantalla; un argumento positivo antes de RETURN especifica el número de líneas para desplazarse hacia adelante. El operador CTRL·L· vuelve a mostrar la pantalla actual. En respuesta a la solicitud, también puede ingresar otros comandos que más se interpretan como acciones a realizar. Por ejemplo, en la sintaxis utilizada en el entorno ed, puede especificar una expresión regular que comience con el carácter I o ?: more busca hacia adelante o hacia atrás en el archivo respectivamente y muestra la parte del texto que incluye la expresión referenciada, si el encuentra Si ingresa un número n antes del carácter /, más coincide con la enésima aparición de esa expresión regular. Por ejemplo :6/[fe]grep/ busca la sexta aparición de la cadena fgrep o la cadena egrep que comienza en la línea actual. El operador. (punto) le pide que vuelva a mostrar la ventana actual, mientras que el operador $ muestra la última ventana del archivo. Si especifica más de un archivo en la lista de argumentos de más, la opción :n (siguiente) coloca el cursor al principio del archivo siguiente al actual, mientras que :p (anterior) lo coloca al principio del archivo anterior. Tanto :n como :p pueden estar precedidos por un número que indica cuántos archivos debe omitir el comando, respectivamente hacia adelante o hacia atrás, antes de hacer referencia al archivo de interés, como en este ejemplo: :3p Naturalmente, los comandos :n y :p no se ejecutan si ejecuta más al final de una canalización. El comando h (ayuda) muestra la lista de más comandos; para salir más y volver al shell, presione la tecla o (salir) o la tecla DEL. El comando more usa la variable TERM para adaptar el formato de la salida al tipo de video que tienes disponible, por lo que el valor de la variable debe ser correcto. El comando more muestra el contenido de los archivos comenzando desde el principio; para ver el final del archivo, debe desplazarse por él o usar el operador $. Para ver la parte inferior (o la cola) del archivo, use el comando tail especificando el nombre del archivo como argumento. Puede usar la cola al final o incluso en el medio de una tubería. El comando escribe las últimas 10 líneas del archivo en la salida estándar, como se muestra aquí: $ tail /etc/profile EDITOR= /usr/bin/vi FCEDIT = /usr/bin/vi EXINIT ='set ai' ENV = "$( - : + $HOME/.ksh.aliases$( - # # *i*Jl" export HISTFILE EDITOR FCEDIT EXINIT ENV >$HISTFILE stty brkint echoe ixon ixany erase trap123 $ La presencia de la opción -n con un argumento numérico n hace que tail muestre un número n de líneas de archivo, en lugar del valor predeterminado (10): $ tail -1 /etc/profile stty brkint echoe ixon ixany erase trap123 $ Además, el argumento numérico - n puede ir seguido de una letra para especificar un recuento en unidades que no sean de línea: - e para contar en caracteres y - b para contar en bloques. Este comando muestra los últimos 20 caracteres del archivo, comenzando desde dentro de una línea si es necesario: $ tail -20c /etc/profile rt PATH; trap123 $ El comando tail generalmente devuelve el control al shell después de leer el final del archivo. En algunas situaciones, mientras un programa está escribiendo en un archivo, puede ser conveniente observar cómo se escribe el archivo. Puede lograr esto ejecutando repetidamente el comando tail - 3, pero la opción -f (seguir) para tail es más conveniente, lo que hace que la ejecución se repita, logrando así que cada nueva línea del archivo se muestre tal como se está ejecutando. escrito, por ejemplo: $ tail -f aumento.archivo Dado que el comando tail - f nunca termina, debe interrumpir su ejecución presionando la tecla Supr cuando llegue al final del archivo. El comando head muestra el comienzo de un archivo, por defecto las primeras 10 líneas; como argumento, toma una lista de nombres de archivo, en ausencia de un argumento, lee su entrada estándar. Obviamente, no puede usar la opción -f para el inicio de un archivo. Puede mostrar cualquier número de líneas con un argumento numérico, por ejemplo: $ head -4 /etc/profile #ident"@(#)/etc/profile.si 1.14.012126/89 60576 AT&T-SF" trap "" 1 2 3 umask 022 # predispone la máscara de creación de fichero por defecto . /etcfTIMEZONE $ 7.8 Los comandos cmp y diff A menudo es útil comparar dos archivos para ver si son idénticos. El comando cmp (comparar) compara dos archivos, incluso archivos binarios, cuyos nombres especificó como argumentos. $ cmp /sbin/sh /usr/bin/ksh /sbin/sh usr/bin/ksh differ: char 5, line 1 $ El comando genera solo el número del primer byte, si lo hay, que difiere en los dos archivos. En cambio, la opción -l hace que cmp especifique el número de bytes y sus valores para cada diferencia que encuentre entre los dos archivos. En este caso el tamaño de la salida puede ser considerable, si hay muchas diferencias entre los dos archivos, pero seguro que la información que contiene es más útil. El comando cmp también toma el carácter - (menos) como argumento, en lugar de un nombre de archivo, para indicar la entrada estándar. $ cat /sbin/sh : cmp - I - /sbin/sh $ Si no hay diferencias entre los archivos, cmp no genera resultados. Para archivos de texto, hay disponible una herramienta más eficiente, a saber, el comando diff (diferencia) que produce un índice completo de todas las líneas que difieren entre los dos archivos, especificando los números de línea y los cambios que se deben realizar para que las líneas sean idénticas. . $cat fichero1 este es un archivo de muestra, que consta de unas pocas líneas, todo muy conciso. Este archivo le permite observar el comportamiento de diff. $cat fichero2 este es un archivo de muestra, que consta de unas pocas líneas, todo muy sencillo. Este archivo le permite observar el comportamiento de diff. $diff fichero1 fichero2 3c3 < todo muy conciso > todo muy sencillo ps El comando diff primero genera los números de las líneas que difieren en los dos archivos y los separa con el carácter e (cambiado); luego muestra las líneas en examen, marcando las del primer archivo con el carácter < y las del segundo archivo con el carácter >. La salida se vuelve más compleja para archivos más grandes a medida que aumenta el número de diferencias, pero el comando diff no tiene dificultad para revisarlas todas. Si especifica un signo - (menos) en lugar de un nombre de archivo, el comando lo interpreta como un archivo de entrada estándar. Una cantidad diferente de caracteres de espacio o cualquier carácter de tabulación en los archivos hace que las líneas difieran entre sí, pero la opción -w (espacio en blanco) hace que el comando diff no considere que las líneas que difieren solo en la cantidad de caracteres de espacio sean distintas. por lo tanto, los espacios y los tabuladores contenidos en un archivo se pueden tratar de la misma manera. $ cat fichero3: diff - w -fichero2 $ También puede usar la opción -i (ignorar) para hacer que la comparación ignore el caso. Si los archivos son idénticos, diff no genera ningún resultado. La salida de diff recuerda el formato de los comandos ed que convierten un archivo en otro. En particular, la opción -e (ed) produce una salida que ed puede usar directamente para convertir archivos. $diff -y fichero1 fichero2 3c todo muy sencillo. ps Puede usar el resultado del siguiente comando para convertir fichero1 a fichero2. $diff - e fichero1 fichero2 > ed.script $ ( cat ed.script ; echo w ) : ed file1 109 98 $ diff fichero1 fichero2 $ Este ejemplo introduce muchos conceptos interesantes. Dado que ed lee los comandos de la entrada estándar, puede usar una canalización para enviar comandos a ed, en lugar de escribirlos directamente desde la terminal. Cuando ed encuentra el final del archivo de canalización, finaliza y devuelve el control al shell. Entonces, si selecciona la salida producida por diff -y en ed, ed interpreta esos comandos y finaliza su ejecución cuando finaliza el archivo ed.script. Es por eso que no necesita escribir q para finalizar su sesión de ed. La salida producida por diff - e no contiene ningún comando w para escribir archivos en el entorno ed, por lo que, de manera predeterminada, e realiza los cambios y luego sale sin copiarlos. Para hacer que e escriba el archivo, necesita especificar la opción w, usando el comando echo w. El comando cat que opera en el archivo ed.script está separado de echo w por el operador de shell; (punto y coma), que tiene la función de mantener distintos los comandos especificados en una línea. El carácter final de ed.script representa el carácter de fin de archivo, por lo que ed sale antes de encontrar la opción w especificada por el comando echo. Puede evitar esta situación delimitando la secuencia completa de caracteres que desea incluir entre paréntesis. El uso de paréntesis como operadores de shell lo obliga a ejecutar todos los comandos que contienen en un solo subshell en lugar de como comandos separados. De esta manera, la salida producida por los diversos comandos se concatena y forma la entrada del comando ed, eliminando así el efecto de fin de archivo no deseado que de otro modo produciría el carácter ;. Otra forma de escribir el mismo comando puede ser la siguiente: $ echo w : cat ed.script - : ed fichero1 Los dos números 109 y 98, que se muestran en el ejemplo anterior, representan el contenido de la salida estándar de ed cuando, y respectivamente, leen y escriben el archivo. Experimente con estas soluciones en su máquina. 7.9 El comando dircmp El comando dircmp (comparación de directorios) compara el contenido de dos subárboles de directorios; informar archivos que existen en un solo directorio y comparar (usando cmp) archivos que existen en ambos directorios. La salida puede ser grande, pero dircmp es útil cuando necesita verificar dos versiones de un directorio. Los dos directorios se proporcionan como argumentos para el comando, por ejemplo: $ dicmp $HOME /tmp/copiado Puede usar la opción -d (diff) para generar una salida de formato similar a diff en lugar de cmp. 7.10 Los comandos sort y uniq El sistema UNIX define dos herramientas de software adicionales que se utilizan a menudo en una estructura de canalización para filtrar archivos de texto de forma adecuada. El comando ordenar ordena alfabéticamente un conjunto de líneas de texto. Puede aceptar una lista de nombres de archivo como argumentos, o leer la entrada estándar y escribir las líneas ordenadas en la salida estándar. $cat texto.archivo Aquí hay un archivo corto. Cada línea comienza con una letra diferente. cada línea comienza con una palabra de cuatro letras. Gran parte de las líneas comienzan con una letra mayúscula. $sort texto.archivo Aquí hay un archivo corto Gran parte de las líneas comienzan con una letra mayúscula. Cada línea comienza con una letra diferente. cada línea comienza con una palabra de cuatro letras. $ El comando sort ordena las líneas de todos los archivos especificados en la línea de comando y, por lo tanto, incluye funciones que en otros sistemas operativos se denominan fusionar. Este comando puede manejar archivos muy grandes, aunque su rendimiento se degrada significativamente para archivos de más de mil líneas. A menudo es más rápido clasificar varios archivos grandes por separado y luego clasificarlos juntos con la opción -m (combinar) del comando de clasificación. El comando sort sigue, durante la fase de reordenación, el orden de precedencia definido por el conjunto de caracteres ASCII (secuencia de clasificación ASCII) y lo aplica comenzando desde el principio de las líneas que compara. Esta secuencia ASCII considera como primer carácter el espacio, luego los signos de puntuación, los números, las letras mayúsculas y finalmente las letras minúsculas. Cuando el primer carácter de las dos líneas coincide, la clasificación pasa a examinar el siguiente carácter, hasta el carácter de nueva línea, si es necesario, para determinar el orden correcto. Al ordenar archivos alfabéticamente, el procedimiento descrito encaja perfectamente, pero cuando la ordenación involucra datos numéricos, los resultados no cumplen con sus expectativas. $ cat datos.archivo 1 2 10 11 21 $ sort datos.archivo 1 10 11 2 21 ps La clasificación es incorrecta porque el carácter 1 precede al carácter 2 en la notación ASCII, por lo que todas las líneas que comienzan con 1 preceden a todas las líneas que comienzan con 2. La opción -n (ordenamiento numérico) especificada en la ordenación de la línea de comando hace que el comando ordene el archivo numéricamente. $sort -n datos.archivo 1 2 10 11 21 ps El comando sort le permite ignorar la diferencia entre caracteres en minúsculas y mayúsculas durante la operación de comparación si usa la opción -f (doblar). $sort -f texto.archivo Aquí hay un archivo corto. Gran parte de las líneas comienzan con una letra mayúscula. Cada línea comienza con una letra diferente. cada línea comienza con una palabra de cuatro letras. $ En este caso no hay diferencia entre Cada y cada uno, pero las líneas difieren en la columna 12, ya que el comienzo precede a la parte. De manera similar, la opción -d (diccionario) cancela la operación de clasificación en la puntuación u otros caracteres especiales, de modo que solo las letras, los dígitos y el carácter de espacio se vuelven significativos. La opción -M (mes) hace que el comando de clasificación trate los tres primeros caracteres de la línea como indicadores de mes, por lo que enero precede a febrero, aunque lo sigue alfabéticamente. Hasta ahora, la clave de clasificación, es decir, la parte de la línea donde el comando de clasificación comienza a clasificar, siempre se consideraba el comienzo de la línea de entrada. El comando ordenar le permite indicar cualquier parte de la línea como clave de clasificación, sin dividir las líneas en partes, que en cambio se consideran registros. Se puede hacer que la ordenación use alguna otra parte de la línea de entrada como clave de ordenación especificando los argumentos + n y -n, donde n es un número que identifica un campo en la línea, mientras que un campo es una secuencia de caracteres separados por un delimitador En particular, el carácter de espacio o carácter de tabulación es un delimitador de campo, y el inicio de la línea representa el campo O. Por lo tanto, la opción +I hace que la ordenación utilice el siguiente campo en lugar del inicio de la línea como clave de ordenación. . $sort +1 texto.archivo Cada línea comienza con una letra diferente. cada línea comienza con una palabra de cuatro letras. Gran parte de las líneas comienzan con una letra mayúscula. Aquí hay un archivo corto. $ En este ejemplo, la clasificación de las líneas procede del segundo campo (línea, parte y a). Utilice la opción -n para que la ordenación deje de compararse en el campo n. $sort +1 -3 texto. archivo En este caso, solo el segundo y el tercer campo se utilizan como clave de clasificación. Cuando los datos se ordenan por campos y las líneas difieren solo en los campos que no forman parte de la clave de ordenación, no puede saber en qué orden aparecen esas líneas en la salida. Sin embargo, puede controlar el orden de los campos del archivo especificando más de un campo en el comando de ordenación como clave de ordenación. $sort +3 -4 +0 -1 archivo.texto. En este caso, la clasificación de las líneas procede considerando el campo 4 como la clave principal. Para las líneas en las que este campo coincide, el inicio de la línea se considera una clave secundaria. $sort +3 -4 +0 -1 texto.archivo Cada línea comienza con una letra diferente. cada línea comienza con una palabra de cuatro letras. Aquí hay un archivo corto. Gran parte de las líneas comienzan con una letra mayúscula. $ Compare esta salida con la siguiente: $sort +3 -4 + 7 texto.archivo cada línea comienza con una palabra de cuatro letras. Cada línea comienza con una letra diferente. Aquí hay un archivo corto. Gran parte de las líneas comienzan con una letra mayúscula. $ Puede cambiar el separador de campo, que por defecto es el carácter de espacio, con la opción -t, que toma un carácter como argumento. Por ejemplo, para usar el carácter: (dos puntos) como separador de campo, escriba: $ sort - t: /etc/passwd Además, sort acepta la opción b (en blanco) para ignorar los espacios en la clave de clasificación y la opción -r (inversa) para invertir el orden de búsqueda. Puede combinar las diferentes opciones y claves de clasificación para ordenar los archivos según sus intenciones, pero la elección correcta generalmente requiere algo de experimentación. El comando ordenar se usa generalmente con uniq (único) para calcular el número de ocurrencias de una determinada línea o campo en un archivo. El comando uniq examina un archivo (la entrada estándar) que contiene múltiples ocurrencias de la misma línea e informa en la salida estándar solo una instancia de cada línea de entrada que difiere de las otras líneas. $ cat data2 abc def ghi def abc $ sort data2 : uniq abc def ghi $ Solo se escribe una copia de cada línea, por lo que uniq produce una lista de líneas distintas. Además, la entrada al comando uniq debe ordenarse correctamente para no arrojar errores. La opción -e (recuento) de uniq se usa a menudo para calcular el número de ocurrencias de líneas distintas que están presentes en el archivo de salida y aparecen antes de la línea correspondiente. $ sort data2 : uniq - e 2 abc 2 def 1 ghi $ Este ejemplo indica que hay dos instancias de las líneas abc y def y una instancia de la línea ghi en el archivo de entrada. La opción -u (única) informa solo las líneas que no se repiten en la entrada, a diferencia de la opción -d (duplicada) que informa solo las líneas que son dobles. El comando uniq también puede limitar su alcance a campos particulares del archivo de entrada. La opción -n, donde n es un número, ignora los primeros n campos de la línea al comparar. Al igual que con el comando ordenar, los espacios representan delimitadores de campo. La opción +n, donde n es un número, ignora los primeros n caracteres de la línea, mientras que cuando -n y +n se usan juntos, los campos se ignoran antes que los caracteres. 7.11 Los comandos cut y paste Vimos el comando cut en el Capítulo 3. Este comando se utiliza para dividir las líneas de entrada según campos o columnas particulares indicados explícitamente. Al igual que el comando ordenar, cortar opera en partes específicas de la línea de entrada; a diferencia de ordenar, no genera la línea de entrada completa, pero le permite eliminar partes de ella. Además, además de cut, está disponible un comando que combina las líneas pertenecientes a dos archivos en la salida. El comando paste, de hecho, acepta dos o más nombres de archivos de entrada, lee una línea de cada archivo, los combina para generar una sola línea que informa en la salida estándar. Cada archivo de entrada contribuye con un campo a la composición de la línea de salida y el comando agrega un carácter de tabulación como delimitador de campo. La opción -d le permite especificar un carácter distinto del predeterminado como delimitador. $cat nuevo.d1 1111 2222 3333 $cat nuevo.d2 MAA 8888 cece DDDD EEEE $paste -d: nuevo.d1 nuevo.d2 1111:MAA 2222:8888 3333:CCCC :DDDD :EEEE $ El comando paste toma cualquier cantidad de nombres de archivo como argumentos y genera sus líneas en orden de izquierda a derecha. Si los archivos difieren en longitud, pegar simplemente inserta el delimitador sin devolver ningún campo. Cualquier nombre de archivo se puede reemplazar por un signo - (menos), que se interpreta como una entrada estándar. En el ejemplo anterior usamos el carácter : (dos puntos) como delimitador, pero puede especificar más de un carácter después de la opción -d y cada elemento de esta lista se usa a su vez para delimitar un par de campos de salida. Cuando se hayan utilizado todos los caracteres de la lista, se reinicia el pegado en el primer carácter de la lista. De esta forma, distintos delimitadores separan los diferentes campos y este método es especialmente adecuado cuando el número de campos coincide con el número de delimitadores. $paste -d123 archivo1 archivo2 archivo3 archivo4 En este caso, el comando pegar toma la primera línea de archivo1, agrega el dígito 1, la primera línea de archivo2, el dígito 2, la primera línea de archivo3, el dígito 3 y finalmente agrega la primera línea de archivo4. La línea resultante termina con una nueva línea y se envía a la salida estándar. El comando pegar repite estas operaciones en todas las demás líneas hasta que llega al final del archivo. 7.12 El comando join A diferencia de paste, que combina líneas coincidentes completas de diferentes archivos, el comando join combina líneas de archivos que coinciden en un rango específico. Por ejemplo, puede tener dos archivos que contienen un nombre o identificador de usuario en un campo, pero información diferente en los otros campos; El comando unir le permite combinar, para cada nombre o campo común, información de dos archivos en una sola línea de salida, por ejemplo: $cat archivo1 nombre.a:oficina:teléfono nombre.b:oficina:teléfono nombre.c:oficina:teléfono $cat archivo2 nombre.a:dirección:hijo nombre.b:dirección:hijo nombre.c:dirección:hijo $ join -t: archivo1 archivo2 nombre.a:oficina:teléfono:dirección:hijo nombre.b:oficina:teléfono:dirección:hijo nombre.c:oficina:teléfono:dirección:hijo $ La opción -t (tabulador) define el delimitador de campo; el valor predeterminado es el carácter de tabulación. El resultado de la combinación se envía a la salida estándar. También puede seleccionar un subconjunto de campos de salida con la opción -o (solo), seguido de una lista de argumentos con el formato m.n, donde m es el número de archivo (1 o 2) y n es el número de campo. El comando join requiere que los dos archivos de entrada se ordenen previamente según el campo común; los archivos también pueden contener varias líneas con el mismo campo de unión. Por defecto, join usa el primer campo de la línea como campo de unión en ambos archivos; la opción - j Goin field) permite cambiar este criterio; para fusionar archivos usando el campo n en el primer archivo y el campo m en el segundo, debe declarar: $ join -j1 . -n - j2 m archivo1 archivo2 7.13 Operaciones de base de datos en archivos de texto Los comandos que acabamos de ver son muy útiles en el manejo de archivos de texto. Con frecuencia se combinan en canalizaciones, a veces utilizando archivos temporales para poder almacenar resultados intermedios. Con estas herramientas, puede realizar operaciones complejas en sus datos, como buscar, contar y eliminar partes de archivos, para producir archivos de salida nuevos y útiles. En realidad, estos operadores constituyen las herramientas básicas para realizar operaciones relativamente sofisticadas sobre bases de datos. Una vez que te hayas familiarizado con los comandos básicos y las principales opciones, resulta muy fácil crear incluso bases de datos complejas, que generalmente están formadas por archivos de texto, es decir, un conjunto de líneas estructuradas en registros, en los que cada campo está separado por un delimitador de su elección. El carácter: y los caracteres de tabulación se usan más comúnmente como delimitadores. En la práctica, puede crear varios archivos que contengan datos, producidos por un editor o algún programa de aplicación, que generalmente están relacionados en cada archivo, pero no están relacionados si pertenecen a archivos separados. Si algún campo de los archivos coincide o se puede relacionar con campos de otros archivos, puede escribir líneas de comando para crear bases de datos relacionales. Cuando define nuevas combinaciones de comandos y canalizaciones que satisfacen sus necesidades, puede realizar consultas de datos específicas sin utilizar un software especialmente escrito, como un sistema de administración de base de datos. Muchas bases de datos complejas se han desarrollado bajo el entorno UNIX utilizando estos comandos, y las posibilidades que crea son casi ilimitadas. En el siguiente ejemplo intentaremos evaluar la consistencia de las posibilidades ofrecidas. Si bien estas herramientas funcionan más lentamente que un sistema de administración de bases de datos profesional, los archivos generalmente tienen un formato de texto fácil de leer, por lo que puede agregar y reformatear datos, hacer preguntas y generar resultados complejos de una manera muy natural. Para conocer, por ejemplo, los identificadores de todos los usuarios de la máquina, proceda de la siguiente manera: $ cut - f1 - d: /etc/passwd root daemon bin sys adm uucp nuucp sian sync lp listen sysadm setup powerdown checkfsys makefsys mountfsys umountfsys jim admin msnet pat giorgio $ De manera similar, puede determinar el shell que está disponible para los usuarios cuando inician sesión en el sistema. $ cut -f1,7 -d: /etc/passwd > temp.dati $ cat temp.dati root: deamon: bin: sys: adm: uucp: lp:/sbin/sh nuucp:/usr/lib/uucp/uucico listen: sync:/usr/bin/sync install: sysadm:/usr/sbin/sysadm vmsys:/sbin/sh oasys:/sbin/sh giorgio:/usr/bin/ksh pat: jim:/usr/bin/ksh $ Hemos redirigido la salida al archivo temporal temp.data, para su uso posterior. Este es un ejemplo no trivial: si el último campo de la línea de entrada está vacío, cut no inserta el delimitador en la salida. Al analizar el archivo /etc/passwd, puede ver que el usuario "raíz" y otros usuarios no tienen su especificación de shell en el séptimo campo. Si tiene la intención de agregar el shell predeterminado /sbin/sh a las líneas que no contienen un shell en la última posición, puede aprovechar el hecho de que cut pone su delimitador al final de las líneas que no tienen un final. campo, por ejemplo: $ grep ":$" temp.dati : sed 's/$1\/sbin\/sh/' > nuovi.dati $ cat nuovi.dati root:/sbin/sh daemon:/sbin/sh bin:/sbin/sh sys:/sbin/sh adm:/sbin/sh uucp:/sbin/sh slan:/sbin/sh lp:/sbin/sh liste:/sbin/sh jim:/sbin/sh admin:/sbin/sh msnet:/sbin/sh pat:/sbin/sh $ El comando grep analiza todas las líneas que contienen el carácter : (dos puntos) en el archivo temporal y luego sed agrega la cadena /sbin/sh al final de cada línea. El comando sed tiene una expresión de sustitución interesante porque incluye el carácter I (barra oblicua) como un carácter simple y no como un delimitador, y para anular el significado especial de /, lo hemos antepuesto con el carácter \ (barra invertida). En este punto, el archivo new.data contiene solo la lista de usuarios que no habían especificado el shell en el archivo etc/passwd y, para incluir también a los otros usuarios, use el siguiente comando: $ grep -v ":$" temp.datos >> nuevos.datos Esto agrega todas las líneas que contienen el carácter: al final del archivo al final del archivo. Puede determinar qué shells están usando los usuarios en la máquina: $ cut - f2 - d: nuevos.datos sort : uniq /sbin/sh /usr/bin/ksh /usr/bin/sync /usr/lib/uucp/uucico /usr/sbin/sysadm $ y cuántos usuarios están usando el mismo shell: $ cut - f2 - d: nuevos.datos : sort : uniq - e : sort - nr 12 /sbin/sh 2 /usr/bin/ksh 1 /usr/sbin/sysadm 1 /usr/lib/uucp/uucico 1 /usr/bin/sync $ El último comando, sort -nr, ordena los resultados en orden numérico descendente, pero hay otras formas de obtener los mismos resultados directamente desde el archivo /etc/passwd original. Escribir pipelines complejos como el anterior requiere algo de experiencia, por lo que es preferible construir estos comandos progresivamente hasta estar seguro de que la salida generada por cada uno es la correcta. Suele ser útil utilizar una pequeña base de datos de prueba en lugar de datos reales, especialmente cuando los datos son grandes y los comandos son complejos; además, también es conveniente mantener la línea de comando almacenada en un archivo y modificarla con el editor, en el transcurso de sus experimentos, en lugar de volver a escribirla cada vez. Si ingresa desde el teclado: $ sh cmdfile se ejecuta la línea de comando contenida en cmdfile, pero para ejecutar cmdfile también puede escribir: $chmod +x cmdfile También puede ejecutar el comando directamente: $ cmdfile Esta técnica, que puede transformar tuberías largas y complejas en comandos fáciles de usar, también forma la base de la programación de shell, como veremos más adelante. 7.14 Perspectivas Los comandos que UNIX pone a disposición del usuario son muchos y las formas de utilizarlos son variadas. A medida que experimenta su propio sistema y observa cómo trabajan otros usuarios, puede aprender rápidamente técnicas de programación, algunas de las cuales se tratan en capítulos posteriores. EL COMANDO sleep El comando de suspensión realiza una función muy útil y a menudo necesaria. De hecho, tiene la tarea de retrasar durante un cierto número de segundos, según las especificaciones de su argumento numérico, el regreso del control de la unidad central al caparazón, sin realizar entre tanto ninguna operación. $ date " + O/or" ; sleep 100 ; date " + O/or" 11:18:23 AM 11:20:04 AM $ El margen de error del comando de suspensión es de aproximadamente un segundo, por lo que si escribe $sleep 1 no obtendrá resultados correctos. Uno de los usos más simples del sueño es crear un sistema de alarma. La siguiente línea de comando genera un sonido en la terminal y muestra un mensaje 10 minutos después de escribir el comando: $ sleep 600 ; echo " '- 007 Hora de almorzar! '- 007" & Este comando está activo hasta que salga del sistema, pero se ejecuta en segundo plano a través del operador &, por lo que puede continuar realizando cualquier otra actividad en paralelo. La cadena '- 007 en el comando echo representa una forma alternativa de cómo mostrar cadenas de caracteres: '\. 007 es la codificación octal ASCII de la combinación de teclas CTRL-G, que genera un sonido (bip) en el terminal. La cadena '- 007 en este contexto tiene un significado muy diferente de '\.07, 007, 7 o '\. 7 y, para indicar al comando de eco que se trata de un solo carácter y no de tres dígitos, anteponga el carácter '\ (barra invertida). Dado que UNIX es un sistema multiprocesador, el programa de otro usuario adquiere el control de la CPU cuando su programa interrumpe su ejecución esperando un evento externo o la disponibilidad de un recurso. Esta situación difiere del comportamiento de los sistemas de un solo proceso, como MS-DOS, en los que puede provocar un retraso al utilizar activamente el sistema. Este tipo de espera, que se logra mediante la ejecución de un cierto número de iteraciones de bucle, puede ser extremadamente dañina en un entorno UNIX, donde otros programas pueden solicitar el uso del sistema mientras su proceso está en condición de espera. Un principio fundamental de los sistemas de multiprocesamiento es que todos los usuarios comparten recursos del sistema, por lo que cuando se encuentra en una situación inactiva, incluso si su comando está activo en segundo plano, debe usar comandos que transfieran recursos del sistema a otros usuarios. El comando de suspensión realiza esta tarea automáticamente porque cuando su proceso está en una situación de suspensión, en realidad no está utilizando una gran cantidad de recursos del sistema. Una ventaja adicional de la suspensión es que su conteo depende del puerto interno y no de la velocidad de procesamiento y se redondea al segundo. EL COMANDO find Cuando examina el contenido de un directorio con el comando ls o copia archivos usando metacaracteres como *, como en este ejemplo: $ cp * $HOME/directorio puede ver que los comandos solo hacen referencia a archivos en un directorio en particular. Si, por otro lado, está interesado en copiar o examinar el contenido de un conjunto de directorios, en lugar de operar por separado en cada directorio, use el comando find que, aunque presenta una sintaxis de línea de comando que es cualquier cosa menos trivial, sigue siendo una de los más útiles y poderosos. El comando de búsqueda puede penetrar en una jerarquía de directorios y ubicar todos los archivos a través de modalidades particulares indicadas en la línea de comando, para realizar acciones particulares sobre ellos. Su línea de comando toma la forma de: buscar expresiones de lista de nombres de ruta donde lista de nombres de ruta representa la lista de directorios para buscar, es decir, uno o más nombres de ruta de directorio completos o relativos. La parte de expresiones contiene la lista de operadores que describen tanto los criterios de selección de los archivos a los que desea hacer referencia como las acciones que desea realizar cuando un archivo satisface los criterios de selección. Por ejemplo $ find $HOME - print representa una de las búsquedas de línea de comando más cortas que implica imprimir los nombres de todos los archivos y directorios en su directorio de inicio. En la sección list-pathname de la línea de comando, puede especificar otros directorios. Este comando $ find /home/giorgio /home/leo - print muestra los nombres de todos los archivos y directorios contenidos en /home/giorgio y /home/leo. También es legal especificar rutas usando metacaracteres: $ find /home/* - print En una línea de comando de búsqueda, todos los nombres de ruta siguen al nombre del comando y no deben estar precedidos por un signo - (menos), a diferencia de los operadores que aparecen al final de la línea. De forma predeterminada, find no realiza ninguna acción en los archivos que encuentra, por lo que debe especificar - imprimir si desea enumerar todos los archivos que encuentran referencias. La opción - print hace que find escriba en la salida estándar todos los elementos que encuentra, uno por línea. Esta propiedad le permite utilizar el comando de búsqueda para contar todos los archivos y directorios presentes. $ find I - print : wc - I 8642 $ ¡En este caso, aprendemos que hay 8642 archivos y directorios! Las operaciones de búsqueda a gran escala como esta, que examina toda la estructura del directorio, pueden consumir mucha CPU y mucho tiempo, especialmente en máquinas grandes. Por lo tanto, debe limitar el uso de find a una lista de nombres de ruta que realmente satisfagan sus necesidades. Puede especificar algunos operadores que restrinjan la búsqueda a un subconjunto particular de archivos, como - nombre, que dirige la búsqueda solo a los archivos a los que se hace referencia explícitamente en la línea de comandos. $ find I - name profile - print /etc/profila $ El nombre de los archivos que indique en la línea de comando también puede contener metacaracteres de shell, protegidos entre comillas. $ find I - name "*profile" - print /etc/profile /home/leo/. profile /home/pat/. profile /home/giorgio/.profile /.profile $ Todos los metacaracteres de shell están permitidos, siempre que estén protegidos. Cuando find busca a través de la jerarquía de directorios, el orden en que encuentra los archivos depende de la organización interna del sistema y no de sus elecciones. Puede procesar la salida producida por el comando de búsqueda con ordenar con otras herramientas, para reorganizar la lista de nombres según sus necesidades. Cuando especifica múltiples opciones en la línea de comando, find las aplica a los archivos de izquierda a derecha. El comando $ find I - print - name "*profile" no coincide con $ find I - name "*profile" - print porque el primer ejemplo imprime los nombres de archivo y luego selecciona el nombre de interés, mientras que el segundo ejemplo selecciona primero los nombres y luego los imprime. El comando de búsqueda hace referencia a cada nombre de archivo en la lista de nombres de ruta, examina todos los componentes de la sección de expresiones para decidir si seleccionar o ignorar el archivo al que se hace referencia. En la primera hipótesis, las expresiones se ejecutan en los archivos, mientras que si solo una expresión fuerza la segunda hipótesis, las expresiones restantes no se analizan. En la terminología de búsqueda, la expresión evaluada es verdadera si se selecciona el nombre del archivo y falsa en caso contrario. Hay muchas otras opciones que puede especificar para el comando de búsqueda, varias de las cuales le permiten hacer referencia a archivos que coinciden con atributos particulares: por ejemplo, - user pat selecciona archivos que pertenecen al usuario pat, mientras que - group sys selecciona archivos que pertenecen al grupo sis. El comando $ find I - user $LOGNAME- print muestra los nombres de todos los archivos en la máquina que posee. La opción -type e selecciona archivos de tipo e, es decir, una de las categorías de archivos que están disponibles en el entorno UNIX, como lo demuestra la primera columna a la izquierda de la información del archivo producida por el comando ls - I (f, para y d, para directorios, son las categorías de archivos más utilizadas). La opción -mtime n selecciona los archivos que actualizó exactamente n días antes de la fecha actual, la opción -mtime -n selecciona los archivos que actualizó en los últimos n días y -mtime + n selecciona los archivos que modificó n días antes de la fecha actual. La opción -size n selecciona archivos que tienen exactamente n bloques de tamaño, la opción -size -n selecciona archivos que tienen un tamaño inferior a n bloques y -size + n selecciona archivos que tienen un tamaño mayor que n bloques. Ingrese este comando desde el teclado $ find I - size + 1000 - print para verificar qué archivos grandes están presentes en la máquina. Puede negar el significado de todos estos operadores si precede sus nombres (por ejemplo, tamaño) con el carácter ! y un carácter de espacio, por el cual el operador asume un valor falso cuando su valor es normalmente verdadero y viceversa. Por ejemplo, este comando $ find . ! - print cancela la operación de impresión, pero ciertamente es redundante. Una versión más útil del comando de búsqueda le permite encontrar todos los archivos en el directorio de inicio que no son de su propiedad. $ find $HOME ! - user $LOGNAME - print ¡Debes delimitar con espacios el operador! que se aplica solo al campo de la línea de comando que le sigue inmediatamente. Para obtener una lista de todos los archivos en el directorio de inicio que no son de su propiedad y tienen más de 50 bloques, use el siguiente comando: $ find $HOME - size + 50 ! - user $LOGNAME - print El comando puede elegir entre sus componentes, tal como aparece en este ejemplo: $ find $HOME - size + 50 - o ! - user $LOGNAME - print El operador -o (o), que conecta las dos expresiones -size +SO y! -user $LOGNAME, le permite seleccionar un archivo que satisfaga uno de estos dos argumentos. Los campos de la línea de comandos que están en posiciones adyacentes, pero que no están conectados con el operador -o, están conectados lógicamente mediante un operador and, por lo que el archivo debe satisfacer ambos argumentos para ser seleccionado. El comando de búsqueda también puede seleccionar el tipo de archivo, por ejemplo: $ find . - type f - print Esto selecciona todos los archivos normales; para seleccionar directorios use - escriba d, para enlaces simbólicos use - escriba I, también puede seleccionar archivos en función de otros tipos de archivos, y también en función del tipo de sistema de archivos al que pertenecen. Tenga en cuenta que find no busca los siguientes enlaces simbólicos a menos que se use la opción -follow. El comando de búsqueda puede usar el operador -exec (ejecutar) para ejecutar un comando particular en los archivos que selecciona. Este operador toma por sí mismo una línea de comando que especifica el nombre del archivo actual que find ha seleccionado y usa la sintaxis especial [ J (llaves derecha e izquierda) para esto. La línea de comando termina con el operador especial \; (barra invertida y punto y coma). Puede utilizar esta estructura de comandos, por ejemplo, para cambiar los derechos de acceso de los archivos ubicados en algunos directorios: $ find . - exec chmod - rw [ ] \; Este comando no muestra los nombres de los archivos que se están actualizando, a diferencia de: $ find . - exec chmod - rw [ J \; - print El operador - exec asume el valor verdadero si el comando que ejecuta devuelve un valor cero; de lo contrario, asume el valor falso. Puede definir, a través de exec, otros operadores para el comando de búsqueda que se examina de izquierda a derecha hasta que una de las expresiones evaluadas sea falsa. EL COMANDO stty El último comando que cubrimos en este capítulo es stty (establecer tty), que se usa para examinar y cambiar los parámetros de comunicación que están asociados con la terminal durante su sesión de trabajo. El sistema UNIX proporciona un control preciso sobre cómo se procesan las señales clave y la salida del terminal. El comando stty le permite inicializar las opciones para una terminal o línea de comunicación en particular. Use la opción -a (todas) del comando stty para ver los valores actuales de las opciones de terminal. $ stty -a speed 9600 baud; lineO; intr =DEL; quit =A: ; erase =Ah; kill = @; eof =Ad - parenb - parodd cs8 - cstopb - hupcl cread - clocal -loblk -ignbrk brkint ignpar -parmrk - inpck istrip - inlcr - igncr icrnl - iuclc ixon ixany - ixoff isig icanon - xcase echo echoe echok - echonl - noflsh opost - olcuc onlcr - ocrnl - onocr - onlret - ofill - ofdel tab3 $ Las opciones se muestran en un formulario que se puede usar para volver a ingresar los parámetros si es necesario. Cada opción de terminal tiene un identificador, como ixon, y se puede activar (set) o desactivar (clear). Si el nombre de la opción está precedido por un signo - (menos}, la opción está deshabilitada; de lo contrario, está habilitada. Por ejemplo, ixon se refiere al control de flujo (XON/XOFF) desde la terminal, pero si el flujo está deshabilitado, la opción toma la notación - ixon. Puede cambiar el valor de una opción usando el comando stty. Use el signo - solo cuando desee deshabilitar la opción. Este comando $ stty ixon $ habilitar el control de flujo, mientras que la siguiente línea $ stty -ixon $ lo deshabilita. En la línea de comando, puede especificar múltiples opciones, de la siguiente manera: $ stty - ixon 1200 $ Este comando inicializa la velocidad del terminal a 1200 baudios y desactiva el control de flujo. Puedes configurar la extensión en caracteres, filas y columnas de tu terminal (o ventana), por ejemplo: $ stty rows 24 columns 80 $ La nueva extensión se pasa a las aplicaciones de pantalla completa, como vi, cuando se inician, anulando los valores predeterminados normales; si cambia el tamaño de una ventana o se conecta con un terminal inusual, puede cambiar el tamaño de la pantalla con un comando manual, si no parece correcto. La cantidad de opciones que se pueden usar es alta, pero evite hacer cambios que puedan alterar la sesión. Cuando el terminal falla, es poco probable que sea una situación temporal. Muy a menudo, no se muestra ninguna salida o el shell no interpreta correctamente las señales del teclado, como en el caso de la tecla de retorno de carro, que puede interpretarse como un espacio entre líneas sin retorno de carro. El proceso de definición de un identificador de inicio de sesión inicializa correctamente las opciones de stty y rara vez necesita actualizar sus valores predeterminados. Sin embargo, si la variable TERM no se inicializa correctamente, o si tiene la intención de experimentar con nuevos terminales o canales de comunicación, como redes de área local, es posible que se requieran cambios en las opciones de stty. Si al iniciar sesión en el sistema, el terminal funciona bien pero luego comienza a comportarse de manera anormal por razones desconocidas, lo mejor es salir del sistema y volver a iniciar sesión. El sistema luego inicializa las opciones del terminal a los valores previamente establecidos. Un comportamiento menos drástico es usar el siguiente comando: $ stty sane $ El mismo argumento define un conjunto de opciones del comando stty, utilizado por la mayoría de los terminales, que no modifican la velocidad del canal de comunicación, pero tienen un efecto positivo cuando el terminal se comporta de forma extraña, sin por ello garantizar el perfecto funcionamiento de las aplicaciones a pantalla completa. , como vi. Si por el contrario, aun activando la misma opción, no consigues restaurar el comportamiento normal del sistema, sal y vuelve a entrar. Si el terminal no funciona correctamente cuando se conecta, probablemente el error ocurra durante esta operación, mientras que si las anomalías ocurren como resultado de una mala interpretación de la tecla de retorno de carro al final de las líneas de comando, presione CTRL-J para reemplazar el retorno de carro hasta que ejecuta el comando stty sane que puede ejecutar con CTRL-J para que el sistema lo interprete correctamente. Las principales opciones para stty son las siguientes: parenb habilita la paridad, mientras que -parenb la deshabilita. Las opciones parodd y -parodd seleccionan paridad e impar, respectivamente (parodd solo se usa si la opción parenb está activada). Las opciones cs5, cs6, cs7 y cs8 asignan el tamaño de fuente a 5, 6, 7 y 8 bits respectivamente. Las opciones 300, 600, 1200, 2400, 4800, 9600 y 19200 configuran la velocidad de comunicación del canal en baudios, mientras que cstopb y -cstopb configuran uno o dos bits de parada, respectivamente. La opción de tabuladores hace que el sistema utilice caracteres de tabulación en lugar de secuencias de caracteres de espacio para reducir el tamaño de la salida, mientras que la opción - tabuladores hace que solo se utilicen caracteres de espacio y se utiliza cuando el terminal no interpreta correctamente el carácter 'i: "y tabulador. También puede usar stty para asignar funciones de control particulares a las teclas. Por ejemplo, asignamos CTRL-D para significar un carácter de fin de archivo, pero si prefiere CTRL-c para hacer esto, realice las asignaciones con el comando stty: $ stty eof e donde y en este caso se reemplaza por el carácter de control que necesita. Puede introducir caracteres de control directamente protegiéndolos con el carácter \ (barra invertida) seguido del carácter ·. Este comando asigna a CTRL-c el significado del carácter de fin de archivo. También puede usar esta sintaxis para modificar el borrado (generalmente representado por +-) y el carácter intr (interrupción, generalmente representado por DEL). Para asignar borrar a +-, use el siguiente comando: $ stty erase \^h También puede configurar la sesión para que cuando escriba +-, el sistema responda con la secuencia retroceso-espacio-retroceso que elimina el carácter en el cursor; también usa el comando $ stty echoe para que esta característica tenga efecto. El Manual del usuario de UNIX contiene la lista completa de opciones de stty, así que consulte este manual y a un experto en comunicaciones antes de desviarse demasiado de las instrucciones dadas en este capítulo, especialmente con respecto a los modos de ejecución y las herramientas que contribuyen a su gestión en el entorno UNIX. ================================================================== Capítulo 8: Programación bajo shell 8.1 Comandos multilínea 8.2 Archivos de comandos de shell 8.3 El operador si 8.4 El comando de prueba 8.5 El comando de salida 8.6 El comando expr 8.7 El operador for 8.8 El operador mientras y hasta 8.9 El operador de casos 8.10 El comando printf y la salida de archivos de comando 8.11 Los archivos de comando .profile y /etc/profile 8.12 Argumentos de la línea de comandos 8.13 Errores y mensajes de error en los procedimientos de shell 8.14 Perspectivas Después de haber examinado los principales comandos de UNIX y haber tratado cómo componer líneas de comando, podemos centrar nuestra atención en las características fundamentales del shell. El shell proporciona un entorno de programación flexible y altamente funcional que ayuda al desarrollo de sus aplicaciones. La programación de shell se parece a la programación por lotes de MS-DOS en concepto, pero tiene características más complejas que agilizan el desarrollo y la ejecución de comandos y procedimientos de uso frecuente. Los programas de shell se usan comúnmente en funciones de utilidad y comandos de administración del sistema. Los ingenieros de sistemas suelen escribir aplicaciones en el lenguaje shell cuando la facilidad de comprensión y actualización son factores más importantes que la eficiencia y la velocidad de ejecución de la aplicación. En cualquier caso, el shell proporciona un excelente rendimiento para la ejecución de sus procedimientos (shell script es el término con el que generalmente se denominan los archivos de comandos) y con este sistema se han desarrollado varias aplicaciones. En este capítulo, primero veremos algunas funciones de shell que aún no hemos cubierto, luego hablaremos sobre la programación de shell y, finalmente, cubriremos usos de shell más avanzados. Finalmente, tenga en cuenta que este capítulo trata sobre el shell Bourne estándar y las características básicas del shell Korn; La programación de shell C es muy diferente. El Capítulo 16 trata sobre la programación de shell Korn y C, y analiza muchas características de estos shells avanzados. 8.1 Comandos multilínea El shell puede aceptar una línea de comando que tenga una longitud que exceda los límites impuestos por el tamaño de la pantalla. Esta situación suele ocurrir en el caso de canalizaciones complejas que constan de muchos comandos y nombres de archivo muy largos. Hasta que introduzca un retorno de carro, si cruza los márgenes de línea, la mayoría de los terminales colocan el cursor al comienzo de la siguiente línea para permitirle completar el comando; cuando escribe un retorno de carro, el shell 1 comienza a procesarse. El comando se trata como una sola línea incluso si abarca físicamente varias líneas terminales. El shell interpreta correctamente los comandos multilínea, que también puedes crear en video de forma artificial, dividiendo lógicamente la línea de comando en varias líneas, para facilitar su legibilidad. Para hacer esta división en líneas separadas, preceda el retorno de carro con \, lo que obliga al shell a ignorar la nueva línea y le permite continuar con el comando en la línea siguiente. Un comando multilínea también puede ocurrir si abre comillas para un argumento del comando que lo requiere y no las cierra antes del retorno de carro. En ambos casos, el shell recuerda la parte del comando que ya ingresó y muestra un mensaje que no es $, pidiéndole que ingrese la parte faltante del comando, por ejemplo: $ cat /etc/profile \ > El nuevo mensaje, que se llama PS2 (cadena de mensaje de segundo nivel, mientras que mensaje$ tiene la abreviatura PSl) se puede configurar y hacer global como cualquier otra variable de entorno, por ejemplo: $ echo $PS2 > $ PS2 ='otro:' $ echo$PS2 otro: $ En este caso, originalmente inicializamos el indicador de PS2 en > pero, independientemente del símbolo que lo represente, PS2 informa que el comando que ingresó desde el teclado está incompleto y que el shell está esperando más caracteres de entrada. Puede cancelar el comando si, en el indicador de PS2, presiona la tecla DEL. Esta operación provoca la eliminación del texto del comando almacenado hasta ese momento y la visualización del indicador PSI (generalmente $) que indica que el shell está listo para aceptar otro comando. INTRODUCCIÓN DE DATOS EN EL PROCEDIMIENTO SHELL (AQUI DOCUMENTOS) El shell interpreta correctamente los comandos de varias líneas, pero en dos casos particulares deja de analizar y muestra el segundo aviso de PS2. En primer lugar, si altera la función real del retorno de carro escapándolo con \ o no delimita correctamente un argumento, el shell no ejecuta el comando que emitió, pero muestra el indicador de PS2 para indicarle que complete la línea de comando correctamente. En segundo lugar, algunos operadores de shell tienen un rango de varias líneas, por lo que un comando puede contener algunos caracteres de nueva línea que actúan como divisores sintácticos de línea de comando. Un ejemplo de este segundo caso se llama aquí documento, entrada directa de datos en el procedimiento de shell, un proceso de adquisición inmediata de datos de entrada que se ingresan directamente en el procedimiento de shell en lugar de almacenarse previamente en un archivo. El operador de shell < saludos > hola >MARCADOR saludos hola $ muestra en la entrada estándar los datos que ingresa directamente desde el teclado después de terminar la línea de comando con el carácter de retorno de carro. El shell se da cuenta de que la línea de comando introduce una operación de entrada de datos directa, muestra el aviso de PS2 para recibir y almacenar las líneas de entrada y, cuando encuentra el marcador de cierre, ejecuta el comando usando los datos ingresados ​​como entrada estándar. Cuando finaliza, muestra el aviso de PSl y espera el siguiente comando. En este ejemplo, el shell interpreta el carácter de retorno de carro como un marcador de fin de línea, pero no como un marcador de fin de comando porque primero debe ingresar datos desde el teclado. Solo cuando haya terminado esta operación especificando la cadena de cierre (es decir, MARKER en el ejemplo anterior), el shell interpreta el siguiente carácter de nueva línea como la señal de fin de comando y luego muestra los resultados producidos por el comando cat en separado. líneas. Hay varios otros casos de uso de comandos de varias líneas en los que aparece el indicador de PS2, mientras que todos los comandos normales muestran PS2 como un error. La entrada directa de datos es mejor que la redirección de entrada estándar cuando tiene la intención de usar variables de shell en los datos, porque el comando lee un archivo redirigido directamente, mientras que el shell examina primero los datos ingresados ​​​​en el procedimiento y luego los entrega al comando. Por ejemplo: $ cat - << HereDocuments >Mi ID de inicio de sesión es $LOGNAME > AquíDocumentos Mi identificación de inicio de sesión es george $ Además de las variables de shell, también puede usar el operador (acento grave) en los datos que ingresa en el procedimiento de shell, para hacer referencia a la salida estándar de una línea de comando. El siguiente ejemplo: $ cat - << XYZZY > echo "Hay archivos 'ls $HOME: wc - I' en $HOME" > XYZZV hace posible combinar variables de shell y los resultados producidos por otros comandos en un archivo de texto. 8.2 Archivos de comandos de shell Cualquier comando, o secuencia de comandos, que pueda ingresar directamente desde la terminal también puede almacenarse en un archivo y ejecutarse más tarde. Los métodos de ejecución de los comandos almacenados en un archivo coinciden con los adoptados para los comandos que se escriben directamente desde el teclado, en este caso el shell asegura que el archivo y no el terminal esté conectado a la entrada estándar. Una forma de ejecutar comandos almacenados en un archivo es especificar el nombre del archivo como argumento para el comando sh que inicia una subcapa, por ejemplo: $ cat cmd.file echo $LOGNAME pwd $ sh cmd.tile giorgio /home/giorgio $ El archivo cmd.file - ejemplo de un archivo de comando corto - en este caso contiene los dos comandos echo $LOGNAME y pwd que ejecuta el comando sh cmd.file, almacenando los resultados producidos en la salida estándar. Otra forma de ejecutar el comando es la siguiente: $ chmod u + x cmd.file $ cmd.tile giorgio /home/giorgio $ Si se puede acceder al archivo de comandos durante la ejecución, no es necesario crear explícitamente un subshell que lo ejecute porque el shell de inicio de sesión se encarga de ello de manera predeterminada. De esta forma, un archivo de comandos se puede ejecutar como un programa binario y apenas se pueden distinguir los dos tipos de comandos. En un archivo de comandos, cada comando ocupa una línea, manteniendo en cada caso la misma estructura que hubieras utilizado al ingresar los mismos comandos desde el teclado; puede utilizar todas las funciones que están disponibles desde el terminal. Por ejemplo, a menudo es conveniente definir variables de shell que tengan un tiempo de vida igual a la duración de la ejecución: $ cat cmd2.file DIR='pwd' echo $DIR $ cmd2.file /home/giorgio $ La variable DIR se establece en el nombre del directorio actual y luego echo $DIR lo muestra. Las variables de shell inicializadas de esta manera solo se conocen dentro del archivo de comandos en el que están definidas, pero no son válidas cuando el shell de inicio de sesión recupera el control después de que el archivo ha terminado de ejecutarse. Del mismo modo, los comandos que defina en los archivos tampoco son visibles para el mundo exterior. $ cat cmd3.file pwd echo Cambio de directorio.... cd /home/leo pwd $ cmd3.file /home/giorgio Cambio di directorio.... /home/leo $ pwd /home/giorgio $ Puede cambiar directorios dentro del archivo de comando, pero la operación cd no tiene efecto en el resto de la sesión. Dado que el sistema no distingue un archivo de comandos de un programa binario ejecutable, los procedimientos de shell pueden contener otros procedimientos dentro de ellos, que se consideran comandos reales. No olvide el uso de la exportación para todas las variables locales que desee usar, incluso en subrutinas o procedimientos jerárquicamente subyacentes. COMENTARIOS EN ARCHIVOS DE COMANDO Los archivos de comandos guardados en un archivo, especialmente si son grandes y muy complejos, generalmente se comentan para que sean más fáciles de leer. En particular, en la notación de shell, el operador # representa el carácter de comentario inicial pero, si usa este carácter como un símbolo de eliminación, debe descodificarlo prefijándolo con un carácter \ antes de poder usarlo como un identificador de comentario. El shell ignora, para fines de implementación, todo lo que sigue al carácter # en la misma línea: $ # cat /etc/passwd $ echo hola #Aquí hay un ejemplo de un comentario al final de la línea hola $ 8.3 El operador if El shell tiene facilidades para controlar el flujo de ejecución de un archivo de comando. Examinemos si, lo que le permite tomar decisiones. La sintaxis de este comando es simple: El ejemplo aparece en una línea, pero if puede abarcar varias líneas que terminan en fi (el inverso de if). Además, expresión representa cualquier expresión lógica o comando que devuelve un valor. Si la expresión consiste en un valor devuelto de cero, el shell ejecuta los comandos que componen la sección entonces, hasta que encuentra el operador de cierre fi. Por ejemplo: $ if true ; then echo hola ; fi hola $ if false ; then echo hola ; fi $ El personaje ; (punto y coma) separa las diferentes secciones de estos comandos, que generalmente se organizan en varias líneas, mientras que el aviso de PS2 le recuerda que el comando está incompleto. $ if true > then > > fi echo hola hola $ Los caracteres retorno de carro y ; (punto y coma) tienen el mismo significado en este contexto, es decir, ambos cumplen la función de delimitadores de los componentes del comando, por lo que siempre se debe garantizar la presencia de al menos uno de ellos. El ejemplo anterior presenta el operador lógico especial verdadero, que puede usar en los archivos de comandos. Este operador siempre devuelve cero, por lo que obliga a la estructura if a ejecutar solo los comandos que componen la sección then. También existe el operador lógico falso, que siempre devuelve un valor distinto de cero. $false $ echo $? 1 $ Recuerde que $ es una variable de shell que contiene el valor de retorno del último comando ejecutado. En la sección entonces de la instrucción if, puede ingresar tantos comandos como desee y anidar otros comandos if. $ if true > then > echo hola $ if expresión; then comando ; fi El ejemplo aparece en una línea, pero if puede abarcar varias líneas que terminan en fi (el inverso de if). Además, expresión representa cualquier expresión lógica o comando que devuelve un valor. Si la expresión consiste en un valor devuelto de cero, el shell ejecuta los comandos que componen la sección entonces, hasta que encuentra el operador de cierre fi. Por ejemplo: $ if true ; then echo hola ; fi hola $ if false ; then echo hola ; fi $ El personaje ; (punto y coma) separa las diferentes secciones de estos comandos, que generalmente se organizan en varias líneas, mientras que el aviso de PS2 le recuerda que el comando está incompleto. $ if true > then > > fi echo saludos saludos $ Los caracteres retorno de carro y ; (punto y coma) tienen el mismo significado en este contexto, es decir, ambos cumplen la función de delimitadores de los componentes del comando, por lo que siempre se debe garantizar la presencia de al menos uno de ellos. El ejemplo anterior presenta el operador lógico especial verdadero, que puede usar en los archivos de comandos. Este operador siempre devuelve cero, por lo que obliga a la estructura if a ejecutar solo los comandos que componen la sección then. También existe el operador lógico falso, que siempre devuelve un valor distinto de cero. $false $ echo $? 1 $ Recuerde que $ es una variable de shell que contiene el valor de retorno del último comando ejecutado. En la sección entonces de la instrucción if, puede ingresar tantos comandos como desee y anidar otros comandos if. $ if true > then > echo saludos > echo 'pwd' > fi saludos /home/giorgio $ Las versiones más complejas de la parte de la expresión de la instrucción if se tratan más adelante en este capítulo. Para indicar la bifurcación en la construcción if, use el operador else que delimita una secuencia de comandos que se ejecutan cuando la parte de la expresión se evalúa como un valor distinto de cero. $ if false ; then > echo saludos >else > echo hola > fi hola $ Además, la sección else no tiene limitaciones en cuanto al número de comandos que pueden componerla. Otras construcciones if pueden seguir al operador else si es necesario y se identifican mediante la forma contraída elif (else if). $si es falso; entonces > eco hola > elif verdadero; entonces > eco hola > fi HOLA ps La presencia de la sección entonces después de elif es obligatoria y toda la construcción se delimita nuevamente con fi. 8.4 El comando de prueba Hasta ahora, hemos presentado una versión simple de la estructura if que es tan simple que los ejemplos discutidos probablemente no hayan sido de mucha utilidad, por lo que ahora dirigimos nuestra atención a nuevas estructuras de control que realizan operaciones lógicas más complejas. Por ejemplo, es muy conveniente tener una función que compare dos números y, si el resultado de la comparación es positivo, examine la sección entonces, o tener una función que verifique la existencia de un archivo y, en función del resultado de esta verificación, ejecuta un conjunto de comandos. Para realizar estas y muchas otras funciones usamos el comando test, que siempre sigue la estructura de control if y define los valores de verdad (o códigos de retorno) en los que se basa la prueba condicional. Hay dos versiones del comando de prueba que puede usar indistintamente en los archivos de comando, pero para mayor coherencia y claridad, elija una y déjela sin cambios. La primera forma del comando de prueba consiste en el nombre del comando, seguido de algunos argumentos que ahora analizaremos. $ if test $VAR > then > echo saludos > fi $ Si no se ha definido la variable de entorno VAR, la expresión de prueba $VAR falla y si considera que el resultado es falso. Si, en cambio, se ha definido la variable de entorno, entonces la prueba es exitosa. $ if test $HOME > then > echo saludos > fi saludos $ La otra forma de prueba utiliza los operadores especiales [y] (corchetes). Los argumentos de prueba están entre paréntesis, pero el término prueba no aparece. $ if [ $HOME] > then > echo saludos > fi saludos $ Como con todos los operadores, debe delimitar los corchetes con caracteres de espacio, de lo contrario, el shell no interpretará la línea de comando correctamente. Tenga en cuenta que el significado de los corchetes en este contexto difiere del discutido cuando discutimos cómo los nombres de archivo se expanden usando metacaracteres, pero el shell interpreta el significado actual de los corchetes dependiendo de si siguen o no al operador if. La naturaleza de los argumentos contenidos entre corchetes determina el tipo de prueba a realizar. El comando de prueba realiza algunas operaciones de archivo, realiza comparaciones numéricas, comparaciones de cadenas de caracteres y los valores de las variables de entorno. En todas las formas del comando, los espacios deben separar los paréntesis y cada operador. La expresión -f archivo (archivo) se evalúa como verdadera si el archivo existe y es un archivo normal; Por ejemplo: $ if [ - f /etc/passwd ] ; then echo el archivo existe ; fi el archivo existe $ De manera similar, la expresión -r archivo (legible) se evalúa como verdadero si el archivo existe y es accesible para lectura; -w archivo (escribible) es verdadero si el archivo existe y se puede escribir; la expresión - x archivo (ejecutable) devuelve verdadero si el archivo existe y es ejecutable; -d archivo (directorio) devuelve verdadero si el archivo existe y es un directorio; la expresión -s archivo es verdadera si el archivo existe y tiene un tamaño mayor que cero. Existir puede usar otros operadores en archivos, pero su uso es bastante raro. Los operadores de comparación de cadenas comprueban la presencia y el valor de las variables de entorno. Esto le permite realizar algunas operaciones, asignar el valor a una variable de entorno y luego probar su valor para decidir qué acción tomar. Por ejemplo, puede ejecutar comandos particulares si se encuentra en un directorio específico: $ DIR='pwd' $ if [ $DIR = $HOME ] > then > echo En el directorio preferido! > fi En el directorio preferido! $ El operador = (igual) comprueba si las dos cadenas de caracteres son idénticas y devuelve el valor verdadero si las cadenas coinciden, el valor falso en caso contrario. ¡Puedes usar el operador! = que devuelve verdadero si las cadenas no son iguales. Todos estos operadores deben estar separados de los corchetes y los argumentos restantes que están dentro de los corchetes por caracteres de espacio. También es posible que los paréntesis contengan solo una cadena o variable de entorno para determinar si se ha realizado su definición. $ if [ "$NOVALUE" ] ; then echo saludos ; fi $ Si no se ha definido la variable de entorno NOVALUE, la prueba devuelve falso y, por lo tanto, la sección entonces no se ejecuta. El constructor NOVALUE está protegido en este ejemplo, porque si la variable no estuviera definida, no se realizaría ninguna sustitución entre los corchetes, lo que daría como resultado que no contiene nada, y la prueba informa un error. La protección con comillas hace que el valor de la expresión se reemplace con una cadena vacía, en lugar de no reemplazarla, si NOVALUE no está definido. Los operadores = y ! = están reservados para comparar cadenas, pero no valores numéricos. El comando de prueba puede comparar números enteros, pero la programación de shell no es adecuada para resolver problemas numéricos, a diferencia de la mayoría de las otras herramientas de programación. La comparación numérica con el comando de prueba toma la siguiente forma: if [ n1 - eq n2 ] donde nl y n2 son expresiones numéricas. El operador -eq (igual) devuelve verdadero si los dos números son iguales. $ echo $VAL 2 $ if [$VAL -eq 2] > then > echo igual > fi igual $ Otros operadores numéricos son - ne (no igual), - gt (mayor que), - lt (menor que) y - le (menor que o igual). El operador de desigualdad -lt devuelve verdadero si el primer número es menor que el segundo; los otros operadores también siguen esta sintaxis. Estos operadores numéricos se utilizan a menudo para verificar el valor devuelto producido por algún comando o canalización y tomar medidas relacionadas si el valor devuelto satisface requisitos particulares. La mayoría de los comandos devuelven cero si se completan correctamente. $ mkdir /tmp/SS $ RET=$? $ if [ $RET - eq o I > then > echo "mkdir ha terminado correctqamente" >else > echo "El directorio no pudo ser definido" > fi mkdir ha terminado correctamente $ Todas estas construcciones se pueden ingresar directamente desde la terminal, sin embargo, se usan más comúnmente en los procedimientos de shell. El comando de prueba define otras herramientas que le permiten combinar operadores con expresiones complejas predefinidas. ¡El operador! tiene la función de negar el significado lógico de cualquier otro operador, como se indica a continuación: $ if [ ! - f file J > then touch file > > fi $ # esto crea el archivo Este comando crea un archivo si aún no existe. Otros operadores combinables disponibles para probar son -o (o) y -a (y) que se utilizan para separar otros operadores. $ F1 = file1 ; F2 = file2 $ if [ ! - f $F1 - a - f $F2 ] > then > echo "$F1 no existe, pero $F2 existe" > fi $ Puede combinar estos operadores en expresiones muy complejas y agrupar operadores complejos entre paréntesis si es necesario. En la práctica, sin embargo, es mejor mantener los comandos de prueba relativamente simples. 8.5 El comando de salida Puede utilizar el comando de salida en los archivos de comandos para terminar inmediatamente su ejecución. El comando de salida tiene un argumento que se convierte en el valor que el procedimiento devuelve al shell de llamada. $ cat cmd4.file if true > then > exit 6 > fi $ sh cmd4.file $ echo $? 6 $ Cuando se utilizan valores de retorno de archivos de comandos, se aplican las convenciones habituales: los comandos que terminan correctamente devuelven el valor cero, mientras que los valores distintos de cero codifican varias condiciones posibles de error 8.6 El comando expr Aunque el lenguaje de programación del entorno de shell no se adapta perfectamente al procesamiento numérico, también hay comandos que pueden realizar cálculos. Entre estos, el más importante es el comando expr (expresión) que toma operadores aritméticos y números como argumentos, los procesa y devuelve el resultado en la salida estándar. $expr4+5 9 $ Puede usar comandos más complejos, separando cada sección de la expresión con caracteres de espacio, porque expr trata cada argumento como parte de la expresión que se va a evaluar. Puede especificar números enteros, así como los operadores + (más), - (menos), * (multiplicación), I (división) y % (resto); los operadores * e I deben estar precedidos por \ para evitar que el shell los interprete antes de que expr los evalúe. $ expr 3 \ * 4 + 2 \ I 2 13 $ Se aplican las reglas habituales de precedencia aritmética, en las que las expresiones 3*4 y 2/2 se evalúan antes que el operador +. No puede modificar las reglas de precedencia en la línea de comando, pero puede dividir fácilmente los cálculos complejos en operaciones separadas. $ VAL='expr 3'-• 4 + 2' $ expr $VAL '- I 2 7 $ Este ejemplo muestra cómo se usa normalmente el comando expr en los archivos de comandos; Las variables de entorno toman valores numéricos que luego emplean otros comandos expr o incluso operaciones de prueba. Además, puede agrupar operaciones entre paréntesis, siempre que estén protegidas, por ejemplo: $ expr 3 \ * \( 4 + 3 \) \ I 2 10 $ El comando expr también puede realizar operaciones lógicas, es decir, determinar si un argumento es igual, mayor o menor que otro. Los operadores = (igual), ! = (diferente), > (mayor que}, < (menor que), > = (mayor que o igual), < = (menor o igual); estos operadores deben estar protegidos porque muchos contienen caracteres de interpretación especial en el shell , por ejemplo : $ X='expr 4 \< 5' $ echo $X 1 $ X='expr 4 = 5' $ echo $X o $ Si los argumentos de estos operadores lógicos son numéricos, expr realiza comparaciones numéricas; si los argumentos son cadenas, expr compara según la secuencia de clasificación o la secuencia de clasificación de cadenas en el alfabeto ASCII. 8.7 El operador for Otros operadores en el lenguaje de programación shell definen construcciones iterativas que le permiten ejecutar repetidamente una parte del archivo de comandos. Entre estos operadores, uno de los más representativos es for, cuya sintaxis es: $ for var en vano ... falla ; do comandos ; done donde var es una variable de entorno así definida y vall,valn constituye el elemento genérico de una lista, cada elemento del cual está separado del otro por un carácter de espacio. Por ejemplo: $ for VAL en 1 2 3 4; do comandos; done Cuando el shell interpreta este comando, asigna el primer elemento de la lista a VAL y luego ejecuta los comandos especificados entre do y el done correspondiente. Luego, el shell asigna el segundo elemento de la lista a VAL y ejecuta nuevamente los comandos indicados, repitiendo este proceso hasta que termina de examinar todos los elementos de la lista. El valor de VAL está disponible en la lista de comandos: $ for VAL in 1 2 3 4 >do > echo $VAL > done 1 2 3 4 $ El número de comandos que puede especificar entre los delimitadores do .. done no está particularmente limitado, y también puede ingresar estructuras de control if .. fi u otras estructuras iterativas. El for construction se puede usar para iterar en archivos; Dado que el shell interpreta el comando for, se realiza la expansión habitual con comodines, por ejemplo: $ for FILE in * ; do echo $FILE ; done Dado que el metacarácter * se reemplaza por los nombres de todos los archivos, este comando muestra los nombres de todos los archivos en el directorio actual en la pantalla. Una forma particularmente ineficiente de contar los archivos contenidos en un directorio podría ser la siguiente: $ COUNT=0 $ for FILE in * >do > COUNT = 'expr $COUNT + 1' > done $ echo $COUNT 14 $ La variable de entorno que sigue al comando for debe estar presente con el único propósito de especificar el número de iteraciones que debe realizar el comando for, no es obligatorio usarla de otra manera. La salida estándar de un comando también puede crear la lista de elementos para el comando for, por ejemplo: $for VAR in 'ls' > do > echo $VAR > done El comando es aceptable porque el shell ejecuta el comando ls, genera una salida dentro del comando for y luego ejecuta el comando completo. El comando for tiene muchos usos, tanto en archivos de comandos como directamente desde la terminal, porque te permite iterar sobre una lista de objetos, ejecutando una cierta cantidad de comandos en cada elemento de la lista. En conclusión, podemos decir que el comando for es uno de los operadores de shell más utilizados. 8.8 El operador while y until El operador while resume algunas características de for y algunas características de if. Consiste en un comando de prueba y luego una sección do .. done. Si la sección de prueba tiene éxito (verdadero), se ejecuta la sección do .. done; si la sección de prueba falla (falso), la sección do .. done no se ejecuta y el ciclo termina. Cuando la sección do .. done ha terminado, el comando while examina la sección de prueba nuevamente y el ciclo finaliza cuando el resultado de esta verificación es negativo (falso), por ejemplo: $ while [ ! - f file ] > do > echo Creando un archivo > touch file > done Este ejemplo representa un intento de crear un archivo, repetido hasta que la operación tenga éxito. Tienes que ponerlo dentro de la sección do.. hecho algunos comandos para modificar el resultado de la prueba, de lo contrario, el ciclo continúa indefinidamente. Este ejemplo crea diez archivos, llamados filel, file2 a filel0. $ VAL=1 $ while [$VAL -lt 11 ] > do > touch file$VAL > VAL='expr $VAL+ 1' > done Este comando se puede escribir de otra manera: $ for VAL in 1 2 3 4 5 6 7 8 9 10 > do > touch file$VAL > done Puede colocar cualquier comando, incluidas otras estructuras while iterativas, dentro de una sección do..done. Puede reemplazar la palabra clave while con hasta para invertir el significado de la prueba. En otras palabras, la estructura while ejecuta repetidamente los comandos especificados en la sección do .. done cuando la parte condicional es verdadera, mientras que la estructura hasta ejecuta los comandos si la parte condicional es falsa. En un archivo de comandos, es una buena práctica sangrar cada subnivel de comandos con un carácter de tabulación, como hicimos en los ejemplos anteriores; esto ayuda a estructurar el programa de forma lógica y favorece la legibilidad sobre la escritura con todos los comandos alineados al margen izquierdo, o justo después del aviso de PS2. La sangría de comandos no afecta la forma en que el shell interpreta el programa, pero ayuda mucho a los usuarios a comprender la esencia del programa. 8.9 El operador de case El shell define el operador de control de casos que realiza una función análoga a la secuencia de comandos if-elif-elif-... elif-fi. Una vez especificada una cadena de caracteres, case establece a qué categoría, entre las indicadas, pertenece la cadena y luego ejecuta el conjunto de comandos que están asociados a esa categoría; las categorías no reconocidas se ignoran. El formato de una declaración de caso es el siguiente: $ case $VAR in > casol) > lista-comandi > ;; caso2) > lista-comandi > .. ,, > caso3) > lista-comandi > .. ,, > > esac El número de casos y comandos de la estructura case no está sujeto a ninguna limitación, pero existen reglas sintácticas precisas. Primero, la lista asociada a cada caso debe tener el operador especial ;; como delimitador de cierre. Además, cada caso debe ser diferente de los demás y debe cerrarse con el operador) (cerrado entre paréntesis). VAR representa una variable de entorno o cualquier expresión que sea igual a una cadena de caracteres; toda la estructura de control debe terminar con la palabra clave esac (opuesto al caso). Como de costumbre, puede anidar cualquier otro operador de shell en una estructura de caso. El siguiente comando muestra un mensaje de saludo a los usuarios de la máquina. $ case $LOGNAME in > leo) > > > pat) > > > giorgio) > > > > > esac echo Hola Leo, bienvenido echo de tus vacaciones .. " echo Pat, no olvides leer tu correo .. " echo Elimina algunos archivos, estas usando echo demasiado espacio en el disco ... Gracias! .. " Dicho procedimiento normalmente se almacenaría en un archivo y los usuarios lo ejecutarían cuando iniciaran sesión en el sistema; o podría insertarse como parte del perfil de inicio de sesión que trataremos en el siguiente párrafo. La sección de casos del árbol de control de casos le permite usar expresiones regulares definidas con metacaracteres de shell. En el ejemplo anterior, podríamos especificar gior•, •r•, ?giorgio o alguna otra forma que represente la cadena giorgio. Además, puede usar el carácter : (tubería) para indicar un OR lógico en la sección de casos, como se muestra a continuación: $ case $LOGNAME in > giorgio: leo) > echo no olvides la reunión de hoy > *) > > > > esac ;; echo Bienvenido a nuestro sistema UNIX .. " En el primer caso, el mensaje se dirige a giorgio o leo, mientras que en el segundo caso, el metacarácter * coincide con cualquier cadena y se usa para enviar un mensaje de bienvenida a todos los demás usuarios. El case final *) se puede utilizar generalmente como el caso por defecto, que agrupa todo lo que no está asociado a los casos definidos. Tenga en cuenta que ejecutar el comando case ejecuta solo la sección que primero satisface los criterios de asociación de casos. Si ningún caso cumple con estos criterios, la declaración del caso se ignora. 8.10 El comando printf y la salida de archivos de comando El medio principal para obtener resultados de un procedimiento de shell es el comando echo, que se usa con frecuencia en los ejemplos anteriores. Proporciona una forma rápida y fácil de generar cadenas de caracteres simples y valores de variables de entorno. Para formatos más complejos de salida de caracteres, está disponible el comando printf, que proporciona un subconjunto orientado a cadenas del lenguaje y capacidades de subrutina printf(3). El comando printf espera dos tipos de argumentos. La primera es una especificación de formato, una cadena de caracteres que especifica el formato general de la salida y puede incluir secuencias especiales que serán reemplazadas por los datos reales. El segundo tipo de argumento para printf es una lista de cadenas; debe haber tantas cadenas como secuencias especiales hay en la especificación de formato. Las secuencias especiales se denominan especificaciones de conversión y definen la forma en que se imprimen las variables; Por ejemplo: $ printf "esta es una cadena: O/os\n" 1234567890 esta es una cadena: 1234567890 $ El primer argumento (protegido con ") contiene la especificación de formato; los caracteres normales, como esta es una cadena: simplemente se imprimen. La secuencia especial %s representa una especificación de conversión; cada cadena (o comando que da como resultado una cadena) sigue el formato La especificación reemplaza la especificación de conversión correspondiente dentro de la especificación de formato en orden. Los argumentos de cadena no utilizados son ignorados por printf, pero las especificaciones de conversión no utilizadas producen resultados impredecibles. Muchas versiones de printf (l) están orientadas solo a cadenas, otros tipos de conversión, como %d y %e normalmente no se esperan. Se pueden usar algunas secuencias particulares en la especificación de formato: \n genera un retorno de carro, \t inserta un carácter de tabulación. El ejemplo anterior de printf parece ser solo una forma más complicada del comando echo, pero printf es útil cuando necesita truncar una cadena de caracteres a una longitud corta o cuando necesita insertar la cadena en un campo definido en la línea de salida. . En la especificación de conversión, puede insertar números entre % y s para controlar el posicionamiento de la cadena de salida y especificar un ancho de campo mínimo, por ejemplo: $ printf "cadena en campo de 20 caracteres: >%20s<\n" 1234567890 cadena en campo de 20 caracteres: > 1234567890< $ Para justificar la cadena a la izquierda, ingrese - (menos) antes del valor numérico; Por ejemplo: $ printf "cadena justificada a la izquierda: >%-20s<\n" 1234567890 cadena justificada a la izquierda: > 1234567890 $ Puede truncar la cadena al incluir un en la especificación de conversión. seguido del número del ancho del campo de salida, por ejemplo: $ printf "cadena truncada a 5 caracteres: >%-5s<\n" 1234567890 cadena truncada en 5 caracteres: >12345< $ El comando printf se usa a menudo para truncar una cadena cuando se asigna a una variable de entorno, por ejemplo: $ XXX= 'printf "%.4s\n" "1234567890"' $ echo $XXX 1234 $ Puede usar este método en sus programas de shell para derivar subcadenas de cadenas más largas. 8.11 Los archivos de comando .profile y /etc/profile Un ejemplo significativo de un archivo de comando, que cada usuario generalmente define y administra personalmente, es un archivo que el sistema ejecuta durante la fase de inicio de sesión para definir el sistema y el perfil del usuario. Este archivo de comando, llamado perfil, le permite adaptar la sesión de inicio de sesión a sus necesidades y declarar variables de entorno de uso general. Conceptualmente llama al archivo AUTOEXEC.BAT bajo MS-DOS, excepto que cada usuario puede tener su propia versión particular de perfil. En realidad, cuando ingresa al sistema, se ejecutan dos archivos separados. El primero de ellos es del sistema y configura el ambiente de trabajo en base a los derechos de acceso al sistema; este archivo está contenido en /etc/profile y todos los usuarios tienen acceso de lectura a él. El archivo /etc/profile se ejecuta primero, justo después de iniciar sesión en el sistema. No hablaremos de ello extensamente en este texto, pero le recomendamos que examine su contenido en el sistema de su máquina. Cuando el administrador del sistema cambia el entorno de trabajo para todos los usuarios, por ejemplo, agregando un nuevo directorio a la variable PATH, el cambio se logra editando /etc/profile. El segundo perfil lo ejecuta el sistema, antes de que el shell muestre el primer aviso$, pero después de ejecutar /etc/profile; este es el archivo .profile ubicado en su directorio de inicio. El comando ls generalmente no detecta la presencia de .profile en su directorio de inicio, porque el . (punto) evita que el comando lo muestre. Si especifica la opción - a (ali) en su lugar $ ls-a el comando muestra .profile junto con todos los demás archivos que comienzan con el carácter. contenida en el directorio de inicio. Puede usar su archivo .profile para adaptar el entorno de trabajo a sus necesidades más de lo que es posible con el archivo /etc/profile, porque en .profile puede almacenar sus propios comandos y hacer que el sistema los ejecute cuando se conecte. UN EJEMPLO DE ARCHIVO .profile El administrador del sistema, al definir su identificador de inicio de sesión, le asigna un archivo .profile simple, que rara vez satisface sus necesidades. En cuanto te familiarices con el sistema UNIX, probablemente te interese adaptar el entorno de trabajo a tus necesidades más precisas. La figura 8.1 muestra un archivo .profile típico que sugiere los tipos de cambios que normalmente se realizan en el entorno de trabajo. Incluso si solo algunos de estos cambios son necesarios, aún puede hacer que la sesión sea más agradable al satisfacer sus necesidades y evitar errores en el sistema. Primero, la variable PATH se redefine para identificar el directorio actual y un archivo binario privado con prioridad sobre los comandos del sistema; esto le permite reemplazar algunos comandos normales con sus propios comandos. Tenga en cuenta, sin embargo, que esto representa un riesgo de seguridad si todos los usuarios tienen acceso de escritura a los directorios, ya que alguien podría poner una versión incorrecta de un comando en su directorio, anulando la predeterminada. La variable PATH también contiene, al principio o al final, el directorio actual. Siguiendo las operaciones descritas, el comando çstty configura el terminal para habilitar el control de flujo (XON/XOFF}, para reemplazar los caracteres de espacio con caracteres de tabulación donde sea posible y para asociar la función de eliminar con la tecla +-. La opción echoe induce al sistema a retroceder -espacio-retroceso cuando presionas +-. Además, .profile le permite asignar los símbolos de su elección a las indicaciones de PS1 y PS2. El archivo .profile de la Figura 8.1 define los terminales que puede utilizar. En primer lugar, la variable de entorno PORT local se utiliza en el comando de prueba para determinar si se encuentra en una consola del sistema o en un terminal remoto. En la consola, .profile inicializa correctamente la variable TERM, por lo que esta larga sección if..fi no se ejecuta. En cambio, si no está trabajando en la consola, el archivo .profile requiere la introducción del tipo de terminal para establecer los parámetros apropiados. El comando read TEAM espera a que escriba una línea desde el teclado y luego la almacena en la variable de entorno TERM. La estructura de control de casos le permite ejecutar diferentes secciones de código dependiendo de lo que escribió desde el teclado, por lo que inicializa correctamente la variable TERM para cada terminal diferente. El comando de tabulaciones envía secuencias de escape relacionadas para inicializar los caracteres de tabulación en el terminal, en caso de que el term inal no pueda recordar los valores de tabulación cuando se desconecte la alimentación. El comando de tabulaciones, utilizado en la línea de comandos de tabulaciones de stty, le permite optimizar el tamaño de la salida en el terminal, reemplazando los caracteres de espacio con caracteres de tabulación. # Un ejemplo típico de un .perfil # Se puede modificar según sea necesario # Cambiar PATH para colocar directorios privados antes de los contenedores del sistema # Nota: cambiar la RUTA puede representar un riesgo de seguridad RUTA = :$INICIO:$INICIO/bin:/sbin:/usr/sbin:/usr/bin # configurar de nuevo el terminal con tab, XON/XOFF, # y "espacio- carácter de retroceso ~ espacio" para borrar stty pestañas echoe borrar h ixon ixoff ixany # editar avisos... PS1 = "[!] 'nombre' >" PS2=">>" # Examen del tipo de terminal y tratamiento diferenciado para cada uno # Terminal ... Si no estamos en consolas, podemos saltarnos # esta fase... POAT='tty' POAT = 'nombre base $POAT' si [ $POAT ! = consola]; entonces # solicitar tipo de terminal de sesión y tienda # del identificador en una variable de entorno echo "\nEQUIPO = \c" leer EQUIPO caso $ EQUIPO en S*) # PC AT&T UNIX if [ $EQUIPO = ss ] ; luego orzuelo cr2 nl1 ; fi EQUIPO=ansi stty-pestañas " computadora: 2621) # HP 2621 o emulador de terminal EQUIPO=2621 pestañas -Thp " ansi:vt) #DEC VT100, VT102 o VT200 EQUIPO=vt100 pestañas .. " •) # todos los demás son considerados # terminales tontas EQUIPO = tonto stty-pestañas exacto " fi Figura 8.1 Un ejemplo de un archivo .profile. # repite el identificador de terminal utilizado echo "EQUIPO =$EQUIPO" # esta sentencia es para el editor vi EXINIT = 'establecer ai' # Especificar el nombre del editor empleado EDITOR= /usr/bin/vi EDITAR = /usr/bin/vi # Para comandos "cd" CDPATH = :$INICIO:$INICIO/bin # Todas deberían ser variables globales exportar RUTA EQUIPO TERMCAP PS1 PS2 EXINIT EDITOR CDPATH EDIT # mostramos la fecha y la hora en tu casa # mostrar noticias aún no revisadas noticias # indicar si hay trabajo atrasado en "$HOME/mbox" if [-f mbox]; luego echo "Tienes correo antiguo"; fi # para usar el shell Korn FCEDIT = /usr/bin/vi VI SU AL= $FCEDIT CHEQUES POR CORREO = 60 ENV= "\$[-: +$HOME/.ksh.aliases\$[ - # # •i•]J" HISTFILE = $INICIO/.ksh.historial exportar ENV HISTFILE FCEDIT VISUAL MAILCHECK # finalmente, cambiamos del shell predeterminado a ksh exec /usr/bin/ksh Figura 8.1 Un ejemplo de un archivo .profile (continuación). La variable TERM puede tomar un valor diferente dependiendo de qué caso de la estructura de control case..esac se esté ejecutando; junto con esto, se inicializan otras variables de entorno: EXINIT, que es utilizada por el editor vi, EDITOR y EDIT, que indican qué editor es el más adecuado para un tipo de software en particular. Entre los diferentes tipos de software, la función de utilidad de ayuda también utiliza estas variables de entorno. También está CDPATH, que es una función de shell de utilidad avanzada que le permite definir una forma corta e inteligente del comando cd, que se trata al final de este capítulo. Finalmente, .profile otorga a sus subcapas acceso a todas estas variables de entorno, dándoles visibilidad global con la exportación. Después de estas operaciones, el archivo .profile realiza un pequeño trabajo administrativo. El comando de fecha muestra la fecha y la hora actuales, mientras que las noticias enumeran las últimas noticias no vistas. La breve estructura if..fi que sigue le recuerda el correo que tiene almacenado; normalmente debería haber eliminado el correo que ha estado procesando, por lo que la presencia del archivo mbox probablemente indica que hay alguna actividad pendiente. Finalmente, .profile inicializa otras variables de entorno asociadas con ksh, un shell alternativo al predeterminado, que el procedimiento inicia con el comando exec /usr/bin/ksh. Su .profile probablemente difiere de lo que hemos mostrado en esta sección, pero la mayoría de los cambios que realiza en su espacio de trabajo y proceso de inicio de sesión para satisfacer sus necesidades son parte de su archivo .profile. EL OPERADOR . Normalmente, el .profile se ejecuta automáticamente cuando inicia sesión en el sistema; sin embargo, mientras escribe y prueba su .profile, es extremadamente tedioso iniciar y cerrar sesión repetidamente en el sistema para realizar los experimentos necesarios. Debido a que las subcapas ejecutan scripts de shell particulares, los cambios que ha realizado en las variables de entorno dentro de la subcapa actual no persisten en el nivel de la capa principal, por lo que no puede ejecutar .profile como cualquier otro archivo de comando, aunque sea un archivo ejecutable normal. . Por lo tanto, los efectos que puede hacer .profile, como modificar la variable TERM, no generan cambios permanentes en su entorno si se ejecuta con el siguiente comando: $ sh .profile El shell define otro operador que le permite ejecutar un archivo mientras mantiene activo el entorno de shell actual, evitando crear un subshell que ejecute explícitamente el archivo. Este es el comando. (punto o punto) que toma como argumento el nombre del archivo que se quiere ejecutar. $ . .profile Cualquier archivo de comando es un argumento válido, pero el . generalmente se usa con .profile para realizar pruebas o para cargar un archivo de este tipo cuando una subcapa ejecuta otro archivo de comando. Los cambios realizados en el entorno de ejecución con . actualizan permanentemente el entorno actual (y las subcapas que se pueden crear más adelante), pero aún no modifican las capas de nivel superior existentes. 8.12 Argumentos de la línea de comandos Quedan por discutir muchos otros aspectos de la programación de shell, incluidos los argumentos de la línea de comandos. Puede escribir programas shell que procesen los argumentos de la línea de comandos de la misma manera que lo hacen otros comandos, si mantiene la sintaxis habitual en los argumentos de sus comandos. Con este fin, el shell proporciona varios operadores para manejar argumentos de línea de comandos que tienen una estructura habitual. LOS PARÁMETROS $#, $* Y LOS PARÁMETROS POSICIONALES Ya hemos discutido las variables de shell $ # y $*, que el shell interpreta como el número de parámetros de línea de comando para un archivo de comando y los valores de todos los parámetros, respectivamente. En este procedimiento echo $# for VAR in$* do echo $VAR done el shell expande la variable $* para representar todos los argumentos de la línea de comandos. Si el nombre del archivo de comando anterior es ECHO.ARG, puede ejecutarlo con un comando como: $ echo.arg primero segundo tercero donde los argumentos primero, segundo y tercero se pasan al fichero de comandos. $ echo.arg primero segundo tercero 3 primero segundo tercero $ Mirando la salida, el 3 es generado por el comando echo $ #, mientras que el resto de la salida producida por el primer segundo tercer comando echo.arg proviene de la ejecución del bucle for ..do.. done. También puede ubicar un único argumento de línea de comando mediante la notación $1, $2, $3, etc., hasta un máximo de nueve argumentos. Por ejemplo, el archivo de comandos que acabamos de ver también puede adoptar esta forma: echo $# echo $1 echo $2 echo $3 y los resultados que obtienes son los mismos. También puede usar estos argumentos para pasar nombres de archivos u otra información a un archivo de comandos desde la línea de comandos. Su utilidad generalmente solo se ve en archivos ejecutados como comandos, ya que el shell de inicio de sesión no tiene argumentos, por lo que $ echo $# o $ No se definen argumentos de línea de comandos para su shell de inicio de sesión, con una excepción: $0 es un argumento legítimo, al igual que $2, y devuelve el nombre del comando correspondiente. $ echo $0 sh $ El primer argumento de la línea de comando es $1. Además, el shell define un operador para inicializar estos argumentos de línea de comandos. $ echo $# o $ echo $2 $ set saludos hola tercero $ echo $# 3 $ echo $2 hola $ El operador set se usa a menudo en archivos de comandos y asigna sus argumentos a parámetros posicionales, por lo que los archivos de comandos pueden usar los identificadores $2, etc., incluso si no especifica ningún argumento en la línea de comandos. Por ejemplo, puede escribir un archivo que use sus parámetros de línea de comandos, pero si no los especifica, el archivo puede inicializarlos con los valores predeterminados. 8.13 Errores y mensajes de error en los procedimientos de shell Por supuesto, desarrollar un programa shell requiere mucho ensayo y error para lograr el resultado deseado. Si los archivos de comandos contienen errores formales, el shell proporciona mensajes de diagnóstico breves. $ for VAR in 'ls' do >saludos syntax error: 'saludos' unexpected $ El error que cometimos en este ejemplo es la omisión del carácter; o el carácter de retorno de carro antes de la palabra clave do, pero el mensaje de error del shell no da indicaciones exactas. Sin embargo, el shell puede proporcionar diagnósticos más completos, ya que los procedimientos del shell se ejecutan con mayor frecuencia desde archivos que desde la terminal. Puede seguir la ejecución de un programa de comando desde un archivo con el comando sh - x, como se muestra en la Figura 8.2. Se proporciona un seguimiento de ejecución, que muestra cada comando ejecutado, precedido por el carácter +, después de que el shell haya realizado sustituciones y manejado operadores, como prueba y otros operadores. Examinar el seguimiento de la ejecución de la prueba hace que sea mucho más fácil examinar el curso de la ejecución y localizar la condición que conduce al error. Otra ayuda para la configuración la ofrece la opción -v (verbose), que muestra, siempre en tiempo de ejecución, información detal lada sobre cada comando en el archivo de comandos, por ejemplo: $ sh -v shell.script primero segundo tercero echo $# 3 for VAR in$• ; do echo $VAR don y primero segundo tercero $ Las opciones -x y -v se pueden usar juntas para obtener resultados de diagnóstico más completos; esto se envía con un error estándar, por lo que puede guardarlo en un archivo separado de la salida normal. # cat shell.script echo $# tor VAR in$• ; do echo $VAR don e $ sh -x shell.script primero segundo tercero + echo 3 3 + echo primero primero + echo segundo segundo + echo tercero tercero $ 8.14 Perspectivas En estos primeros capítulos, ciertamente no hemos cubierto todas las formas de escribir y usar programas shell. Para aprender a programar con la shell es fundamental practicar mucho con pequeños archivos insertados directamente desde el terminal, pero también es interesante y útil para leer y readaptar los archivos de programa de otros usuarios. Algunos comandos son buenos ejemplos de procedimientos de shell y, por lo general, es difícil saber con certeza si un comando es un programa binario compilado o un procedimiento de shell accesible en ejecución. En la mayoría de los sistemas, los comandos /usr/bin/calendar, /usr/bin/spell, /usr/bin/basename y muchos otros son procedimientos de shell, que puede examinar de cerca para comprender cómo funcionan. shar: UN EJEMPLO DE ARCHIVOS DE COMANDOS La figura 8.3 muestra un ejemplo de complejidad moderada, generando otro procedimiento de shell. Esta es una versión simple del comando shar (archivo de shell), cuya función es crear un archivo que contiene varios otros archivos dentro de él. Una aplicación útil de este comando es cuando se transfieren archivos entre máquinas usando el correo electrónico o el comando uucp, donde cuantos menos archivos se transfieran, menor será la dificultad. #! /sbin/sh # shar: shell archive shell script # esegue in /sbin/sh # shar: raggruppa file nel formato di distribuzione "shar" # adatto per estrazione in ambiente sh o ksh, non csh. # argomenti della linea di comando non dichiarati # ci deve essere almeno un argomento if [ $ # - lt 1 ] ; then echo "uso: shar file1 file2 file3 ... fileN" exit 1 fi # ora iniziamo a creare il file di uscita in standard output. # Innanzitutto una intestazione generale .... echo '# NON USARE csh per disimpaccare questo file' echo '# Formato SHAR. Archivio creato "date' # viene trattato ciascun file: "$*" è la lista di argomenti for file in $* ; do # se il file non esiste, visualizziamo un messaggio, # ma non usciamo if [ ! \( -r $file -a -f $file\)] ; then echo shar: "Non è possibile archiviare $file" > /dev/tty continue fi # il file viene trovato, scriviamo in standard output il nome echo "echo x - $file" # scriviamo in standard output la linea di comando "sed", non eseguia- mo sed echo "sed 's(XJJ' > $file < <' + SHAR + MARK + "' # Qui eseguiamo il comando "sed" per avere 'X' come prefisso # su qgni linea inviata in standard output. sed 'si /Xl' $file # a fine file scriviamo in standard output il marcatore di fine dati echo " + SHAR + MARK + " # eseguiamo il comando "ls" sul file e serbiamo il risultato in un echo echo "echo "ls - I $file' (come inviato)'" # esaminamo i diritti di accesso in "ls - I", creiamo un # comando "chmod" e lo scriviamo in standard output ls - I $file : sed \ -e 'sf.\( ... \)\( ... \)\( ... \). */U = \ 1,g = \2,o = \3/' \ -e 's/-//g' \ - e 'si. •/chmod & "'$file/" # un comando "ls" per la procedura di uscita echo "ls - I $file" done # fine del ciclo echo "exit O" # comando exit in standard output Figura 8.3 Procedura di shell shar. El comando shar no tiene las mismas capacidades que otras herramientas de archivado de archivos porque solo trata archivos de texto y archivos en binario o compilado, pero se usa ampliamente para intercambiar datos entre sistemas UNIX. En la práctica, con el comando shar, puede crear archivos que contengan varios archivos de origen de tamaño limitado y luego enviarlos a otros usuarios que los descomprimen (descomprimen), es decir, separan y restauran los archivos originales. Como todos los buenos programas de comunicación, el programa shar realiza algunas comprobaciones para averiguar si alguna parte de los datos se ha perdido en el curso de las operaciones. Para ejecutar el programa shar, use la siguiente línea de comando: $ shar lista-nombres/archivo > archivo-temporal El comando lee los archivos indicados en la lista y devuelve el material archivado a la salida estándar, que generalmente se redirige a algún otro archivo, probablemente en un directorio diferente al que está procesando con el comando shar. El archivo producido por este procedimiento es en realidad un archivo de comando ejecutable y puede restaurar los archivos originales del archivo con el siguiente comando: $ sh /tmp/out.file o con $ chmod + x /tmp/out.file $ /tmp/out.file El comando shar proporciona un método para empaquetar archivos en un procedimiento de shell, y el programa que se muestra en la Figura 8.3 requiere un estudio cuidadoso. Hacemos una breve descripción. Las primeras líneas son simples comentarios; siempre debe incluir muchos comentarios en todos los programas para facilitar la comprensión. Las siguientes líneas verifican si el comando tiene argumentos de nombre de archivo y, si no, shar muestra un mensaje de error y sale. El programa real comienza con los comandos de eco; el procedimiento de shell shar ejecuta algunos comandos y escribe otros en la salida estándar con declaraciones de eco. Después de que se muestran algunos mensajes, comienza el bucle principal, en el que el operador de shell $* define la lista de argumentos para el procedimiento, cuyo número coincide con el especificado por $ #. En particular, $* representa los argumentos reales, separados por caracteres de espacio, mientras que $# representa solo el número de argumentos. Dentro del bucle, shar comprueba si cada archivo está realmente allí. La sección de prueba devuelve un valor positivo (verdadero) si el archivo es ilegible o si no existe. Usamos paréntesis para delimitar los operadores de prueba, y el carácter \ anterior evita malas interpretaciones por parte del shell. Si estas comprobaciones no encuentran el archivo, shar muestra un mensaje de error; para evitar que ingrese al archivo que está creando, la salida de echo se redirige directamente a la terminal con > /dev/tty. Las siguientes líneas no son triviales, ya que generan algunos comandos que se pueden ejecutar en el procedimiento de salida; de hecho, shar genera la información para incluir el archivo real dentro del procedimiento (ver aquí documento). El comando sed agrega una X al comienzo de cada línea del procedimiento producido que contiene datos de archivo; la secuencia de datos está cerrada por la línea echo + SHAR + MARK +. Las siguientes líneas restantes verifican que los archivos se hayan transferido correctamente. Primero, ls -1 genera el tamaño del archivo original, luego la línea echo ls -1 $file cerca del final del procedimiento hace que el extremo receptor ejecute el comando ls. Debe ser responsabilidad del destinatario verificar si los dos archivos tienen la misma longitud. El complicado comando sed transforma la salida de ls -1 en un comando chmod para inicializar correctamente los derechos de acceso en el archivo receptor, finalmente también se envía un comando de salida. Cuando se ejecuta shar, coloca los archivos especificados en su lista de argumentos en un nuevo procedimiento de shell ejecutable. Puede probar cómo funciona este procedimiento en su máquina, tal vez intente mejorarlo ya que no trata con archivos ubicados en subdirectorios. EL COMANDO getopts Hasta ahora, hemos tratado los nombres de archivo u otros argumentos de entrada como argumentos para los procedimientos de shell, sin embargo, la sintaxis normal de la línea de comandos también permite opciones, es decir, indicadores precedidos por el signo - (menos), que modifican el comportamiento habitual del comando. Los procedimientos de shell también pueden aceptar indicadores de opción de línea de comandos. El operador de shell getopts (obtener opciones) facilita el trabajo de analizar las opciones, ya que la colocación de banderas en la línea de comando no necesita ser forzada por criterios posicionales y, además, algunas banderas pueden asociarse con otros argumentos. El operador getopts, disponible en los sistemas SVR3 y SVR4, evolucionó a partir del antiguo getopt, que todavía se usa en versiones anteriores de UNIX. El operador le permite crear procedimientos de shell que pueden examinar los argumentos de la línea de comandos como otros comandos ejecutables. En particular, después de c ubrir las opciones y banderas de la línea de comandos, finalmente le permite usar la función set para asignar los argumentos restantes de la línea de comandos (no banderas, no opciones) a las notaciones usuales $1, $2, $3, etc. La Figura 8.4 muestra un ejemplo de procedimiento de shell usando la función getopts. La siguiente línea: while getopts yz:x VAR define un bucle de programa usando la función getopts, con dos argumentos asociados. El primero representa una lista de cartas de opciones aceptadas. #! /sbin/sh # Primero analizamos las opciones, asignándolas # variables de shell para indicar qué opciones han sido # definido. while getopts yz:x c do case $c in x) XFLAG=true y) .. " YFLAG=true .. z) " ZFLAG=true ZOPT = $0PTARG .. *) # OPTARG es el valor actual " echo $USAGE exit 2 .. " esac don y # ahora que hemos revisado todas las opciones, reduzcamos la lista por # argumentos solo para los restantes shift 'expr $OPTINO -1' # # # # XFLAG, YFLAG o ZFLAG pueden haberse inicializado de acuerdo con los argumentos de la línea de comandos. ZOPT se inicializa a "str" ​​si se dio la opción "-z str" A partir de aquí, puede seguir el resto del procedimiento de shell voluntario, que no contiene caracteres de espacio. En esta lista, cada letra que requiere un argumento va seguida del carácter: (dos puntos). El segundo argumento, es decir, VAR en el ejemplo, es una variable de entorno temporal que contiene el valor de la opción de línea de comando actual, que se asigna dentro del bucle while. Este bucle se ejecuta para cada argumento que aparece en la línea de comandos y, cuando se han examinado todos los argumentos, getopts devuelve false y el bucle while sale. Las opciones -x, -y y -z están permitidas, y la opción -z debe ir seguida de un argumento. Asumiendo que el nombre del procedimiento es script, las siguientes son líneas de comando correctas, entre muchas. $ script $ script -x $ script -y -x $ script -z hola $ script - x - z hola $ script -z hola -y La función getopts define la variable USO que informa las opciones permitidas en el comando getopts insertado en el ciclo while. La variable de shell OPTARG, también definida por la función getopts, se inicializa con el valor del argumento que sigue a la opción actual. En este ejemplo, OPTARG se define solo cuando se maneja la opción -z, porque la cadena de control para getopts tiene el carácter: (dos puntos) solo después de la opción -z. Dentro del ciclo while, puede manejar cada uno de los argumentos de la línea de comandos, inicializando algunas variables u operando de la manera adecuada para cada argumento dado. Para las opciones que toman sus propios argumentos, como la opción -z en el ejemplo, debe usar una variable de entorno especial para almacenar el valor del argumento, porque la función getopts define OPTARG solo mientras una opción de línea de comando en particular se convierte en la opción actual. opción en el ciclo while. Después de que todos los argumentos de la línea de comandos se hayan procesado dentro del bucle while, el comando shift modifica la variable $• para eliminar las opciones ya examinadas, de modo que $1 se convierte en el primer argumento de la línea de comandos aún no procesado. Una vez que se han examinado todas las opciones, el procedimiento de shell puede continuar realizando las operaciones previstas. EL COMANDO trap Normalmente, una señal como colgar, CTRL-D (terminar) o alguna señal de error del sistema, enviada a un procedimiento de shell en ejecución, hace que el programa finalice inmediatamente y regrese al shell de llamada. Por lo general, esto es lo que desea, pero a veces el shell puede estar en proceso de intercambiar algunos archivos o realizar alguna otra operación crítica. En estos casos, es preferible atrapar la señal y dejar que el procedimiento de shell continúe hasta completarse; en otros casos, puede ser preferible emitir la señal y ejecutar algunas operaciones de restauración antes de salir del shell. El comando trap sirve para estos propósitos: puede usarse en cualquier parte de un procedimiento de shell, pero nunca debe usarse directamente en la línea de comando. El comando trap requiere como primer argumento una línea de comando protegida con ", seguida de una lista de números de señal. Cuando se recibe una de las señales en la lista, se ejecuta la línea de comando, luego el procedimi ento continúa la ejecución; si usa trap usted desea salir del procedimiento, debe incluir explícitamente exit en el comando protegido; por ejemplo: trap "¡echo recibió una señal!; exit" 1 2 15 La lista de señales disponibles y sus significados está disponible en la página Signal(S}, manual del Manual de referencia del programador. No puede acceder a los números de señal en la lista de comandos protegidos, pero puede incluir tantos comandos trap en su procedimiento como desee. Para cancelar una trampa de señal, use otro comando de trampa para la misma señal; si la cadena de comando es nula, la señal se ignora. Por ejemplo: trap "" 1 2 15 Las tres señales se ignoran, lo que dificulta la interrupción del procedimiento. EL COMANDO wait En ocasiones, es posible que desee iniciar varias aplicaciones en segundo plano, pero suspender todas las demás actividades hasta que finalice una o todas las aplicaciones. Los trabajos en segundo plano suelen volver al shell inmediatamente, aunque pueden seguir ejecutándose durante mucho tiempo. Puede usar el comando de espera para informar al shell que, aunque haya iniciado el trabajo en segundo plano, desea esperar hasta que se complete. Ejecute wait con la identificación del proceso del trabajo en segundo plano que desea esperar, por ejemplo: $ cat /unix > /tmp/ss & 10009 $ wait 10009 Cuando se completa el trabajo, wait lo devuelve al shell para recibir otro comando. El comando de espera sin argumentos espera a que finalicen todos los trabajos en segundo plano. El comando de espera le da a los procedimientos de shell algún contador de trabajo[. NIVELES DE SHELL Y COMANDO shl Los sistemas SVR3 y SVR4 proporcionan una herramienta que permite que varios shells estén activos en un solo terminal; no es un sistema de múltiples ventanas como el Sistema X Window, porque cada shell ocupa toda la pantalla. Existen herramientas para definir nuevos shells, para cambiar entre shells y para eliminarlos después de usarlos. La definición de los diferentes niveles de shell (capa de shell) permite que el sistema considere cada shell individual como una sesión independiente; el sistema actúa como si se hubiera conectado a la máquina varias veces desde diferentes terminales. Cada sesión, llamada capa de shell, se trata como una terminal virtual y las diferentes capas no interactúan. Dado que cada nivel ocupa todo el video, hay algunas herramientas disponibles que le permiten cambiar de un nivel a otro cuando lo desee. En este entorno, puede ejecutar varios programas simultáneamente, cada uno de los cuales tiene acceso total a la terminal. Puede usar el sistema a nivel de shell de varias m aneras, limitadas a terminales tty; no se puede utilizar en algunas redes de área local o con el sistema X Window. Para las consolas del sistema, es preferible el comando vtlmgr (administrador de capa de terminal virtual), si su sistema lo admite. El comando shl (capas de shell) activa el administrador de capas, que controla el acceso a las diferentes capas que ha definido. Cuando inicia el programa shl, aparece un nuevo aviso en la pantalla para informarle que ya no está en una sesión normal, pero que está bajo el control del sistema shl. Por ejemplo: $ shl >>> En este punto, shl espera un comando. Puede crear una nueva capa, eliminar una existente o cerrar el administrador de capas por completo. Para crear una nueva capa, escriba crear después del mensaje ">>>". $shl >>> create (1) El nivel así definido toma un nombre, generalmente el número de nivel, del 1 al 7, siendo 7 el número máximo de niveles permitido. El aviso de PS 1 de cada nivel se cambia al nombre del nivel actual, para distinguir el nivel actual en el video. En el ejemplo anterior, una vez que haya ejecutado el programa shl y haya definido el nuevo nivel de shell, el shell de inicio de sesión se cuelga y el shell (1) espera sus comandos. Puede usar este nivel como un caparazón normal y puede eliminarlo con el comando de salida o presionando la combinación de teclas CTRL-D. Cuando elimina un nivel, el control vuelve al administrador de niveles que muestra el indicador >>>; luego puede especificar más comandos para shl. Cuando el programa shl se está ejecutando, independientemente de la capa que esté activa, puede volver al indicador >>> en cualquier momento activando shl con la combinación de teclas CTRL-z. Cuando se activa shl, inmediatamente muestra el aviso >>> y espera los comandos. Este uso de CTRL-Z anula el uso de CTRL-z para el trabajo contra [ (cubierto en el Capítulo 16). Puede crear una segunda capa usando los siguientes comandos: $ shl >>> create (1) CTRL-Z >>> create (2) Ahora tiene dos niveles de proyectiles, y el activo es el nivel (2). Hasta 7 niveles pueden estar activos al mismo tiempo. Puede crear una capa, iniciar una aplicación que produzca algún resultado y luego crear una segunda capa. En esta situación, la salida producida por el primer nivel (y por todos los demás niveles activos posibles) va directamente al terminal y se superpone a la salida producida por el nivel actual. De esta forma, las aplicaciones continúan su ejecución en las capas, escribiendo los resultados producidos en el terminal, independientemente del número de capas activas. Solo la capa activa puede aceptar los comandos que escribe en el teclado, las otras capas no se bloquean porque continúan ejecutándose incluso cuando no están activas (sin bloqueo). El sistema shl proporciona los comandos de bloqueo y desbloqueo para cambiar este comportamiento y hacer que una capa se bloquee cuando no está activa, por lo que la salida producida por esa capa se detiene hasta que se vuelve actual. Usado >>> bloque 2 para hacer el bloqueo de nivel (2) y >>> desbloquear 2 para hacer el bloqueo de nivel (2) no bloqueado. Cuando regresa al programa shl, en cualquier momento presionando la combinación de teclas CTRL-z, además de crear, varios otros comandos están disponibles, la mayoría de los cuales aceptan como argumento la indicación numérica del nivel en el que operan. te presentas? en el indicador >>> para obtener una lista de todos los comandos disponibles. Puede cambiar libremente de una capa activa a otra; presione CTRL-z, espere el indicador >>> y escriba el comando de reanudación con el número de nivel que desea activar; o, más simplemente, ingrese el nombre del nivel, sin la palabra clave del currículum, por ejemplo:. (1) CTRL-Z >>> 2 (2) Ahora el nivel (2) está activo. Para eliminar un nivel, presione CTRL-D dentro del nivel, o ingrese el comando de eliminación en el indicador >>>, indicando el número de nivel que se eliminará como argumento. (2) CTRL-Z >>> delete 2 >>> Finalmente, el comando quit desactiva el administrador de niveles, restaurando el shell de inicio de sesión, y se eliminan todos los programas que están activos en los diferentes niveles. La combinación de teclas CTRL-z utilizada para activar el programa shl también se denomina carácter de cambio; puede modificarlo para adaptarlo a sus necesidades utilizando el comando stty. $ stty swtch e donde e es el carácter elegido para reemplazar CTRL-z. CONSOLA VIRTUAL La consola virtual es una adaptación significativa del concepto shl. Algunas versiones de SVR3 y SVR4 permiten utilizar las teclas de función para pasar directamente de un nivel a otro, evitando la llamada del comando shl y los relativos procedimientos CTRL-z. La funcionalidad de la consola virtual se limita a la consola del sistema, mientras que shl se puede ejecutar tanto en terminales remotas como en la consola. En algunas versiones, al presionar una tecla de función se borra la pantalla y se genera un mensaje de inicio de sesión que le permite volver a iniciar sesión en la máquina; en otras versiones, el inicio de sesión actual se conserva y al presionar la tecla de función se activa un nuevo shell. Una vez establecida la sesión, puede activarla inmediatamente pulsando la tecla de función correspondiente. Una actualización de pantalla generalmente ocurre cuando cambia de sesión, resolviendo uno de los principales inconvenientes del comando shl. En algunas versiones, la consola virtual siempre está disponible y no es necesario activarla ejecutando un comando como en el caso de shl; en otras versiones tienes que activar la característica con el comando $ vtlmgr (administrador de capa de terminal virtual). Para intercambiar pantallas cuando la función vtlmgr está activa, debe presionar ALT-SYSREO (mantenga presionada ALT mientras presiona SYSREO), seguido de una tecla de función. Las primeras teclas de función están asociadas a los niveles correspondientes y al pulsar la tecla de función se activa el nivel relativo. Si el nivel de la consola virtual aún no existe, la secuencia de teclas de función ALT-SYSREO crea la nueva consola virtual; también puede usar el comando newvt para crear consolas virtuales. Nuevamente, puede eliminar una capa con CTRL-D o con el comando de salida. En la consola del sistema, puede crear una terminal virtual, iniciar el sistema X Window o una sesión de DOS en una ventana, cambiar a una nueva ventana para iniciar otra sesión de DOS; por lo tanto, puede alternar entre estas diferentes sesiones tantas veces como sea necesario. Consulta la documentación de tu versión de SVR4 para verificar si soporta la funcionalidad de consola virtual y cuántas sesiones permite activar simultáneamente. FUNCIONES DE SHELL Los shells SVR3 y SVR4 proporcionan otro mecanismo de definición de procedimientos que es un poco más eficiente que el enfoque del procedimiento de shell que se analizó anteriormente. Sin embargo, estas funciones de shell son más difíciles de controlar que los procedimientos normales de shell porque se definen directamente en el shell y no tienen vida permanente en un archivo. Cuando define una función de shell, el shell actual lee la definición y la función se almacena dentro del shell que está actualmente activo. Puede ejecutar una función de shell como cualquier otro comando o procedimiento de shell, pero cuando cierra la sesión, pierde la función. También puede colocar definiciones de funciones de shell en un archivo y ejecutar el archivo con el mecanismo .filename descrito anteriormente, que permite que el shell actual lea e interprete el archivo, en lugar de una subshell recién creada. Las funciones de shell no se pueden exportar ni están disponibles automáticamente para los subshells, pero los subshells sí. volver a leerlos si es necesario. Puede definir funciones de shell usando el siguiente formato: $ nombre() ( > lista-comandos >) donde nombre es el nombre que desea asignar a la función. Se requieren corchetes ( ); la llave izquierda define el inicio de la lista de comandos, donde puede especificar cualquier comando ejecutable u operador de shell. También puede usar los parámetros posicionales $#, $• y $1 a $9 dentro de la función. Por ejemplo: $show() ( > echo $1 > echo $2 > exit 2 >) $ mostrar saludos hola saludos hola $ Este ejemplo define una función de shell llamada show que muestra los dos primeros argumentos y luego devuelve el valor de salida 2 al shell que llama. Las funciones de shell no tienen límite de complejidad; puede definir los procedimientos de shell utilizados con frecuencia para que funcionen, lo que reduce el tiempo de CPU. Sin embargo, si usa repetidamente un conjunto de funciones de shell, debe asegurarse de colocarlas en su .profile o usar algún otro mecanismo para asegurarse de que siempre estén disponibles cuando las necesite. LA VARIABLE cdpath El shell le permite especificar una ruta de búsqueda para operaciones de cd, que actúa de manera muy similar a la variable PATH. La variable de entorno CDPATH le permite declarar una lista de nombres de directorio para escanear cuando busca una ruta relativa proporcionada como argumento para el comando cd. El comando cd busca su argumento en cada directorio listado en CDPATH y asume el primer directorio que contiene el argumento de la ruta relativa como el directorio actual. El valor de CDPATH sigue la sintaxis de PATH, por ejemplo: $echo $CDPATH :/home/giorgio:/home/giorgio/src $ El primer carácter: (dos puntos) significa que la búsqueda debe realizarse primero en el directorio actual; luego la búsqueda se hace en /home/giorgio, y finalmente en /home/giorgio/src. Si el argumento del comando cd es una ruta absoluta completa, se supone que es el directorio actual; esto es muy útil si cambia de directorio con frecuencia. SECUENCIAS DE COMANDOS Otra construcción de shell que se usa con menos frecuencia es la secuencia de comandos. A diferencia del operador;, que simplemente agrupa los comandos, una secuencia de comandos se construye con los operadores && (and lógico) or :: (or lógico) para separar los comandos individuales. El operador && ejecuta el segundo comando solo si el primer comando fue exitoso (devuelve cero); el operador : : ejecuta el segundo comando solo si el primer comando no fue exitoso (devuelve un valor distinto de cero), si el primer comando fue exitoso, el segundo no se ejecuta. Por ejemplo: $ touch archivo.mio :: echo No se puede crear archivo.mio es equivalente a: $ touch archivo.mio $if [ $? - ne 0 ] ; then echo No se puede crear archivo.mio ; fi