13 ago 2010

Procesos

Procesos

Un proceso, como hemos visto en secciones anteriores, es una abstracción que incluye:

- Una aplicación en ejecución
- Sus variables de entorno
- Información para identificarlo y para determinar su propietario
- El estado de entrada y salida de la aplicación
- El estado del proceso, incluyendo su prioridad y uso de recursos

El comando ps

El comando ps muestra por pantalla los comandos que se están ejecutando en un sistema.
Por defecto sólo se muestran "mis" procesos con un conjunto de información reducida

luciag@pluton:~> ps
PID TTY TIME CMD
25193 pts/2 0:00 tcsh

En este caso veo que tengo una aplicación en ejecución, que es la shell.
Si ejecuto otro proceso, por ejemplo, un find

luciag@pluton:~> find . -name mifichero > /dev/null &
[1] 25268
luciag@pluton:~> ps
PID TTY TIME CMD
25193 pts/2 0:00 tcsh
25268 pts/2 0:00 find

El 25268 es el PID, o identificador del proceso.
Si quiero que termine, lo mato:

luciag@pluton:~> kill 25268

Si quiero ver todos los procesos, hay opciones "específicas".
En Solaris ps -ef (he cortado los tres primeros)

luciag@pluton:~> ps -ef
UID PID PPID C STIME TTY TIME CMD
root 0 0 0 Jun 22 ? 0:13 sched
root 1 0 0 Jun 22 ? 0:08 /etc/init -
root 2 0 0 Jun 22 ? 0:00 pageout
root 3 0 0 Jun 22 ? 68:34 fsflush
[...]

Características de un proceso

El PID: Cuando lanzamos un comando, se le asigna un identificador de proceso único, en orden creciente y comenzando desde cero (los primeros procesos son "de sistema").

El PPID: La creación de nuevos procesos en Unix se realiza por la vía de duplicar un proceso existente invocando al comando fork(). Al proceso original se le llama "padre" y al nuevo proceso "hijo". El PPID de un proceso es el PID de su proceso padre.

El UID: Propietario del proceso, el que lo echó a correr, normalmente. Este usuario y root son los únicos que podrán hacer cosas con él, como matarlo.

El EUID: Puede ser distinto que el UID si se lanzó el proceso con setuid.

Entorno de un proceso

El entorno de un proceso está compuesto por las variables de entorno. Como vimos, hay variables de entorno globales, que son heredadas por los procesos hijos, y variables de shell o
Todos los procesos tienen asociadas variables como el directorio actual: $cwd o $PWD


Terminal de control.

En general los procesos están asociados a una terminal de control. Esta terminal determina el valor por defecto de los archivos stdin, stdout y stderr del proceso.

Una excepción a esto son los procesos llamados daemons, que una vez lanzados se desvinculan de su terminal de control y siguen ejecutando inclusive después de cerrada la sesión de usuario desde la cual se lanzaron

Opciones del comando ps

El comando tiene distintas opciones según el sistema operativo. En Linux, por ejemplo, con la opción -F vemos un listado "full" de nuestros procesos:

luciag@luna.acme.com:/usr/bin> ps -F
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD
luciag 5065 5064 0 18906 2544 1 09:30 pts/2 00:00:00 -tcsh
luciag 7041 5065 0 17471 1112 2 10:36 pts/2 00:00:00 ps -F

mientras que en Solaris no existe y debemos conformarnos con la -f.

luciag@pluton:~> ps -f
UID PID PPID C STIME TTY TIME CMD
luciag 25193 25191 0 12:56:41 pts/2 0:00 -tcsh

En Linux vemos dos columnas muy interesantes, relativas al consumo de memoria. RSS es el "resident set size" o memoria física en uso, y SZ (o VSZ) es el "virtual size" o tamaño del espacio de direcciones virtual, memoria direccionada por el proceso.

Para obtener esas opciones en Solaris podemos recurrir a la opción -o para hacernos nuestro propio ps a medida.

luciag@pluton:~> ps -ouid,pid,ppid,c,vsz,rss,stime,tty,time,fname
UID PID PPID C VSZ RSS STIME TT TIME COMMAND
20073 25193 25191 0 2696 2264 12:56:41 pts/2 0:00 tcsh

