Fundamentos de Unix e Internet. - Parte II


https://tutorialesenlinea.es/uploads/posts/2018-02/1517746844_linux-tutoriales.jpg

Eric Raymond
Traducción: Camilo Figueroa 

Revision History

Revision 2.9

Minor updates.

Revision 1.0

Initial revision.


Este documento describe en un lenguaje no técnico los fundamentos de trabajo de computadores tipo PC, sistemas operativos tipo Unix, y la Internet.

Tabla de contenido


Fundamentos de Unix e Internet. - Parte I


7. ¿Que hace su computador haga varias cosas a la vez?

8. ¿Que hace que mi computador mantenga procesos de manera conjunta y organizada?

8.1. Memoria virtual: versión simple.

8.2. Memoria virtual: versión detallada.

8.3. La unidad de administración de memoria.

9. ¿Que hace que mi computador guarde cosas en memoria?

9.1. Números

9.2. Caracteres

10. ¿Que hace mi computador cuando almacena cosas en el disco?

10.1. Nivel inferior del disco y el sistema de arhivos

10.2. Nombres de archivos y directorios

10.3. Puntos de montaje

10.4. Como un archivo logra ser visto

10.5. Propietario, permisos y seguridad de archivo.

10.6. Como las cosas pueden andar mal

11. ¿Como trabajan los lenguajes de programación?

11.1. Lenguajes Compilados

11.2. lenguajes Interpetados

11.3. Lenguajes Pseudocódigo

 

Fundamentos de Unix e Internet. - Parte III


inicio

7. ¿Que hace su computador haga varias cosas a la vez?

Realmente el no lo hace. Los computadores pueden solamente hacer una tarea a la vez. Pero el computador puede cambiar de tareas muy rápidamente y un tonto podría pensar para sus adentros que hace varias cosas a la vez. Esto es llamado timesharing / 'tiempo compartido'

Una de las tareas del kernel es administrar el timesharing. El tiene una parte llamada el programador, el cual mantiene dentro de si información sobre otros procesos (no kernel). Cada 1/60 de segundo un temporizador se apaga en el kernel, generando una interrupción en el reloj. El programador detiene cualquier proceso que actualmente este corriendo, suspendiéndolo en un lugar, y tomando control de otro proceso.

1/60 de segundo puede no sonar a mucho tiempo. Pero para los procesadores de hoy es suficiente para correr decenas de miles de instrucciones de maquina, con las cual puede hacer mucho trabajo. Si aún usted tiene muchos procesadores, cada uno puede completar un poco en cada uno de sus intervalos de tiempo.

En la practica, un programa puede no lograr usar la totalidad de su intervalo de tiempo. Si una interrupción llega desde un dispositivo I/O, el kernel detendrá la tarea actual, iniciará el manipulador de interrupción y retornará a la actual tarea. Una tormenta de interrupciones de alta prioridad puede exprimir el normal procesamiento: esta mala conducta es llamada 'thrashing' y por fortuna es muy difícil de inducir en los modernos Unix

En efecto, la velocidad de los programas es solo muy raramente limitada por la cantidad de tiempo (de maquina) que pueda obtener (hay algunas excepciones a esta regla, como las tarjetas de sonido y las de generación de gráficos 3D). Mucho mas a menudo las demoras suceden cuando el programa tiene que esperar un dato desde una unidad de disco u una conexión de red.

Un sistema operativo que soporte rutinariamente muchos procesos simultáneamente es llamado "multitasking” / "multitarea”. Desde sus cimientos, la familia de sistemas Operativos Unix fueron diseñados para la multitarea y Unix es muy bueno en ello – Mucho mas efectivo que Windows o el viejo Mac OS, los cuales tenían la multitarea atornillada dentro de ellos como una idea de último momento y la realizaban de una manera muy pobre. Una eficiente y confiable multitarea es en gran parte lo que hace a Linux superior para las redes (networking), las comunicaciones y los servicios web (web services).


inicio

8. Que hace que mi computador mantenga procesos de manera conjunta y organizada?

El programador del kernel cuida de dividir los procesos en el tiempo. Su sistema operativo también tiene que dividir estos procesos en el espacio, de tal forma que los procesos no puedan montarse unos con otros. Aun si usted supone que todos los programas intentan trabajar de manera colaborativa, usted no desearía que un bug (error) en uno de ellos sea capaz de afectar a otros. Las operaciones que su sistema operativo realiza para resolver este tipo de problemas se llama 'administración de memoria' / 'memory management'.

En su maquina cada proceso necesita su propia área de memoria, como un lugar donde correr su código y mantener sus variables y resultados. Usted puede pensar que este conjunto de cosas esta compuesta de un segmento de código de solo lectura (que contiene las instrucciones de los procesos) y un segmento de datos escribible (conteniendo todas las variables del proceso). El segmento de datos es único para cada proceso, pero si dos procesos están corriendo el mismo código, Unix, automáticamente lo organiza para que estos procesos compartan el mismo segmento de código, como una medida de eficiencia.

8.1. Memoria virtual: versión simple

La eficiencia es importante por que la memoria tiene un alto costo. Algunas veces usted no tiene la suficiente memoria para mantener todos los programas que la maquina esta corriendo, especialmente si usted usa programas de gran tamaño como un servidor X. Para resolver estos casos Unix usa una técnica llamada Memoria Virtual. El no trata de mantener para un proceso todo el código y datos necesarios. En lugar de ello, Unix mantiene solo un relativamente pequeño espacio de trabajo; el resto de el proceso es dejado en un lugar llamado 'space swap'/'espacio de intercambio' en su disco duro.

