C Shell

De Wikipedia, la enciclopedia libre
Saltar a: navegación, búsqueda
C shell
Muestra la shells tcsh y sh  Unix ejecutándose en escritorio Mac OSX.
Información general
Autor(es) Bill Joy
Lanzamiento inicial 1978
Última versión estable 6.20.00
Género Shell
Programado en C
Sistema operativo BSD, Unix, Mac OSX, GNU/Linux
Licencia BSD
[editar datos en Wikidata]

C shell es un shell de Unix (llamado csh o tcsh mejorado) creado por Bill Joy cuando se graduó de la Universidad de Bekeley, California en 1970. Este intérprete fue distribuido en sus inicios con 2BSD en el año de 1978 por Joe. Otros colaboradores que contribuyeron en sus inicios al código fueron Michael Ubell, Eric Allman, Mile O'Brien y Jim Kulp.

La shell C es un intérprete de comandos que se ejecuta en una ventana en modo texto y permite al usuario escribir comandos. La shell C también puede leer comandos desde un fichero de texto llamado script y como toda shell de Unix soporta comodines y tuberías para referirse a los nombres de ficheros, sustitución de comandos, variables, condicionales e interacción. Lo que diferenciaba la shell C de otras (en 1980) fueron sus características interactivas y estilo general. Las nuevas características lo hicieron más fácil y rápido de usar. El lenguaje comandos que usa se parece al lenguaje C.

En muchos sistemas como Mac OS X y Red Hat, chs es tcsh, una versión mejorada de csh. A menudo cualquiera de los dos nombres (csh o tcsh) es un enlace simbólico a la versión mejorada de C shell (tcsh).

En Debian y algunos derivados (Ubuntu) hay dos paquetes diferentes, csh y tcsh. El primero se basa en la versión orginal para BSD y el segundo la es mejora de csh.

tcsh agregó nombres de archivos, terminación de línea de comandos y el concepto de edición de líneas de comando que tomó prestado del sistema Tenex, por el cual lleva la letra "t". Debido a que tcsh solo agregó funcionalidad y no cambió lo que había allí se mantuvo compatible con la C shell original. Inició como una rama lateral a partir del código inicial que Joe había escrito, tcsh es ahora la rama principal que se continua desarrollando. tcsh es estable y las versiones aparecen aproximadamente una vez por año, estas versiones consisten en pequeñas correcciones de errores.

Estilo C[editar]

El sistemas operativo Unix se había escrito exclusivamente en C, así que el primer objetivo de C shell fue un lenguaje de comandos que poseyera un estilo consistente con el resto del sistema.

El uso de palabras claves, paréntesis, la gramática integrada y el soporte de matrices de C shell fueron estrachamente influenciados por el lenguaje C.

Según los estándares actuales chs no parece similar a C al igual que otros lenguajes de línea de comando. Pero en los años ochentas y noventas la diferencia era vista como algo sorprendente, sobre todo si se compara con Bourne shell (conocida como sh), que para la época era la shell dominante escrita por Stephen Bourne en los laboratios Bell. El siguiente ejemplo ilustra los operadores y la sintaxis de las expresiones más convecionales de C shell.

Bourne shell

#!/bin/sh
if [ $días -gt 365 ]
then
   echo Ha pasado más de un año.
fi

C shell

#!/bin/csh
if ( $días > 365 ) then
   echo Ha pasado más de un año.
endif

sh carecía de expresiones gramáticas. La condición entre corchetes era evaluada de forma lenta, esto quería decir que necesitaba correr programas externos para realizar dicha comprobación. sh tomaba palabras como argumentos y comandos que debían ser ejecutado como proceso hijos. Si el proceso hijo daba un código de retorno cero, entonces sh buscaría una cláusula then (una sentencia separada pero a menudo escrita en la misma línea con un punto y coma) y ejecutaría el bloque anidado, de lo contrario se ejecutaría el resto. La vinculación del programa "test" y "[" dio una ventaja de notación a los corchetes y la apariencia que la funcionalidad test era parte del lenguaje. sh usó una palabra clave invertida para marcar el final de un bloque de control, fue un estilo tomado de ALGOL68.