Existe una utilidad muy popular similar al taskmgr de Windows que es el top. Es un ps de todo el sistema que nos ordena por cierto criterio (normalmente por consumo de CPU o memoria) y va actualizando la salida por pantalla.

Procesos en background y nohup.
Los comandos de shell de UNIX pueden lanzarse en background añadiendo & al final. Esto significa que permitirán que sigamos utilizando la shell mientras ellos se ejecutan.

luciag@pluton:~> find . -name mifichero > /dev/null &
[1] 25415
luciag@pluton:~> jobs
[1] + Running find . -name mifichero > /dev/null

Cuando el comando se complete dirá por pantalla lo que ha ocurrido.

luciag@pluton:~>
[1] Done find . -name mifichero > /dev/null

Este comando tiene asociada la terminal. Si queremos que cuando nos marchemos de la sesión de la terminal el comando siga ejecutándose tenemos que usar nohup. Esto "desposee" al proceso de su terminal.

luciag@pluton:~> nohup find . -name mifichero > /dev/null &
[1] 25415
luciag@pluton:~> exit

Prioridades

Cuando hay más de un proceso listo para ejecutar, el kernel asigna el uso de CPU al proceso que tenga más prioridad. En UNIX esto varía dinámicamente, según el sistema operativo se utiliza un algoritmo que procura ser justo con los distintos procesos dando prioridad a los interactivos. Suelen tener en cuenta cuánto uso de CPU ha hecho el proceso últimamente, etc.

El usuario de un proceso puede querer influir en el algoritmo de prioridad con el comando nice. Este es un número que se asigna al proceso para ver cómo de "nice" (majete) es el comando con los demás. Cuanto más nice, más desventaja (todos le atropellan).

En los sistemas "tipo BSD" el valor del número nice puede variar entre -20 y +20, siendo por defecto 0. En los sistemas "tipo SysV" los valores posibles van de 0 a 39, siendo 20 el valor por defecto. Se puede modificar el valor nice por defecto en el momento de lanzar un programa lanzándolo a correr con el comando nice, o posteriormente utilizando el comando renice.

Estados de un proceso
Cuando se inicia un proceso, puede quedarse en uno de los siguientes estados:

- Ejecutándose (running): Básicamente haciendo su trabajo, bien en modo usuario o kernel.
- Listo pero esperando (runnable): Esperando su cuanto de CPU.
- Durmiendo (asleep): Esperando un recurso compartido (disco, red, etc)

Además de estos estados básicos podemos pararlo (stopped) o continuarlo. Y en ciertos casos "problemáticos" el proceso puede quedarse "zombie".


estados


Proceso zombi: proceso parado que queda en la tabla de procesos hasta que termine su padre. Este hecho se produce cuando el proceso padre no recoge el código de salida del proceso hijo.
Proceso huérfano: proceso en ejecución cuyo padre ha finalizado. El nuevo identificador de proceso padre (PPID) coincide con el identificador del proceso init (1).

Cancelar procesos

Si queremos cancelar la ejecución de un proceso, podemos utilizar el comando kill.
Si conocemos el PID usaremos kill PID

luciag@pluton:~> find . -name mifichero > /dev/null &
[1] 25440
luciag@pluton:~> ps
PID TTY TIME CMD
25193 pts/2 0:00 tcsh
25440 pts/2 0:01 find
luciag@pluton:~> kill 25440
luciag@pluton:~>
[1] Terminated find . -name mifichero > /dev/null

O si nos gusta más el comando jobs usaremos kill %job

luciag@pluton:~> find . -name mifichero > /dev/null &
[1] 25442
luciag@pluton:~> jobs
[1] + Running find . -name mifichero > /dev/null
luciag@pluton:~> kill %1
luciag@pluton:~>
[1] Terminated find . -name mifichero > /dev/null

Una vez leí un artículo de cómo usar el doom para matar procesos. Muy divertido pero poco útil.

Señales

Las señales de UNIX son un mecanismo para anunciar a un proceso que ha sucedido un evento que debe atender. Cuanto estamos usando el comando kill le estamos mandando una de las siguientes señales al proceso
  • Señal SIGTERM: kill -15 PID (que tenga a bien terminar)
  • Señal SIGKILL: kill -9 PID (que termine por la fuerza)