Note que en el pasado el termino "algunas veces” fue "casi siempre” debido a que el tamaño de la memoria era generalmente pequeño en relación al tamaño de los programas que corrían, así que el proceso de swapping era frecuente. Ahora la memoria es mucho menos costosa y aun las maquinas low-end (de baja categoría) tienen bastante memoria. Una moderna maquina personal de 64 MB de memoria o mas le es posible correr servidores X y un conjunto de tareas sin nunca necesitar el swap después de que se ha cargado en memoria.

8.2. Memoria virtual. Versión detallada

Realmente en la ultima sección se simplificaron las cosas un poco. Si, los programas ven la mayor parte de la mayoría como un grande y plano banco de direcciones de memoria, que una memoria física, y aquí un disco con 'memoria de intercambio' es usado para mantener esta ilusión. En todo caso su hardware no tiene más que cinco diferentes tipos de memoria dentro de si, y la diferencia entre estos tipos de memoria puede representar una buena decisión cuando los programas tienen que funcionar a máxima velocidad. Para entender realmente que sucede dentro de su computador, usted debe aprender como todas ellas trabaja en conjunto.

Los cinco tipos de memoria son estos: registros del procesador,cache interno (o en chip), cache externo (o fuera de chip), memoria principal, y disco. Y la razón de que sean varios tipos es simple: la velocidad cuesta dinero. He listado estos tipos de memoria en orden decreciente respecto a el tiempo de acceso y en orden creciente respecto al costo. La memoria de registros del procesador es la mas rápida y costosa, y puede ser accedida de manera aleatoria en cerca de un billón de veces por segundo, mientras que la memoria del disco es la mas lenta y barata, y puede realizar cerca de 100 accesos aleatorios en un segundo.

He aquí una lista que refleja velocidades datadas en el inicio del 2000 de una maquina de escritorio común. Mientras que la velocidad y la capacidad crecen los precios van bajando y es posible esperar que este tipo de proporciones se sostengan de manera constante.


Disco: Tamaño 13000 MB. Velocidad de acceso: 100KB/sec.

Memoria principal: Tamaño 256 MB. Velocidad de acceso: 100MB/sec.

Cache Externo: Tamaño 512 MB. Velocidad de acceso: 205MB/sec.

Cache Interno: Tamaño 32KB. Velocidad de acceso: 500MB/sec.

Procesador: Tamaño 28 bytes. Velocidad de acceso: 1000MB/sec.


No es posible construir alguna cosa mas allá de estos rápidos tipos de memoria, Esto requeriría mucho trabajo (y aun si no lo fuera) por que la memoria rápida es volátil. Esto significa que pierde su sustento cuando la energía desaparece. Y aquí hay un gran desequilibrio entre la velocidad del procesador y la velocidad del disco. Los tres niveles de en medio de la jerarquía de memorias (cache interno, cache externo y memoria principal) existen básicamente para cerrar esta brecha.

Linux y otros Unix tienen una característica llamada 'memoria virtual' / 'virtual memory'. Lo que esto significa es que el sistema operativo se comporta como si tuviera mas memoria de la que realmente tiene. Su verdadera memoria física principal se comporta mas como un gran conjunto de ventanas o valijas (caches) que un gran lugar de memoria "virtual”, la mayor parte de la cual en un momento dado almacena en disco en una zona especial llamada 'swap area' / 'zona de intercambio'. Fuera del alcance de los programas de usuario, el sistema operativo se encuentra moviendo bloques de datos (llamados "paginas”) entre la memoria y el disco para mantener esta ilusión. EL resultado final es que su memoria virtual es mucho mas grande pero no mas lenta que la memoria real.

Que tan lenta sea la memoria virtual depende físicamente de que tanto los algoritmos de swapping encuentren la forma para que los programas usen la memoria virtual. Afortunadamente los datos leídos y escritos por la memoria que están cerca en tiempo también tienden a estar cerca en el espacio de memoria. Esta tendencia es llamada 'Localidad' / ' Locality' o mas familiarmente 'localización de referencia' ( y esto es algo bueno). Si las referencias de memoria saltaran alrededor de la memoria virtual de manera aleatoria, generalmente se tendría que leer y escribir del/en disco para cada nueva referencia, y la memoria virtual sería tan lenta como lo es el disco. Pero porque los programas manifiestan realmente una fuerte localidad, el sistema operativo puede hacerlo (leer/escribir) con relativos pocos swaps/intercambios por referencia.

Por experiencia ha sido encontrado que el mas efectivo método para un amplio tipo de patrones de uso de memoria es muy simple: es llamado LRU o el algoritmo del "ultimo recientemente usado”. El sistema de memoria virtual toma los bloques del disco dentro de su conjunto de trabajo en la medida que lo necesite. Cuando él corre fuera de la memoria física al espacio de trabajo, él descarga el bloque 'mas recientemente usado'. Todos los Unix y la mayoría de los otros sistemas operativos con memoria virtual usan pequeñas variaciones del LRU.