Por el contrario csh podía evaluar expresiones directamente, lo que la hacía más rápida. Tenía mejor legibilidad: Sus expresiones utilizaban una gramática y un conjunto de operadores copiado en su mayoría del lenguaje C; ninguna de sus palabras claves se invirtieron y su estilo era parecido al de C.

Un segundo ejemplo, comparando scripts que calculan las primeras 10 potencias de 2.

Bourne shell

#!/bin/sh
i=2
j=1
while [ $j -le 10 ]
do
   echo '2 **' $j = $i
   i=`expr $i '*' 2`
   j=`expr $j + 1`
done

C shell

#!/bin/csh
set i = 2
set j = 1
while ( $j <= 10 )
   echo '2 **' $j = $i
   @ i *= 2
   @ j++
end

Debido a la falta de expresión gramática, el script sh utiliza la sustitución de comando y el comando expr. La declaración @ en C shell es un juego de palabras, es la sentencia "at-sign-ment".

Tenemos un tercer ejemplo mostrando un estilo para una instrucción switch.

Bourne shell

#!/bin/sh
for i in d*
do
   case $i in
      d?) echo $i is short ;;
      *) echo $i is long ;;
   esac
done

C shell

#!/bin/csh
foreach i ( d* )
   switch ( $i )
      case d?:
         echo $i is short
         breaksw
      default:
         echo $i is long
   endsw
end

En el script sh ";;" marca el final de cada caso debido a que sh no permite declaraciones nulas.

Mejoras para el uso interactivo[editar]

El segundo objetivo de C shell era ser mejor para el uso interactivo. Se introdujeron nuevas características que lo hizo más fácil, rápido y más amigable para escribir comandos en la terminal. Los usuarios podían realizar tareas con menos pulsaciones de teclas y ejecutaban más rápido. La característica nueva más significativa fue el historial y el mecanismo de edición de alias, directorios, notación de tilde, cdpath, control de trabajo y path hashing. Estas nuevas características resultaron ser muy populares y muchas de ellas fueron copiadas por otras shells de Unix.

Historial[editar]

El historial permite a los usuarios recordar comandos y volver a ejecutarlos haciendo algunas pulsaciones de teclas rápidas. Por ejemplo, dos signos de exclamación "!!" escritos como un comando se denominan un "bang, bang" y hace que se ejecute el comando anterior. Otras combinaciones cortas de pulsaciones de teclas son, "!$" significa que se debe ejecutar sólo el último argumento del comando anterior; permite que los bits y piezas de comandos anteriores se peguen juntos y edite para formar un nuevo comando.

Edición de operadores[editar]

La edición funciona tanto para un comando anterior como en la sustitución de variables, donde los operadores van desde la búsqueda "/" a la sustitución de cadenas de caracteres o analizar una ruta para extraer un segmento específico.

Alias[editar]

Permiten abreviar un conjunto de comandos y expresiones dentro de una palabra clave definida por el usuario, la cual C shell expande y ejecuta. Para situaciones simples los alias se ejecutan más rápido y sonmás convenientes que los scripts.

Pila de directorios[editar]

La pila de directorios permite al usuario empujar o abrir el directorio de trabajo actual, facilitando el salto hacía adelante o hacía atrás entre distintos lugares del sistema de archivos.

Notación de tilde[editar]

La notación tilde ofrece un forma abreviada de especificar las rutas relativas al directorio home usando el caracter "~".

Autocompletando nombres de archivos[editar]

La tecla tabuladora puede ser utilizada de forma interactiva para mostrar posibles terminaciones de nombres de archivos.

Cdpath[editar]