Pero existen más señales.
  • kill -STOP PID: Pausa el proceso (con el teclado CTRL-Z)
  • kill -CONT PID: Lo reanuda
Si de repente hemos pausado un proceso y queremos que se siga ejecutando en el background (porque se nos ocurre que queremos seguir tecleando, por ejemplo) escribimos bg

Lo pasaríamos al frente con fg.

Threads

Un proceso puede tener muchas secuencias de ejecución o hilos. Varias secuencias de ejecución (threads) pueden agruparse en un proceso y compartir algunos segmentos de memoria.

Existen opciones dentro del comando ps para examinar cómo los hilos se asocian a procesadores virtuales. Por lo menos, en Solaris, podemos ver los hilos. .

luciag@pluton:~> ps -e -olwp,fname,pid,fname,args | grep jrun
1 jrun 7334 jrun jrun -config ess.config -nohup -start ess
2 jrun 7334 jrun jrun -config ess.config -nohup -start ess
3 jrun 7334 jrun jrun -config ess.config -nohup -start ess
4 jrun 7334 jrun jrun -config ess.config -nohup -start ess
(he cortado por obvio el resto de LWPs)

Cotilleando el /proc filesystem

En Solaris, AIX y Linux, los procesos escriben a un sistema de ficheros especial llamado el /proc filesystem. Este filesystem contiene información especial de los procesos, que se puede utilizar leyendo desde los llamados comandos p*, que son similares en Solaris y AIX/Linux.


SolarisAIX, Linux
pflags [-r] [pid | core]procflags [-r] [pid]
pcred [pid | core]proccred [pid]
pmap [-rxIF] [pid | core]procmap [-F] [pid]
pldd [-F] [pid | core]procldd [-F] [pid]
pstack [-F] [pid | core]procstack [-F] [pid]
pfiles [-F] [pid]procfiles [-nF] [pid]
ptime command [argument]Not available

Los más interesantes son pstack y pfiles.
pstack me permite obtener un listado del stack por thread de llamadas al sistema.
pfiles me permite obtener información sobre todos los descriptores de archivo abiertos por un proceso.

Bibliografía
http://sial.org/howto/shell/background


12 ago 2010

Sistema de ficheros

Ficheros en UNIX

Se dice muchas veces que en UNIX todo son ficheros. Esto se debe a que se utiliza una representación tipo fichero de otras entidades que, por ejemplo, en Windows no lo son.

En UNIX son ficheros:

- Los ficheros regulares: Los que tienen contenido, que puede ser texto, ejecutable, datos binarios.
- Los directorios: En UNIX un directorio un contenedor de otros ficheros que no deja de estar caracterizado, a su vez, como un fichero.
- Los enlaces simbólicos: Son un tipo de ficheros que solamente apuntan a otro fichero.
- Los ficheros de dispositivo: Se refieren a dispositivos físicos, como una tarjeta de red o un CD-ROM.
- Los ficheros especiales de intercomunicación de proceso: named pipes, ipc sockets.

Distinguir los tipos de ficheros
Con el comando ls -l, obtenemos los atributos de los ficheros. La primera letra de los atributos es el tipo de fichero, siendo el resto los permisos como veremos a continuación.
En Linux también podemos distinguir el tipo de fichero por el color que se puede ver si utilizamos el argumento (--color): ls -l --color.
fichero regular (-): -rw------- /etc/passwd
fichero regular ejecutable(-): -rwxr-xr-x /bin/ls
directorio (d): drwx------ /dev/pts
enlace simbólico (l): lrwxrwxrwx /dev/cdrom -> /dev/scd0

fichero device caracter (c): crw------- /dev/ptmx
fichero device bloque (b): brw------- /dev/sda

unix domain socket (s): srwxrwxrwx /dev/gpmctl
named pipe (p): prw------- /dev/initctl