La memoria virtual es el primer vinculo en el puente entre las velocidades del disco y el procesador. Esta explicitamente administrada por el sistema operativo. Pero aun hay un gran espacio entre la velocidad de la memoria principal y la velocidad en la cual el procesador puede acceder a su memoria de registro. Las memorias cache internas y externas apuntan a esto usando una técnica similar a la que hemos descrito sobre la memoria virtual.

Así como la memoria principal se comporta como un conjunto de ventanas y valijas en el área de intercambio/swap del disco, el cache externo actúa como una ventana sobre la memoria principal. El cache externo es rápido (250M de velocidad de acceso por segundo, en vez de 100M) y pequeño, El hardware (específicamente el controlador de la memoria de su computador) hace el LRU en el cache externo sobre los bloques de datos traídos desde la memoria principal. Por razones históricas la unidad de almacenamiento swapping es llamada 'una linea' en vez de 'una pagina'.

Pero aun no lo hemos logrado. EL cache interno da el ultimo paso de efectividad en velocidad al almacenar porciones de la cache externa. Esto aun es mas rápido y pequeño. EN efecto esto se sucede en el chip del procesador.

Si realmente queremos hacer que nuestros programas sean realmente rápidos, nos sera muy útil conocer estos detalles. Sus programas logran rapidez cuando tienen una fuerte localidad, por que esto hace que el caching trabaje mejor. La mas fácil manera de hacer que los programas sean rápidos es, por lo tanto, hacerlos mas pequeños. Si un programa no funciono mas despacio al recibir grandes cantidades de I/O del disco o esperar eventos de red, él usualmente correrá a la velocidad del cache mas pequeño en el que él pueda ajustarse.

Si usted no puede hacer que la totalidad de su programa sea pequeño, enfoque los esfuerzos en ajustar la localidad de las porciones con problemas de velocidad. Detalles sobre las técnicas para hacer esto van mas allá del alcance de este tutorial: En el momento que usted las necesite, usted habrá profundizado lo suficiente con algún compilador para entender por si mismo muchas de las técnicas.

8.3. La unidad de administración de memoria

Aun cuando usted tenga suficiente memoria principal como para evitar el swapping, la parte del sistema operativo llamada 'administrador de memoria'/'memory manager' tiene aun importantes cosas que hacer. El tiene que asegurarse que los programas puedan solamente alterar sus propios segmentos de datos, esto es prevenir que erróneos o maliciosos códigos dentro de un programa dañen los datos de otro. Para lograr esto, él mantiene una tabla de datos y de segmentos de código. La tabla es actualizada siempre que un proceso cualquiera realice una petición de mas memoria o libere memoria (usualmente cuando el programa termina).

Esta tabla es usada para pasar ordenes a una especializada parte esencial del hardware llamada MMU o 'unidad de administración de memoria'. Los chips de procesadores modernos tienen MMUs internamente construidos. La MMU tiene la especial habilidad de colocar barreras alrededor de las áreas de la memoria, de tal forma que una referencia fuera de limite será rechazada y causara una situación de interrupción especial.

Si usted siempre ve un mensaje de Unix que dice "Segmentation fault”/”falla de segmentación”, "core dumped”/”memoria vaciada”, o algo similar, esto es lo que exactamente esta sucediendo: Un programa en ejecución ha hecho una solicitud para acceder a la memoria fuera de su segmento logrando así una interrupción fatal. Esto indica un error en el código del programa: el 'vaciado de memoria' deja tras de si su información de diagnostico para ayudar al programador a detectar el error.

aquí hay otro aspecto para proteger procesos de los otros además de limitar sus accesos de memoria. Usted también necesita ser capaz de controlar sus accesos a archivos para que un malicioso o problemático programa no corrompa piezas criticas del sistema. Esta es la razón del por que Unix tiene permisos de archivos,tema que discutiremos mas adelante.


inicio

9. Que hace que mi computador guarde cosas en memoria?

Usted probablemente sabe que cualquier cosa en un computador es almacenada como una cadena de bits (dígitos binarios: usted puede pensar en ellos como un gran número de pequeños cambios de encendido y apagado). aquí vamos a explicar como estos bits son usados para representar las letras y números que su computador mastica.

Antes de comenzar con esto, se necesario entender el "tamaño de palabra”/”word size” de su computador. El tamaño de palabra es tamaño preferido de su computador para manipular unidades de información: Técnicamente es el ancho del registro de su procesador, área usada por el procesador para hacer cálculos lógicos y matemáticos. Cuando la gente escribe sobre computadores que poseen tamaños en bits (llamándolos computadores de "32-bit” o "64-bit”), esto es lo que significa.

La mayoría de computadores (incluyendo computadores 386, 486 y Pentium) tienen un ancho de palabra. Los anteriores modelos de maquinas 286 tenían un tamaño de palabra de 16: Las viejas mainframes a menudo usaban palabras de 36-bit. Los AMD opteron, Intel Itanium y los Alpha desde que estaban en DEC y ahora tiene Compaq tienen 64-bit de palabra.

El computador ve su memoria como una secuencia de palabras numerada desde cero hasta algún alto valor dependiendo del tamaño de su memoria. Ese valor esta limitado por el tamaño de palabra. Esa es la razón de porque los programas en viejas maquinas como las 286 tenían que funcionar mediante difíciles piruetas para dirigir grandes cantidades de memoria.

9.1. Números

Los números enteros son representados como cualquier otra palabra o pares de palabras, dependiendo de el tamaño de palabra de su procesador. Una maquina con 32-bit de palabra es la mas común representación de entero.