Extiende la noción de ruta de búsqueda del comando cd (chage directory). Si el directorio especificado al comando cd no está en el directorio actual, csh intentará encontrarlo en los directorios almacenados en cdpath.

Control de procesos[editar]

En la década de los ochentas la mayoría de los usuarios tenía terminales en modo de caracteres simples que impedía varias ventanas, por lo cual sólo podían trabajar en un proceso a la vez. El control de procesos de C shell, permitió al usuario suspender la actividad actual y crear una nueva instancia de C shell, denominada proceso. Escribiendo Ctrl + Z, el usuario podía cambiar entre procesos utilizando el comando fg, entonces, se decía, que el proceso actual estaba en primer plano y el resto de los procesos estaban suspendidos o en segundo plano.

Path hashing[editar]

El hash de la ruta acelera la búsqueda de ejecutables en C shell. En lugar de realizar una llama al sistema de archivos por cada ruta de un directorio, esto es, uno a la vez hasta encontrar el archivo o quedarse sin posibilidades, C shell consultará una tabla hash interna que se construye al escanear la ruta de los directorios. Esta tabla puede indicar a C shell donde encontrar el archivo (si existe) sin tener que buscar y puede ser actualizada con el comando rehash.

Descripción general del lenguaje[editar]

C shell funciona ejecutando una línea a la vez. Cada línea es tokenizada en un conjunto de palabras separadas por espacios u otros caracteres con significado especial, incluyendo paréntesis, tubería, operadores de redirección de entrada y salida, punto y coma y signos de expansión.

Declaraciones básicas[editar]

Una instrucción básica es aquella que ejecuta un comando. La primera palabra se toma como nombre del comando que se va a ejecutar, puede ser un comando interno, por ejemplo, echo o un comando externo, el resto de las palabras se pasan como argumentos al comando.

Ejemplo básico de las declaraciones y su gramática:

Comodín[editar]

C shell al igual que todos los shells de Unix, trata cualquier argumento que contiene caracteres comodines como un patrón, y lo reemplaza con la lista de todos lo nombres de archivos que coinciden.

* coincide con cualquier número de caracteres.
? coincide con cualquier caractere individual.
[...] coincide con cualquier caracter dentro de los corchetes. Se permiten rangos usando el guion.
[! ... ] coincide con cualquier caracter que no esté en el conjunto.


C shell también introdujo varias notaciones convenientes (conocida como extend globbing) que fueron copiados por otros shells de Unix.

abc{def,ghi} es una variación y se expande a abcdef abcghi. ~ directorio home del usuario. ~user directorio home del usuario.

Mutiples niveles de directorios, por ejemplo, "*/*.c", son soportados.