Explicación sobre los ficheros de dispositivo y especiales
¿Qué es un fichero de dispositivo? Los ficheros de dispositivo permiten a los programadores/usuarios interactuar con los dispositivos con llamadas al sistema. Existen varios tipos.
Los ficheros de bloque representan dispositivos que mueven los datos en forma de bloques, como los discos, CD-ROM, tarjetas de red, regiones de memoria, particiones, etc.
Los ficheros de carácter representan dispositivos con los que uno se comunica transmitiendo un carácter de cada vez, como el ratón, teclado, terminales virutales o módems serie.
También existen pseudo-dispositivos como /dev/null, /dev/zero, /dev/random. Los ficheros de dispositivo se crean con el comando mknod.
¿Qué es un named pipe? En Linux, es un mecanismo de comunicación entre procesos, operando el mecanismo FIFO (First In, First Out) de forma que un proceso que escribe al pipe por un proceso es el primero que será leído por el otro. Las named pipes son entidades en el sistema de ficheros creadas con el comando mkfifo.
¿Qué es un IPC socket o UNIX domain socket? Los sockets IPC son mecanismos de comunicacíon entre procesos similares a los sockets Internet (es decir se realizan los mismos tipos de llamadas al sistema para utilizarlos), pero sin usar la red.


El árbol de directorios

Todos los ficheros que se encuentran en un sistema operativo UNIX se colocan lógicamente en un mismo árbol, independientemente del número de discos duros que haya en el equipo (a diferencia de Windows).





Cuando entramos en la cuenta no aparecemos en la raíz del árbol sino en la casa del usuario.
En este árbol el directorio home del usuario stud1 es /u/course/stud1.
El directorio home de un usuario se especifica en su creación en el fichero en el que se guarda la información de los usuarios, llamado /etc/passwd.
Como se puede ver existe otro fichero llamado passwd, pero es el ejecutable. Este está en la ruta /bin/passwd.

Caminos absolutos y relativos, el comando cd

Para acceder a los distintos ficheros se utiliza el comando "cd", que puede funcionar por caminos absolutos y relativos.

- Camino absoluto:
Estando en /u/course/stud1 queremos listar los contenidos de /usr/tmp. Podemos escribir cd /usr/tmp y después ls.
Para ponernos en la raíz cd /
Para volver al home del usuario cd
Para ir al usuario que estábamos antes cd -

- Camino relativo:
Para subir un nivel cd ..
Si estando en /u/course/stud1 queremos ir a /u/course, cd .. (con espacio)
Si queremos ir a /u/ucc/dermoudy, cd ../../ucc/dermoudy.
Si estando en /u queremos ir a /u/course/stud1 podemos hacer cd ./course/stud1 o cd course/stud1

Situación en el árbol, comando pwd y el prompt

También se utilizan caminos absolutos y relativos en el manejo de ficheros. Por ejemplo para los comandos de visualización cat y more.

Para saber en qué parte del árbol estamos tenemos varias herramientas:
- El comando pwd
- La variable de entorno $cwd (solamente tcsh)
- El prompt: Configurable por el administrador, suele utilizar ciertas convenciones.
Suele incluirse el nombre del directorio:
luciag@luna.acme.com:/bin>
Si estoy en el raíz:
luciag@luna.acme.com:/>
El carácter :~ suele emplearse para "home":
luciag@luna.acme.com:~>
Por tanto si estoy en un directorio debajo del home:
luciag@luna.acme.com:~/bin>

Manejo de ficheros
Para crear un fichero vacío podemos utilizar el comando touch.
curso@pluton:~> touch fichero1
Si queremos crear un fichero nuevo a partir de otro, utilizamos el comando cp (copy). Para borrar, tenemos el comando rm (remove). Para mover el comando mv (move). Con opción -i para que nos pregunte interactivamente (-f es lo contrario, forzar sin preguntar).

curso@pluton:~> cp fichero1 fichero2
curso@pluton:~> mv fichero2 fichero3
curso@pluton:~> rm fichero3

Para crear un directorio mkdir. Los comandos mv, cp, rm se pueden utilizar para meter y sacar ficheros en directorios. El comando rmdir borra el directorio solo, no lo haría si tuviera ficheros dentro. Añadimos las opciones recursivas a los comandos anteriores para que podamos meter y sacar directorios de directorios. La opción -p de mkdir nos permite crear directorios de más profundidad

curso@pluton:~> mkdir directorio1
curso@pluton:~> mkdir -p directorio1/directorio2/directorio3
curso@pluton:~> rmdir directorio1/directorio2/directorio3
curso@pluton:~> cp fichero1 directorio1/directorio2
curso@pluton:~> cp -R directorio1/directorio2/ directorio1/directorio5
curso@pluton:~> mv directorio1/directorio5 directorio1/directorio8
curso@pluton:~> rm -r directorio1


