1.1: Contexto
- Page ID
- 55186
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)Líneas de Comando y Sistemas Operativos
Muchos sistemas operativos, incluyendo Microsoft Windows y Mac OS X, incluyen una interfaz de línea de comandos (CLI) así como la interfaz gráfica de usuario estándar (GUI). En este libro, nos interesan principalmente las interfaces de línea de comandos incluidas como parte de un sistema operativo derivado del entorno históricamente natural para la computación científica, Unix, incluyendo las diversas distribuciones de Linux (por ejemplo, Ubuntu Linux y Red Hat Linux), BSD Unix y Mac OS X.
Aun así, es útil comprender los sistemas operativos informáticos modernos y cómo interactúan con el hardware y otro software. Un sistema operativo se considera vagamente como el conjunto de software que administra y asigna el hardware subyacente, dividiendo la cantidad de tiempo que cada usuario o programa puede usar en la unidad central de procesamiento (CPU), por ejemplo, o guardar los archivos secretos de un usuario en el disco duro y protegerlos del acceso por otros usuarios. Cuando un usuario inicia un programa, ese programa es “propiedad” del usuario en cuestión. Si un programa desea interactuar con el hardware de alguna manera (por ejemplo, leer un archivo o mostrar una imagen a la pantalla), debe canalizar esa solicitud a través del sistema operativo, que generalmente manejará esas solicitudes de tal manera que ningún programa pueda monopolizar la atención del sistema operativo o el hardware.
La figura anterior ilustra los cuatro principales recursos “consumibles” disponibles para las computadoras modernas:
- La CPU. Algunas computadoras tienen múltiples CPU y algunas CPU tienen múltiples “núcleos” de procesamiento. Generalmente, si hay n núcleos totales y k programas ejecutándose, entonces cada programa puede acceder hasta n/k potencia de procesamiento por unidad de tiempo. La excepción es cuando hay muchos procesos (digamos, unos pocos miles); en este caso, el sistema operativo debe dedicar una cantidad considerable de tiempo simplemente cambiando entre los diversos programas, reduciendo efectivamente la cantidad de potencia de procesamiento disponible para todos los procesos.
- Discos duros u otro “almacenamiento persistente”. Dichas unidades pueden almacenar grandes cantidades de datos, pero el acceso es bastante lento en comparación con la velocidad a la que se ejecuta la CPU. El almacenamiento persistente suele estar disponible a través de unidades remotas “mapeadas” a través de la red, lo que hace que el acceso sea aún más lento (pero quizás proporcionando mucho más espacio).
- RAM, o memoria de acceso aleatorio. Debido a que los discos duros son tan lentos, todos los datos deben copiarse en la RAM de “memoria de trabajo” para que pueda acceder la CPU. La RAM es mucho más rápida pero también mucho más cara (y por lo tanto generalmente proporciona menos almacenamiento total). Cuando se llena la RAM, muchos sistemas operativos recurrirán a tratar de usar el disco duro como si fuera RAM (conocido como “intercambio” porque los datos se intercambian constantemente dentro y fuera de la RAM). Debido a la diferencia de velocidad, puede parecerle al usuario como si la computadora se hubiera estrellado, cuando en realidad simplemente está trabajando a un ritmo glacial.
- La conexión de red, que proporciona acceso al mundo exterior. Si varios programas desean acceder a la red, deben compartir tiempo en la conexión, al igual que para la CPU.
Debido a que las interfaces de software que usamos todos los días, las que nos muestran nuestros íconos de escritorio y nos permiten iniciar otros programas, son tan omnipresentes, que a menudo pensamos en ellas como parte del sistema operativo. Técnicamente, sin embargo, estos son programas que son ejecutados por el usuario (generalmente de forma automática al iniciar sesión o al inicio) y deben realizar solicitudes del sistema operativo, al igual que cualquier otro programa. Los sistemas operativos como Microsoft Windows y Mac OS X son en realidad sistemas operativos integrados con amplias suites de software de usuario.
Una breve historia
La historia completa de los sistemas operativos utilizados por los investigadores computacionales es larga y compleja, pero un breve resumen y explicación de varios términos y acrónimos de uso común como BSD, “open source” y GNU pueden ser de interés. (Los lectores impacientes pueden en este punto saltar adelante, aunque algunos conceptos en esta subsección pueden ayudar a comprender la relación entre el hardware y el software de la computadora).
La investigación fundamental sobre cómo los componentes físicos que componen la maquinaria informática deben interactuar con los usuarios a través del software se realizó ya en las décadas de 1950 y 1960. En estas décadas, las computadoras eran raras, máquinas del tamaño de una habitación y eran compartidas por un gran número de personas. A mediados de la década de 1960, investigadores de Bell Labs (entonces propiedad de AT&T), el Instituto de Tecnología de Massachusetts y General Electric desarrollaron un novedoso sistema operativo conocido como Multics, abreviatura de Multiplexed Information and Computing Service. Multics introdujo una serie de conceptos importantes, incluidos los avances en cómo se organizan los archivos y cómo se asignan los recursos a múltiples usuarios.
A principios de la década de 1970, varios ingenieros de Bell Labs no estaban contentos con el tamaño y la complejidad de Multics, y decidieron reproducir la mayor parte de la funcionalidad en una versión reducida que llamaron Unics, esta vez abreviatura de Uniplexed Information and Computing Service, un juego con el nombre de Multics pero sin denotar un gran diferencia en la estructura. A medida que avanzaba el trabajo, el sistema operativo pasó a llamarse Unix. Otros desarrollos permitieron que el software se tradujera (o portara) fácilmente para su uso en hardware de computadora de diferentes tipos. Estas primeras versiones de Multics y Unix también fueron pioneras en el intercambio automático y simultáneo de recursos de hardware (como el tiempo de CPU) entre usuarios, así como archivos protegidos que pertenecen a un usuario de otros, características importantes cuando muchos investigadores deben compartir una sola máquina. (Estas mismas características nos permiten realizar múltiples tareas en computadoras de escritorio modernas).
Durante este tiempo, AT&T y su subsidiaria Bell Labs tuvieron prohibido por la legislación antimonopolio comercializar cualquier proyecto que no estuviera directamente relacionado con la telefonía. Como tal, los investigadores licenciaron, de forma gratuita, copias del software Unix a cualquier parte interesada. La combinación de una tecnología robusta, fácil portabilidad y costo gratuito aseguraron que hubiera un gran número de usuarios interesados, particularmente en la academia. En poco tiempo, se escribieron muchas aplicaciones para operar sobre el framework Unix (muchas de las cuales usaremos en este libro), lo que representa un poderoso entorno informático incluso antes de la década de 1980.
A principios de la década de 1980, se resolvió la demanda antimonopolio contra AT&T, y AT&T era libre de comercializar Unix, lo que hicieron con lo que solo podemos suponer que era entusiasmo. Como era de esperar, los nuevos términos y costos no fueron favorables para la base de usuarios de Unix, en gran parte académica y centrada en la investigación, causando gran preocupación para muchos tan fuertemente invertidos en la tecnología.
Afortunadamente, un grupo de investigadores de la Universidad de California (UC), Berkeley, llevaba algún tiempo trabajando en su propia investigación con Unix, rediseñándola lentamente de adentro hacia afuera. Al final de la demanda antimonopolio de AT&T, habían producido un proyecto que parecía y funcionaba como Unix de AT&T: BSD (para Berkeley Systems Distribution) Unix. BSD Unix fue lanzado bajo una nueva licencia de software conocida como la licencia BSD: cualquier persona era libre de copiar el software de forma gratuita, usarlo, modificarlo y redistribuirlo, siempre y cuando cualquier cosa redistribuida también se liberara bajo la misma licencia BSD y se le diera crédito a UC Berkeley (esta última cláusula fue posterior caído). Las versiones modernas de BSD Unix, aunque no se usan mucho en la academia, se consideran sistemas operativos robustos y seguros, aunque en consecuencia a menudo carecen de características de vanguardia o experimentales.
En el mismo año en que AT&T buscó comercializar Unix, el informático Richard Stallmann respondió fundando la organización sin fines de lucro Free Software Foundation (FSF), que se dedicó a la idea de que el software debía ser libre de propiedad, y que los usuarios debían ser libres de usarlo, copiarlo, modificarlo y redistribuirlo. También inició el proyecto de sistema operativo GNU, con el objetivo de recrear el entorno Unix bajo una licencia similar a la de BSD Unix. (GNU significa No Unix de GNU: un acrónimo recursivo y autorreferenciado que ejemplifica el peculiar humor de los informáticos).
El proyecto GNU implementó un esquema de licencias que difería algo de la licencia BSD. El software GNU debía ser licenciado bajo términos creados específicamente para el proyecto, llamados GPL, o GNU Public License. La GPL permite a cualquier persona usar el software de la manera que considere conveniente (incluyendo distribuir de forma gratuita o vender cualquier programa construido con él), siempre que también ponga a disposición el código legible por humanos que haya creado y lo licencie bajo la GPL también (la esencia del “código abierto” [1]). Es como si la Ford Motor Company regalara los planos de un auto nuevo, con el requisito de que cualquier auto diseñado con esos planos también venga con planos propios y reglas similares. Por esta razón, el software escrito bajo la GPL tiene una tendencia natural a propagarse y crecer. Irónica e ingeniosamente, Richard Stallmann y el grupo BSD utilizaron el sistema de licencias, generalmente destinado a proteger la difusión de la propiedad intelectual y provocando la crisis de Unix de la década de 1980, para garantizar la libertad perpetua de su trabajo (y con ello, el legado de Unix).
Si bien Stallmann y la FSF lograron recrear la mayor parte del software que componía el entorno estándar Unix (el software incluido), no volvieron a crear inmediatamente el núcleo del sistema operativo (también llamado kernel). En 1991, el estudiante de informática Linus Torvalds comenzó a trabajar en este componente básico con licencia de la GPL, al que llamó Linux (pronunciado “lin-ucks”, según lo prescrito por el propio autor). Muchos otros desarrolladores contribuyeron rápidamente al proyecto, y ahora Linux está disponible en una variedad de “distribuciones”, como Ubuntu Linux y Red Hat Linux, incluyendo tanto el kernel de Linux como una colección de software GPL compatible con Unix (y ocasionalmente no GPL). Las distribuciones de Linux difieren principalmente en qué paquetes de software vienen incluidos con el kernel y cómo se instalan y administran estos paquetes.
Hoy en día, un número significativo de proyectos de software se emiten bajo las licencias GPL, BSD o similares “abiertas”. Estos incluyen tanto los proyectos Python como R, así como la mayoría de las otras piezas de software cubiertas en este libro. De hecho, la idea también se ha popularizado para proyectos sin código, con muchos documentos (incluido este) publicados bajo licencias abiertas como Creative Commons, que permiten a otros utilizar materiales de forma gratuita, siempre que se sigan ciertas disposiciones.
- El software moderno se escribe inicialmente usando “código fuente” legible por humanos, luego se compila en software legible por máquina. Dado el código fuente, es fácil producir software, pero lo contrario no es necesariamente cierto. Las distinciones entre las licencias BSD y GPL son, por lo tanto, significativas.