Desde la versión 6.17.01 el comodín recursivo de la zsh (p. ej. "**/*.c" o "***/*.html" también soportado con la opción globstar.

Dar la responsabilidad de interpretar comodines a la shell era una decisión importante en Unix, significaba que los comodines funcionan como comandos y siempre de la misma manera. Sin embargo, la decisión se basó en la capacidad de Unix de pasar largas listas de argumentos de forma eficiente a través de las llamadas al sistema con exec que csh utiliza para ejecutar comandos. Por el contrario, en Windows la interpretación de comodín se realiza usualmente por cada aplicación. Este es un legado de MS-DOS que sólo permitía que un línea de comandos de 128 bytes se pasara a una aplicación, haciendo que pasar un comodín al indicador de comandos de DOS fuera impractico. En la actualidad Windows puede pasar líneas de comandos de aproximadamente 32K de caracteres Unicode. La carga para interpretar un comodín la tiene la aplicación.

Redirección de E/S (Entrada/Salida)[editar]

Por defecto cuando csh ejecuta un comando, el comando hereda las funciones de la biblioteca de entrada/salida (stdio) estándar para stdin (entrada estándar), stdout (salida estándar), stderr (salida de errores estándar) que normalmente apuntan a la ventana de la terminal donde se ejecuta C shell. Los operadores de redirección de E/S permite que el comando utilice un archivo en lugar de la entrada y salida estándar.

> significa que el stdout se escribirá en un archivo y si existe lo sobreescribirá y si no existe lo creará, los errores que se presenten serán mostrado en la ventana del shell.

>& significa que stdout y stderr se escribirá en una archivo, sobreescribiéndolo si existe y creándolo si no existe.

>> adjunta stdout al final de un archivo.

>& adjunta stdout y stderr al final de un archivo.

< significa leer stdin desde un archivo.

<< stdin leerá las siguientes líneas hasta que coincida con la cadena de caracteres.

Operadores de unión[editar]

Varios comandos pueden ser unidos en la misma línea.

; significa, ejectua el primer comando y el siguiente.

&& significa, ejecuta el primero comando y si obtienes un código de retorno 0 ejecuta el siguiente.

||significa, ejecuta el primer comando, y si devuelve un código de retorno distintos de 0, entonces, ejecuta el siguiente.

Tuberías[editar]

Los comandos puede ser conectados usando tuberías, esto es, que la salida de un comando es la entrada del siguiente. Ambos comandos se ejecutan simultáneamente.

| significa conectar stdout con el siguiente comando. Si hay errores se mostrarán en la pantalla de la shell.

|& significa conectar stdout y stderr al stdin del siguiente comando.

Ejecutar simultáneamente significa "en paralelo". En sistema con varios núcleos (procesadores múltiples) los comandos de tuberías (pipeline) pueden estar ejecutándose al mismo tiempo, en caso contrario el programdor del sistema operativo divide el tiempo de ejecución entre los comandos.

Dado un comando, p.ej. "a|b", la shell crea una tubería, entonces a y b usarán stdio para que los dos comandos sean redirigidos. a escribe su salida (stdout) en la entrada de la tubería (|), mientras b lee la entrada (stdin) desde la salida de la tubería. Las tuberías son implentadas por el sistemas operativo con una cierta cantidad de búfer para que puedan escribir antes que la tubería se llene, pero una vez que la tubería se llena cualquier escritura nueva será bloqueada dentro del sitema operativo hasta que b lea lo suficiente para desbloquear la nueva escritura. Si b intenta leer más dados de los que están disponibles se bloqueará hasta que haya escrito más datos o hasta que la tubería se cierre, p.ej. si sale.

Sustitución de variables[editar]

Si una palabra comienza con el signo de dólar, "$" los siguientes caracteres son tomados como el nombre de un variable y la referencia se sustituye por el valor que contenga la variable.

Comillas y símbolo de escape[editar]

Las comillas permiten que los caracteres especiales, como, espacios en blanco, comodines, paréntesis y signos de dólar, se tomen como texto literal.

/ Tomar el siguiente carácter como un carácter literal.

"texto" Comilla débile. Los espacios en blancos y comodines se toman como literales, mientras las sustituciones y comandos se siguen realizando.

'texto' Comilla fuerte. Todo el texto incluido se toma como literal.

Sustitución de comandos[editar]

La sustitución de comandos permite que la salida de un comando pueda ser usada como los argumentos de otro.

`comando` Significa, tome la salida de un comando, analiza las palabras y pégalas de nuevo en la línea de comando.

Ejecución en segundo plano[editar]

Normalmente cuando C shell inicia un comando, espera que el comando termine antes de darle al usuario otro mensaje que indica que puede escribir de nuevo otro comando.

comando & Significa, ejecuta el comando en segundo plano y muestra el indicador para que puedan escribir un nuevo comando.

Subshells[editar]

Una subshell es un copia secundaria separa de shell que hereda su estado actual, pero puede hacer cambios p. ej. en el directorio actual, sin afectar a la shell padre.

(comando). Significa, ejecute el comando en una subshell.


Véase también[editar]