Enlaces duros y simbólicos
Dentro del árbol de directorios dos ficheros pueden referirse a lo mismo.
- Enlace duro: Dos nombres para la misma cosa física. Utiles para administradores. No atraviesan las unidades fisicas (sistemas de ficheros). Se hacen con ln fichero1 fichero2. Cuando se borra uno se borra el otro.
- Enlace simbólico: Se hacen con ln -s, y el enlace simplemente "apunta" al fichero o directorio original. Se hacen con ln -s sourcename targetname. Cuando se borra el enlace no pasa nada. Cuando se borra el fichero original el enlace se queda "colgando" y pierde su sentido.


Permisos de ficheros y directorios

Existen tres tipos de permiso para un fichero:

- Lectura (r): Permite ver el contenido (p.e. con cat)
- Escritura (w): Permite modificar el contenido (p.e. con editor)
- Ejecución (x): Permite ejecutar el fichero (siempre que sea de "naturaleza" ejecutable).

Que para un directorio significan

- Lectura (r): Permite ver los ficheros que hay dentro (p.e. con ls)
- Escritura (w): Permite crear ficheros dentro o borrarlos
- Ejecución (x): Permite hacer un cd dentro de ese directorio.

Propietario, grupo y otros

Cada usuario es dueño de los archivos creados por él, hasta que los borre o los ceda a otro usuario. Cada usuario pertenece a un grupo, y puede compartir archivos con los usuarios de ese grupo. Cada archivo está asignado a un grupo de usuarios, al cual debe pertenecer su dueño.
- El propietario del fichero (u): Quien lo creó.
- El grupo (g): Los usuarios se definen asociados a grupos. El propietario tiene un grupo, estos permisos se aplicarían a los usuarios que estén en el mismo grupo que el propietario del fichero.
- Otros (o): Todos los que no sean el propietario ni los usuarios de su grupo.

Visualización de permisos
Los permisos de los ficheros se ven con ls -l fichero.
Los permisos de los directorios se ven con ls -ld fichero (de lo contrario vemos los de los ficheros que hay dentro).

El fichero /etc/passwd (root:root): -rw-r--r-- (lo puede leer propietario, grupo y otros, pero sólo escribir propietario - root)
El fichero /bin/ls (root:root): -rwxr-xr-x (lo puede leer y ejecutar propietario, grupo y otros, pero sólo escribir propietario, root)
Directorios: Entorno confiado: drwxr-xr-x (todos pueden ver mis cosas, pero no escribirlas)
Directorios: Entorno desconfiado: drwx------ (nadie más que yo puede ver mis cosas).

Cambio de permisos
Comando chmod: chmod [u/g/o][+/-][rwx] fichero. Lo vemos con un ejemplo:
Quiero dar permisos de escritura para mí y mi grupo: chmod ug+w fichero
Quiero dar permisos de ejecución para todos: chmod +x fichero
Quiero quitarle todos los permisos a los otros: chmod o-rwx fichero
Si estamos hablando de un directorio usamos la opción -R para que afecte recursivamente a los ficheros que hay dentro: chmod -R +rx /home/curso/directorio1

Los permisos en base octal
Esto de +rwx o -rwx parece poco cómodo cuando se trata de especificar varias acciones a la vez. El sistema operativo tiene una forma de interpretarlo con tres números en base octal. Si lectura es 4, escritura es 2, y ejecución es 1, siendo las combinaciones lectura+escritura 6, lectura+ejecución 5, escritura+ejecución 3, todo 7 y nada 0, podemos usar 3 números para dar los permisos:

Por ejemplo, escribir:
chmod -R 700 /home/curso/secreto ----> El propietario tiene TODOS los permisos, grupo y otros ninguno (drwx------)
chmod -R 750 /home/curso/secreto ----> El propietario tiene TODOS los permisos, el grupo lectura y ejecución, y los otros ninguno (drwxr-x---)
chmod -R 755 /home/curso/secreto ----> El propietario tiene TODOS los permisos, el grupo y los otros lectura y ejecución (drwxr-xr-x).


El setuid, setgid, y "sticky bit"
Los permisos setuid (como en -rwsr-xr–x, chmod 4755) en un fichero sirve para ejecutar con elevación al usuario, es decir, ejecutas el fichero como si fueras el propietario.