La aritmética del entero es cercana pero no es realmente matemática base 2. Los bit de bajo orden son 1, le sigue el 2, el 4 y así sucesivamente como un puro binario. Pero los números con signo son representados en la notación de "complemento a dos”. Los bits de mas alto orden son un bit con signo, lo cual hace que la cantidad sea negativa y cada numero negativo puede obtener su correspondiente positivo valor al invertir todos los bits y sumando uno. Es por esto que los enteros en una maquina de 32-bit tienen el rango de -231 to 231 – 1. Ese 32 avo bit esta siendo usado para el signo: 0 significa un número positivo y 1 significa un numero negativo.

Algunos lenguajes de computación permiten usar la aritmética sin singo, lo que significa base 2 con cero y números positivos solamente.

La mayoría de los procesadores y algunos lenguajes pueden hacer operaciones con 'números de punto flotante'/'Flotating-point number' (esta capacidad esta preestablecida dentro de los chips de procesadores mas recientes). Los números de punto flotante le dan a usted más amplios rangos de valores que los enteros y permiten ser expresados en fracciones. La forma en la cual esto es realizado varia y sería muy complicada de discutir ahora en detalle, pero en ideas generales se refiere a la 'notación científica', donde uno podría escribir 1.234 * 1023; la codificación de el numero es dividida en una mantisa (parte decimal de la fracción. n del t.) y la parte del exponente (23) para la potencia decimal (lo que significa que el número multiplicado resultante podría tener 20 ceros. 23 menos los tres lugares decimales.

9.2. Caracteres

Los caracteres son normalmente representados como cadenas de siete bits cada carácter en una codificación llamada ASCII (American Standard Code for Information Interchange / Estandard Americano de Código para el Intercambio de Información): en las maquinas modernas, cada uno de los 128 caracteres ASCII son los últimos (los mas bajos) siete bits de un octeto o byte de 8 bits: los octetos son empaquetados dentro de las palabras de memoria, así que (por ejemplo) una cadena de seis caracteres solo puede tomar dos palabras de memoria. Para ver un listado con los códigos ASCII escriba 'man ascii' en su ventana de Unix.

El anterior párrafo estuvo equivocado en dos formas. La menor de ellas es que el termino 'octeto' es formalmente correcto pero raramente es verdaderamente usado: la mayoría de las personas se refieren a un octeto como un byte y espera que tengan 8 bits de longitud. Estrictamente hablando, el termino 'byte' es más general: es usado para, por ejemplo maquinas de 36-bits como 9-bit de bytes (aunque esto probablemente nunca sucederá de nuevo)

La mayor de ellas es que no esta permitido que todas las palabras usen ASCII. En efecto, muchas de las palabras no pueden ser ASCII. Esto puede no ser importante par el Ingles Americano, pero los acentos y también otros caracteres especiales son necesarios para los usuarios que usan otros lenguajes. Inclusive el Ingles Británico tiene problemas con la ausencia del símbolo usado para el símbolo de la moneda Libra.

han existido varios intentos de corregir este problema. Todo uso de bits de mayor tamaño que no esta en ASCII, haciéndolo en la mitad inferior del conjunto de 256 caracteres. El mayor uso de esta técnica es llamado 'conjunto de caracteres Latin-1 (mas familiarmente llamado ISO 8859-1). Este es el conjunto de caracteres por defecto para Linux, HTML y X. Microsoft Windows usa una versión cambiada de Latin-1 adicionándole caracteres como las dobles comillas derecha e izquierda en lugares donde el propio Latin-1 ha dejado sin asignar por históricas razones (para profundizar sobre los problemas que esto causa visite la pagina demoroniser)

Los soportes para lenguajes de Europa Occidental, incluyendo el Ingles, francés, Alemán, Español, Italiano, Alemán, Noruego, Suizo, y el Danes. Sin embargo esto no es suficiente, y como resultado ahora hay series del latin-2 por medio de -9 conjuntos de caracteres para apoyar caracteres del griego, Árabe, Hebreo, Esperanto y serbo-croacia. Para mayores detalles visite la pagina Sopa del alfabeto ISO .

La última solución es un gran estandard llamado Unicode (y su gemelo idéntico ISO/IEC 10646-1:1993). Unicode es idéntico al Latin-1 en los 256 casilla mas bajos. Sobre estos hay un espacio de 16 bits que incluye el Griego, Cirilico, Armenio, Hebreo, Arabe, Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, Malayalam, Thai, Lao, Georgian, Tibetan, Kana japones, el completo conjunto de caracteres del Hangul Coreano y el unificado conjunto de caracteres para los ideogramas Chinos/Japoneses/Koreanos (CJK). Para mayores detalles visite la pagina de Unicode.


inicio

10. ¿Que hace mi computador cuando almacena cosas en el disco?

Cuando usted mira un disco duro bajo Unix, usted observa un árbol de directorios y archivos con nombre. Normalmente usted no necesita profundizar en su estructura, pero él se ha convertido en algo muy útil para saber que sucedió en detalle si usted tiene un disco dañado y necesita recuperar los archivos. Desafortunadamente, no es una buena forma describir la organización del disco desde el nivel inferior del mismo, así que lo describiremos desde el mismo hardware hacia arriba.

10.1. Nivel inferior del disco y el sistema de archivos

El área de superficie de su disco, donde él almacena la información, esta dividida en algo similar a un tablero de dardos – dentro de circulares pistas las cuales como las partes de un pastel. Debido a que las pistas cercanas a la parte exterior tienen mas área que aquellas cercanas al centro del disco, las pistas del exterior están divididas en mas sectores que las pistas del interior. Cada sector (o bloque de disco) tiene el mismo tamaño, el cual bajo los modernos Unix es generalmente 1 KB binario (1024 palabras de 8 bits). Cada bloque de disco tiene su única dirección o 'disk block number'/'numero de bloque del disco'.

Unix divide el disco dentro de 'particiones de disco'. Cada partición es un continuo campo de bloques que son usados separadamente de cualquier otra partición, cada uno como un sistema de archivos o espacio swap aparte. La razón original para tener particiones es la de recuperar los daños en un mundo de discos muy lentos y susceptibles a errores; los limites entre estas particiones reducen la fracción de su disco que probablemente lo haría inaccesible o corrupto debido a un mala lectura del disco. Hoy en día es más importante que las particiones puedan ser declaradas como 'solo-lectura' (previniendo a un intruso el modificar archivos críticos del sistema o compartirlas sobre una red de varias maneras que no discutiremos aquí. La partición con el número más bajo es a menudo tratada de manera especial como la partición de arranque'/'boot partition' donde usted puede colocar el kernel para que sea iniciado.

Cada partición es implementada como espacio swap (usado para implementar la memoria virtual) o un sistema de archivos para almacenar archivos. Las particiones swap corresponden a una secuencia lineal de bloques. De otra mano, el sistema de archivos necesita una forma de mapear(relacionar) los nombres de los archivos a secuencias de bloques del disco. Debido a que los archivos crecen o disminuyen de tamaño y/o cambian con el tiempo, un bloque de datos de archivos no sería una secuencia lineal de estos sino mas bien todos estarían de manera dispersa a lo largo de su partición. (desde donde quiera que el sistema operativo pueda encontrar un bloque libre cuando lo necesite). Este efecto de dispersión se llama 'fragmentación'.

10.2. Nombres de archivos y directorios

Dentro de cada sistema de archivos, el proceso de mapeo de nombres a bloques es manipulado a través de una estructura llamada 'i-node'. Hay un conjunto de ellos cerca de la parte inferior (los números más bajos de bloque) de cada sistema de archivos (los más bajos de ellos son usados para proteger y etiquetar propósitos que no describiremos aquí). Cada I-node describe un solo archivo. Los bloques de datos de archivos (incluyendo directorios) se encuentran sobre los i-nodes (los números más altos del bloque)

Cada I-node contiene una lista de números de bloque del disco en el archivo que él describe (Actualmente esto no es del todo cierto, solo es correcto para archivos pequeños, pero el resto de los detalles no es importante conocerlos aquí). Note que cada i-node no contiene el nombre del archivo.

Los nombres de los archivos se encuentran en la 'estructura de directorios'. Una 'estructura de directorios' solo mapea los nombres hacia los números i-node. Esto sucede porque, en Unix, un archivo puede tener múltiples nombres y todos verdaderos (a esto se le llama Links Duros): Estos son solo múltiples entradas de directorios que apuntan al mismo i-node.

10.3. Puntos de montaje

En la más simple situación, su entrada en el sistema de archivos de Unix se encuentra en una sola partición. Esto es inusual aun cuando usted vea esto en algunos pequeños sistemas personales Unix. Es más típico que estén regados a lo largo de varias particiones, posiblemente en diferentes discos físicos. Así que, por ejemplo, su sistema puede tener una pequeña partición donde se encuentra el kernel, una partición ligeramente mayor donde se encuentran las utilidades del sistema operativo, y una partición mucho más grande donde se encuentran ubicados los archivos del usuario.

La única partición a la cual se tiene acceso inmediatamente después de arrancar el sistema se llama la 'partición raiz'/'root partition', la cual es (la mayoría de las veces)la única desde la cual usted puede arrancar. En ella se encuentra le directorio raíz del sistema de archivos, el nodo superior bajo cual cualquier otra cosa se encuentra.

Las otras particiones en el sistema tienen que ser adjuntadas a la partición root para que la totalidad del sistema de múltiples particiones pueda ser accesible. Él montará cada una de las particiones sobre un directorio en la partición root.

Por ejemplo, si usted tiene un directorio Unix llamado /usr, es probable que él sea un punto de montaje que apunta a una partición que contiene muchos programas que han sido instalados con el Unix pero que no son requeridos durante el proceso de arranque.

10.4. Como un archivo logra ser visto

Ahora podemos dar una mirada al sistema de archivos desde arriba. Cuando usted abre un archivo (por ejemplo: /home/esr/WWW/ldp/fundamentals.xml) esto es lo que sucede.

El kernel arranca en la raíz el sistema de archivos de Unix (en la partición raíz). Él busca un directorio llamado 'home'. Usualmente 'home' es un punto de montaje para la partición de usuario que esta ubicada en cualquier otro lugar, así que él (el kernel) va hacia ese lugar. En el nivel superior de la estructura del directorio de dicha partición de usuario el kernel busca una entada llamada 'esr' y extrae un número i-node. El kernel entonces se dirige a dicho i-node, advirtiendo que dicho i-node esta asociado a un bloque de datos de archivos correspondiente a una estructura de archivos. Aquí busca 'WWW', extrae el número i-node y se dirige al correspondiente subdirectorio, buscando ahora 'lpd'. Aquí hay otro i-node de directorio, abriéndolo él encuentra el numero i-node para 'fundamentals-xml'. Ese i-node no es un directorio, en lugar de ello dicho i-node contiene la lista de bloques del disco asociados con el archivo.

10.5. Propietario, permisos y seguridad de archivo

para mantener a los programas alejados de accidentes o malas situaciones al tomar datos que no debe usar, Unix tiene características de permisos. Estas características fueron originalmente diseñadas para soportar el timesharing (compartición del tiempo) al proteger en la misma maquina a múltiples usuarios de entre si. en la época en la que Unix funcionaba principalmente en costosos minicomputadores compartidos.

Para entender el concepto de archivos de permisos es necesario recordar la descripción de usuarios y grupos en la sección ¿Que pasa cuando usted se registra en el sistema?. Cada archivo tiene un usuario propietario y un grupo propietario. Inicialmente estos permisos son los del creador del archivo: ellos pueden ser cambiados con los programas chown(1) y chgrp(1).

Los permisos básicos que pueden ser asociados con un archivo son 'lectura'/'read' (permiso para leer sus datos), 'escribir/'write' (permisos para modificar lo) y 'ejecutar'/'execute' (permisos para correr como un programa). Cada archivo tiene tres conjuntos de permisos: uno para su usuario propietario, uno para su grupo propietario, y uno para los demás. Los 'privilegios' que usted logra cuando se registra en el sistema son solo la capacidad de lectura, escritura y ejecución de aquellos archivos para los cuales los bits de permisos están asignados a su 'identificador de usuario'/'user ID' o a uno de los grupos a los que pertenece, o archivos que han sido adecuados como accesibles para todo el mundo.

Para observar como estos permisos interactuan y como Unix los despliega vamos a mirar una lista de archivos en un hipotético sistema Unix.

snark:~$ ls -l notes

-rw-r--r-- 1 esr users 2993 Jun 17 11:00 notes

Este es un archivo ordinario de datos. La lista nos indica que él pertenece al usuario 'esr' y fue creado dentro de su grupo propietario 'users'. Probablemente la maquina en la que estamos ubico por defecto en ese grupo a cada usuario ordinario: otros grupos de usuario que comúnmente usted podrá ver son 'staff', 'admin', 'wheel' (por obvias razones los grupos no son muy importantes en computadores personales o estaciones de trabajo unipersonales). Su sistema Unix puede usar un grupo por defecto distinto. Quizás alguno nombrado después de su identificador de Usuario.

La cadena ‘-rw-r—r--’ representa los bits de permisos para el archivo. El primer bit es la posición para el bit del directorio: él puede mostrar 'd' si el archivo es un directorio, o mostrar 'l' si el archivo es un link simbólico. Los tres siguientes bit son los permisos del usuario, los tres contiguos son los permisos de grupo, y los tres últimos son los permisos para los demás (a menudo llamados 'permisos para todo el mundo'). En este archivo el usuario propietario 'esr' puede leer o escribir el archivo, otras personas en el grupo 'users' pueden leer el archivo y cualquier otra persona en el mundo puede leerlo. Estos son los típicos conjuntos de permisos para un archivo ordinario de datos.

Ahora vamos a mirar un archivo con unos permisos muy diferentes. Este archivo es el GCC (el compilador GNU del lenguaje de programación C)

snark:~$ ls -l /usr/bin/gcc

-rwxr-xr-x 3 root bin 64796 Mar 21 16:41 /usr/bin/gcc

Este archivo pertenece al usuario llamado 'root' y a un grupo llamado 'bin': este archivo puede ser escrito (modificado) solo por el usuario 'root',pero leído o ejecutado por cualquier otro. Esta es una típica titularidad y configuración de permisos para un comando pre-instalado en el sistema. El grupo 'bin' existe en algunos Unix para agrupar juntos a los comandos del sistema (el nombre es una reliquia histórica, es la abreviatura para 'binario'). En vez de el grupo 'usr' el sistema Unix podría usar el grupo 'root' (no es exactamente lo mismo que el usuario 'root').

El usuario 'root' es el nombre convencional para el usuario con el numero de identificación 0, que es una especial y privilegiada cuenta que puede sobrescribir todos los privilegios. El acceso a la raíz es útil pero peligrosa: un error al teclear mientras se esta como 'root' adentro del sistema puede alterar archivos críticos del sistema que un usuario ordinario no podría tocar usando el mismo comando.

Debido a que la cuenta root es muy poderosa, el acceso a ella debe ser protegido cuidadosamente. La clave del usuario 'root' es la pieza más crítica de seguridad en su sistema y es lo que muchos crackers e intrusos siempre desean conseguir.

Sobre claves: No la deje escrita y no escoja claves que fácilmente puedan ser adivinadas, como el primer nombre de su novio/a esposo/a. Esta es una mala practica muy común que ayuda a los crackers a no parar. En general no escoja ninguna palabra del diccionario: hay programas llamados 'diccionarios de crackers' que funcionan buscando claves probables a través de listas de comunes elecciones. Una buena técnica e escoger una combinación consistente en una palabra, un dígito, y otra palabra, como por ejemplo 'shark6cider' o 'jump3joy': esto hará que el tiempo necesario de búsqueda para un diccionario de búsqueda sea muy largo. No use estos ejemplos, se puede esperar que los crackers después de leer este documento incorporen estos ejemplos en sus diccionarios.

Ahora veamos un tercer caso:

snark:~$ ls -ld ~

drwxr-xr-x 89 esr users 9216 Jun 27 11:29 /home2/esr

snark:~$

Este archivo es un directorio (note el 'd' en el primer espacio de permisos). Observamos que el archivo puede ser escrito por esr pero leído y ejecutado por cualquier otro.

El permiso de lectura sobre un directorio le da la habilidad de listar el directorio – esto es mirar los nombres de los archivos y directorios que él contiene. El permiso de escritura da la habilidad de crear y borrar archivos en el directorio. Estas reglas tienen sentido si usted recuerda que el directorio incluye una lista de nombres de los archivos y subdirectorios que contiene.

Los permisos de ejecución en un directorio significa que es posible entrar en el directorio para abrir los archivos y los directorios contenidos en él. En efecto, él le da permisos para acceder a los i-nodes en el directorio. Un directorio sin ningún permiso de ejecución puede ser inútil.

Ocasionalmente usted podría ver un directorio que es ejecutable para los usuarios 'world' pero no es legible para estos mismos usuarios: Esto significa que un usuario aleatorio pude acceder a los archivos y directorios inferiores pero solo conociendo sus nombres exactos (el directorio no puede ser listado).

Es importante recordar que leer, escribir o ejecutar permisos en un directorio es independiente de los permisos en los archivos y directorios que contiene. En particular, la posibilidad de escritura en un directorio no da automáticamente acceso a los archivos existentes.

Finalmente vamos a ver los permisos del programa login.

snark:~$ ls -l /bin/login

-rwsr-xr-x 1 root bin 20164 Apr 17 12:57 /bin/login

Este programa tiene los permisos que podríamos esperar para un comando de sistema – excepto por la 's' donde el permiso de ejecución para el propietario debería estar. Esta es la manifestación visible de un permiso especial llamado el 'set-user-id' o 'setuid bit'

El bit setuid es normalmente adjuntado a programas que necesitan dar privilegios de root a usuarios ordinarios, pero de una forma controlada. Cuando este permiso es definido en un programa ejecutable usted logra los privilegios de el propietario de el archivo del programa mientras el programa corra por parte suya, sean o no de su propiedad.

Como la cuenta root misma, los programas setuid son útiles pero peligrosos. Cualquiera quien pueda subvertir o modificar un programa setuid propiedad del root puede usarlo para generar una ventana de sesión con privilegios de usuario. Por esta razón abrir un archivo en la mayoría de los Unix para escribir hace que dicho archivo desactive su bit setuid. Muchos ataques a la seguridad de Unix tratan de explotar bugs en los programas setuid buscando aprovecharse de ellos. Por eso administradores de seguridad de sistemas están consientes de estos programas tomando cuidadosas medidas y reacios a instalar nuevos.

Debemos resaltar un par de importantes detalles de lo que hemos visto ahora: A saber, como el grupo propietario y sus permisos son asignados cuando un archivo o directorio es creado por primera vez. El tema de grupos es de cuidado porque los usuarios pueden ser miembros de múltiples grupos, pero uno de ellos (especificado en la entrada del usuario en /etc/passwd) es el grupo por defecto para el usuario y normalmente será el propietario de los archivos creados por el usuario.

La historia detrás de los bits de permisos con los que inicia un archivo es un poco mas complicada. Un programa que crea un archivo normalmente especificará los permisos con los que dicho archivo comenzará. Pero estos permisos serán modificados por una variable de entorno del usuario llamada el 'umask'. El umask especifica cuales bit de permisos serán desactivados cuando es creado un archivo: El valor más común, y que esta establecido por defecto en la mayoría de sistemas es -------w- or 002,el cual desactiva el bit de la escritura para todo el mundo. Para mayores detalles mire la documentación del comando umask en su ventana de sesión.

El grupo inicial para un directorio es también un poco mas complicado. En algunos sistemas Unix un nuevo directorio obtiene el grupo por defecto del usuario creador (esta es una convención del sistema V): en otros, él obtiene el grupo propietario del directorio padre en el cual ha sido creado (esta es la convención BSD). En algunos modernos Unix, incluyendo Linux, la conducta definitiva puede ser seleccionada al configurar el set-group-ID en el directorio (chmod g+s).

10.6. Como las cosas pueden andar mal

Anteriormente se aludía que los sistemas de archivos eran frágiles. Ahora sabemos que para obtener un archivo usted tiene que saltar a través de lo que podría ser una arbitraria y larga cadena de directorios y referencias de i-node. Ahora supongamos que su disco duro produce un mal salto.

Si usted tiene suerte, solo desechará algunos datos de archivo. Si no tiene suerte, se podría corromper una estructura de directorio o un numero i-node y dejar en el limbo a la totalidad del árbol de un subdirectorio, o peor aún, resultar en una estructura corrompida que apunta múltiples rutas a un mismo bloque de disco o i-node. Tal daño puede ser propagado como una normal operación de archivo, desechando datos que no estaban en el lugar donde inicio el salto equivocado.

Afortunadamente, este tipo de contingencias se han convertido en algo poco común así como el hardware de los discos se han vuelto más confiables. Aun más, esto significa que Unix buscará revisar periódicamente la integridad del sistema de archivos para asegurarse que todo funcione correctamente. Los Unix modernos realizan rápidamente dicha revisión de integridad en cada partición en el momento del arranque, justo antes de montarlas. Cada pocos re inicios sucederá la revisión de integridad de manera mas detallada, tomándose unos pocos minutos de duración.

Si todo esto suena a que Unix es terriblemente complejo y susceptible de fallas, entonces puede sonar tranquilizador saber que estas revisiones en el momento del arranque comúnmente detectan y corrigen problemas normales antes de que ellos se conviertan en problemas realmente desastrosos. Otros sistemas operativos no tienen estas facilidades, lo cual aligera un poco el tiempo de arranque pero puede dejarlo a usted mas seriamente afectado cuando intente recuperarlo a mano (inclusive asumiendo que usted tiene una copia de las utilidades de Norton o cualquier otra cosa que este a primera mano)

Una de las tendencias en los diseños de los actuales Unix es el 'registro diario del sistema de archivos'/'journalling file systems'. Este sistema organiza el tráfico para el disco garantizando que el disco se encuentre en un consistente estado al cual pueda regresar. Esto hace que la revisión detallada sea mas rápida en el momento del arranque.


inicio

11. ¿Como trabajan los lenguajes de programación?

Ya hemos discutido sobre como los programas son corridos. En ultimas cada programa tiene que ser ejecutado como un flujo de datos que son instrucciones en el lenguaje maquina de su computador. Pero los seres humanos no manejan muy bien el lenguaje de maquina: hacer esto se ha convertido en un raro y oscuro arte aun entre hackers.

hoy en día casi todo el código de Unix esta escrito en un 'lenguaje de alto nivel'/'high-level language' excepto una pequeña cantidad de interfaces directas de hardware soportadas en el kernel mismo (el termino 'alto nivel' es un viejo termino usado para distinguir los 'lenguajes ensamblador'/'assembler languajes' de 'bajo nivel'/''low-level, los cuales son básicamente pequeños envoltorios alrededor del código de maquina.

Existen varios diferentes tipos de lenguajes de alto nivel. Para hablar acerca de ellos es útil tener en mente que el 'código fuente'/'source code' de un programa (la versión editable creada por un ser humano) tiene que ir a través de algún tipo de traducción al código maquina que la maquina pueda realmente correr.

11.1. Lenguajes Compilados

La mayoría de los tipos de lenguaje convencionales son lenguajes compilados. Los lenguajes compilados son traducidos a archivos ejecutables de maquina (en código binario) por un programa especial llamado (lógicamente) el compilador. Una vez ha sido generado el binario, usted puede hacerlo correr directamente sin tener que mirar de nuevo el código fuente (la mayoría del software es entregado en binarios compilados hechos desde código que usted no ve).

Los lenguajes compilados tienden a dar un excelente desempeño y a tener un mas completo acceso al sistema Operativo, pero también hay dificultad en programar en él.

C, el lenguaje en el que Unix esta escrito es de lejos es el mas importante de ellos (con su variante C++). FORTRAN es otro lenguaje compilado que aún es usado entre ingenieros y científicos pero con años de haber sido creado y mucho mas primitivo. En el mundo Unix estos son los lenguajes compilados que principalmente se usan: Fuera de ellos, COBOL es ampliamente usado para software de finanzas y negocios.

Antes eran usados muchos otros lenguajes compilados, pero la mayoría de ellos se han extinto o son estrictamente usados en herramientas de investigación. Si usted es un nuevo desarrollador de Unix usando un lenguaje compilado, estará probablemente usando C o C++.


11.2. Lenguajes Interpretados

Un lenguaje interpretado depende de un programa interprete que lea el código fuente y lo traduzca inmediatamente en cómputos y llamadas del sistema. El código fuente debe ser reinterpretado (y el interprete debe esta presente) cada vez que el código es ejecutado.

Los lenguajes interpretados tienden a ser mas lentos que los lenguajes compilados, y a menudo tienen limitado acceso al hardware y a partes importantes del sistema operativo. De otra parte estos lenguajes tienden a ser fáciles para programar y menos estrictos que los lenguajes compilados

Muchas utilidades de Unix, inlcuyendo la shell, bc, sed y awk son de hecho pequeños interpretes de lenguajes. BASICs es usualmente interpretado, de igual manera Tcl. Históricamente, el más importante lenguaje interpretado ha sido LISP (con mayores mejoras sobre la mayoría de sus sucesores). Hoy, las shells de Unix y el Lisp que se encuentra dentro del editor Emacs son probablemente los mas importantes lenguajes interpretados puros.

11.3. Lenguajes Pseudocódigo

Desde 1990 ha tomado creciente importancia un tipo de lenguaje híbrido que usa la compilación y la interpretación. los lenguajes P-code son como los lenguajes compilados por que la fuente es traducida a un binario compacto que es lo que usted realmente ejecuta, pero no es un código maquina. En lugar de ellos es un pseudocódigo (o código-p) que usualmente es bastante mas simple pero mas poderoso que un lenguaje real de máquina. Cuando usted corre el programa se interpreta el p-código.

El pseudocódigo puede correr casi tan rápido como un binario compilado (los interpretes de seudocódigo pueden ser simples sencillos y rápidos). Los lenguajes seudocódigo pueden mantener la flexibilidad y poder de un lenguaje interpretado.

Importantes lenguajes seudocódigo son Python, Perl y Java.


inicio