Por ejemplo el bit setuid se utiliza en el fichero /usr/bin/passwd para que todo el mundo pueda cambiar su contraseña de forma controlada. Pudiendo ejecutar este programa se consigue que un usuario pueda escribir en el fichero de claves(/etc/passwd) pero sin tener que dar permisos de escritura al fichero, lo cual seria un gran agujero de seguridad
Aunque la característica setuid es muy útil en muchos casos, puede plantear un riesgo de seguridad si el atributo setuid se asigna a programas ejecutables que no fueron diseñados cuidadosamente. Los usuarios pueden explotar vulnerabilidad en programas defectuosos para conseguir privilegios elevados permanentemente, o ejecutar de forma no intencionada un troyano.

Los permisos setgid (como en -rwxrwsr–x, chmod 2755) en un fichero sirven para ejecutar con elevación al grupo, es decir, ejecutas el fichero como si fueras del grupo.

En un directorio fuerza a todos los archivos y subdirectorios creados en ellos a pertenecer al grupo del dueño del directorio y no al grupo del usuario que crea el archivo o subdirectorio.
Los permisos stickybit (como en -rwxrwxrwt, chmod 1777) en un directorio no sirve actualmente para nada, ahora sirve para que sólo puedan borrarse los directorios propios y no los ajenos. Estos suelen ser los permisos del directorio /tmp.

La regla general para el setgid/setuid es "NO HACERLO", por motivos de seguridad.

Máscaras
Existe una forma de que decidir con qué permisos por defecto se crean los ficheros (e.g touch) y directorios (e.g. mkdir), que son las máscaras. Utilizo el comando umask con la siguiente convención: 0 permite y 1 prohibe.

0 = 000, 1 = 001 , 2 = 010, 3 = 011, 4 = 100, 5 = 101, 6 = 110, 7 = 111

Si veo umask 023: El 0 significa que el propietario tendra 000 (todo permitido, rwx). El 2 significa que el grupo tendra 010 (r-x, sólo lectura y ejecución). Y el 3 significa que los otros tendrán 011 (r--, sólo lectura)

Cambio de propietario
El administrador puede cambiar de propietario a un fichero con el comando chown, y el grupo con el comando chrgrp.

¿Podría tener ACLs en UNIX?
Una lista de control de acceso o ACL es lo que tenemos en Windows que nos permite establecer de forma más detallada los permisos sobre un fichero o directorio. Mediante extensiones del sistema de ficheros podría tener esta posibilidad, sin embargo no es algo estándar de UNIX, yo no lo he hecho nunca.


Metacaracteres
Al igual que en MS-DOS, tenemos metacaracteres como
? -> un solo caracter
* -> varios caracteres
[] -> rango de caracteres

La diferencia con MS-DOS en el manejo de metacaracteres en el sistema de ficheros es que por un lado, es la shell en UNIX quien los procesa, mientras que en MS-DOS es cada comando, y también que no se tienen en UNIX en cuenta las "extensiones".

ls -l /dev/* --> Lista todos los ficheros en el directorio /dev
ls /*/* ---> Lista todos los archivos que cuelguen de un solo directorio que cuelgue del raiz

Búsqueda de ficheros
Para buscar ficheros se utiliza el comando find. find efectúa una búsqueda en el árbol de directorios cuya raíz está en el nombre del directorio dado, evaluando las expresiones dondicionales de izquierda a derecha.

find /directorio/directorio -name nombrefichero -accion

La acción suele ser generalmente -print y es la que se toma cuando se omite.
Pero puede haber acciones más complejas como borrar los ficheros encontrados o cambiarlos de permisos.
curso@pluton:~> find . -name ‘vssver.vss’ -exec rm -fr {} \;
curso@pluton:~> find . -name "secreto.txt" -exec chmod o-r '{}' \;


En Linux tenemos un interesante comando de sintaxis mucho más sencilla que es "locate", que en lugar de leer el sistema de ficheros, lee la base de datos actualizada por el comando updatedb buscando por la cadena que le indicamos.

El basename y dirname
Basename es un comando que aplicado a una ruta completa, separa la parte "no directorio", y dirname es el comando complementario. Por ejemplo:


luciag@luna.acme.com:~> echo $PWD
/export/share/home/luciag


luciag@luna.acme.com:~> dirname `echo $PWD`
/export/share/home


luciag@luna.acme.com:~> basename `echo $PWD`
luciag


Con este ejemplo también hemos visto el uso del operador "acento grave" para ejecutar comandos dentro de otros comandos.

Terminales como archivos
Hemos visto que se puede escribir en archivo, pero que las terminales también son archivos.

¿Quiero saber dónde estoy escribiendo? Escribo tty. Esto devuelve el nombre del dispositivo asociado a mi terminal, que es una pseudoterminal /dev/pts/7.

Con el comando w puedo mirar quién está conectado

luciag@luna.acme.com:~> w
nachohs pts/6 nachow.acme.com 23Sep10 6days 0.07s 0.07s -csh

Con el comando write puedo mandarle un mensaje, puedo incluir a qué ventana quiero mandárselo (el precursor del net send)

luciag@luna.acme.com:~> write nachohs pts/6
hola, nacho.

También puedo iniciar una sesión de talk y elegir a qué ventana quiero mandárselo (el precursor del MSN - xD)

luciag@luna.acme.com:~> talk nachohs pts/6

Estructura interna de los archivos

Un archivo es una secuencia de bytes. Un byte es equivalente a un caracter. El sistema no impone estructura alguna a los archivos ni asigna significado a su contenido; el significado de los bytes depende totalmente de los programas que interpretan el archivo.

En ningún caso hay ningún byte que no haya sido colocado por el usuario o un programa. No hay caracter de fin de archivo. El núcleo del sistema UNIX se mantiene al tanto del tamaño de los archivos sin introducir ningún caracter especial.

El caracter nueva-línea es interpretado por las terminales como nueva línea y retorno de carro (CR LF, carriage-return y line-feed), necesario para desplegar correctamente los renglones en la terminal. Al apretar la tecla Enter el núcleo transmite a la terminal CR LF, pero en un archivo se guarda sólo LF.
Windows no hace eso, sino que almacena ambos caracteres, por eso cuando pasamos un fichero desde un sistema Windows, nos aparece un caracter espúreo que es el CR (visualizado como un ^M desde los editores en UNIX).

El sistema de ficheros

Un sistema UNIX típico puede contener miles de archivos, cientos de directorios y enlaces simbólicos. El árbol de éstos se puede expandir por múltiples discos físicos y particiones.

El sistema operativo está constituido por ciertos ficheros que vienen con unos permisos predeterminados, siempre con una organización que tiene aspectos comunes entre variantes de UNIX pero difiere en otros puntos. En muchos casos, los ficheros se distribuyen or función y no por cómo de frecuentemente pueden cambiar. Por ejemplo, el directorio /etc contiene ficheros que no cambian nunca y otros que cambian mucho.

Sin embargo hay una división similar a la de las "particiones" en Windows que es prácticamente común a todos los sistemas UNIX, que es la de los sistemas de ficheros.

Todos los sistemas UNIX tienen un filesystem que es el raíz o root filesystem, que contiene un conjunto mínimo de ficheros y directorios. Lo mínimo para sobrevivir. También son parte del root filesystem los dispositivos, que se almacenan en el directorio /dev. El kernel está en el root filesystem, en Linux se mantiene en un directorio llamado /boot. Directorios importantes en el root filesystem son /etc con ciertos ficheros críticos, /sbin y /bin con ejecutables, y en algunos casos /tmp (en otros es un filesystem separado).

Otros sistemas de ficheros o particiones de gran importancia son /usr y /var. En /usr se suelen encontrar los programas , y en /var una miscelánea de ficheros que pueden aumentar de tamaño, como spool, ficheros de trazas, los packages a instalar (Solaris) y la información de auditoría (si se activa).

Se suele hacer una partición aparte para los ficheros de usuario, siendo el punto de montaje preferido el /home. También si tenemos un área de datos grande podemos destinar un filesystem entero a dicha zona de datos, con nombres como /disk o similar. Para instalar programas opcionales, lo suyo es usar un filesystem cuyo nombre es /opt.

Bibliografía

Capítulo 6 del libro de Nemeth UNIX and Linux System Administration

http://iie.fing.edu.uy/~vagonbar/unixbas/sisarch1.htm

Ejercicio de este tema:
Un ejercicio de cambio de permisos*