Servicios del sistema operativo

La librería estándar de Python (en particular el módulo os) es en muchos sentidos una adaptación de las llamadas al sistema POSIX. Hasta tal punto que la propia documentación hace referencia en varias funciones al manual en línea (páginas man) equivalentes.

Línea de comandos

Los argumentos en línea de comandos está disponibles en una lista de cadenas: sys.argv. El módulo "oficial" para tratamiento de la línea de comando es argparse.


In [14]:
import sys
sys.argv


Out[14]:
['-c',
 '-f',
 '/home/david/.ipython/profile_default/security/kernel-6e8291b9-a0ec-4663-b471-6df27d548bb5.json',
 "--IPKernelApp.parent_appname='ipython-notebook'",
 '--profile-dir',
 '/home/david/.ipython/profile_default',
 '--parent=1']

In [12]:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
    print("verbosity turned on")


usage: -c [-h] [--verbosity VERBOSITY]
-c: error: unrecognized arguments: -f /home/david/.ipython/profile_default/security/kernel-6e8291b9-a0ec-4663-b471-6df27d548bb5.json --IPKernelApp.parent_appname='ipython-notebook' --profile-dir /home/david/.ipython/profile_default --parent=1
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2
To exit: use 'exit', 'quit', or Ctrl-D.

Información básica


In [2]:
import os
os.name


Out[2]:
'posix'

Variables de entorno


In [3]:
os.environ


Out[3]:
{'WINDOWID': '29360134', 'LESS': '-rMRg', 'ALIOTH_USER': 'davidvilla-guest', 'GJS_DEBUG_OUTPUT': 'stderr', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'LOGNAME': 'david', 'USER': 'david', 'HOME': '/home/david', 'XDG_VTNR': '7', 'PATH': '/home/david/repos/omnetpp-4.2.1/bin:/home/david/bin:/home/david/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games', 'QUILT_COLORS': 'diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33', 'DEBFULLNAME': 'David Villa Alises', 'DISPLAY': ':0', 'GLOBIGNORE': '.svn:.cvs:.hg', 'SSH_AGENT_PID': '1770', 'LANG': 'es_ES.UTF-8', 'TERM': 'xterm-color', 'SHELL': '/bin/bash', 'XAUTHORITY': '/var/run/gdm3/auth-for-david-IiRjc1/database', 'SESSION_MANAGER': 'local/amy:@/tmp/.ICE-unix/1711,unix/amy:/tmp/.ICE-unix/1711', 'SHLVL': '1', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'WINDOWPATH': '7', 'EDITOR': 'jed', 'QUILT_PATCHES': 'debian/patches', 'DEBEMAIL': 'David.Villa@gmail.com', 'USERNAME': 'david', 'QUILT_REFRESH_ARGS': '-p ab --no-timestamps --no-index', 'XDG_RUNTIME_DIR': '/run/user/1000', 'PYTHONPATH': '/home/david/repos/qoogol', 'COMP_WORDBREAKS': ' \t\n"\'><;|&(:', 'VTE_VERSION': '3602', 'SSH_AUTH_SOCK': '/run/user/1000/keyring/ssh', 'GDMSESSION': 'default', 'DEBREPO_URL': 'arcorepo@babel.esi.uclm.es/var/arcorepo', 'GIT_PAGER': 'cat', 'QUILT_PATCH_OPTS': '--reject-format=unified', 'XDG_SESSION_ID': '1', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-5bY9II4nes,guid=a8fbbb2fa446ab1388d433c453ba4d91', '_': '/usr/bin/ipython', 'DESKTOP_SESSION': 'default', 'GPG_AGENT_INFO': '/run/user/1000/keyring/gpg:0:1', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'DEBSIGN_KEYID': '201B8868', 'OLDPWD': '/home/david', 'GDM_LANG': 'es_ES.UTF-8', 'CLICOLOR': '1', 'HISTCONTROL': 'ignoreboth', 'XDG_DATA_DIRS': '/usr/share/gnome:/usr/local/share/:/usr/share/', 'PWD': '/home/david/repos/python-intro', 'DJANGO_SETTINGS_MODULE': 'settings', 'FIGNORE': '.svn:.cvs:.hg', 'COLORTERM': 'gnome-terminal', 'XDG_MENU_PREFIX': 'gnome-', 'LS_COLORS': 'rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:', 'PAGER': 'cat', 'GJS_DEBUG_TOPICS': 'JS ERROR;JS LOG', 'QUILT_DIFF_ARGS': '-p ab --no-timestamps --no-index --color=auto', 'XDG_SEAT': 'seat0'}

In [4]:
os.getenv('SHELL')


Out[4]:
'/bin/bash'

In [37]:
os.putenv('PATH', '/usr/bin:/usr/sbin:/usr/local/bin')

In [38]:
os.unsetenv('FOO')

Sistema de ficheros


In [4]:
os.chdir('/tmp/')

In [5]:
os.getcwd()


Out[5]:
'/tmp'

Crear un directorio:


In [33]:
os.mkdir('/tmp/foo-dir')

Borrar un directorio:


In [32]:
os.rmdir('/tmp/foo-dir')

In [11]:
os.stat('/etc/motd')


Out[11]:
posix.stat_result(st_mode=33188, st_ino=131214, st_dev=2054L, st_nlink=1, st_uid=0, st_gid=0, st_size=286, st_atime=1404899737, st_mtime=1390906391, st_ctime=1394548950)

Crear una _pipe__:


In [14]:
os.pipe()


Out[14]:
(43, 44)

Crear un FIFO (una named pipe):


In [27]:
os.mkfifo('/tmp/fifo')

Comprobar el acceso a un fichero para el usuario efectivo:


In [15]:
os.access('/etc/motd', os.R_OK)


Out[15]:
True

Cambiar los permisos de acceso a un fichero:


In [17]:
!touch /tmp/foo

In [20]:
import stat
os.chmod('/tmp/foo', stat.S_IWUSR)

Cambiar el propietario de un fichero:


In [22]:
uid = os.getuid()
gid = os.getgid()
os.chown('/tmp/foo', uid, gid)

Crear un enlace "duro":


In [30]:
os.link('/tmp/foo', '/tmp/bar')

Borrar un fichero:


In [34]:
os.remove('/tmp/bar')

Crear un enlace simbólico:


In [35]:
os.symlink('/tmp/foo', '/tmp/bar')

Listar el contenido de un directorio:


In [5]:
print(os.listdir('/'))


['tmp', 'proc', 'usr', 'boot', 'root', 'dev', 'srv', 'run', 'bin', 'lost+found', 'salt-syndic.log', 'sys', '.bash_history', 'etc', 'vmlinuz.old', 'dropbox', 'bootx64.efi', 'initrd.img', 'vmlinuz', 'sbin', 'lib', 'media', 'home', 'opt', 'lib64', 'var', 'mnt', 'initrd.img.old']

In [8]:
os.curdir


Out[8]:
'.'

In [9]:
os.pardir


Out[9]:
'..'

In [10]:
os.sep


Out[10]:
'/'

In [11]:
os.devnull


Out[11]:
'/dev/null'

Procesos

Crear un subproceso:


In [36]:
os.fork()


Out[36]:
3875

Esperar la terminación de un subproceso (y recoger su valor de retorno);:


In [ ]:
os.wait()

Terminar (con error) el proceso actual:


In [ ]:
# os.abort()

Ejecutar un binario en el proceso actual:


In [ ]:
# os.execl('/bin/ls', '')

Ejecutar un binario en un proceso nuevo:


In [ ]:
os.spawnl('/bin/ls', '')

Ejecutar un binario en un subproceso y obtener la salida estándar:


In [7]:
os.system('ls /')


Out[7]:
0

Obtener el PID actual:


In [20]:
os.getpid()


Out[20]:
1776

El PID del padre del proceso actual:


In [21]:
os.getppid()


Out[21]:
10972

UID del propietario del proceso actual:


In [10]:
os.getuid()


Out[10]:
1000

GID del propietario del proceso actual


In [11]:
os.getgid()


Out[11]:
1000

In [3]:
os.getgroups()


Out[3]:
[24, 25, 29, 30, 44, 46, 104, 113, 114, 1000]

Identificador del grupo de procesos:


In [16]:
os.getpgid(0)


Out[16]:
10972

In [18]:
os.getpgrp()


Out[18]:
10972

Crear una sesión y asignar un identificador de grupo.


In [ ]:
os.setsid()

In [36]:
os.getsid(os.fork())


Out[36]:
1776

Creación de un subproceso con acceso a su entrada/salida: os.popen, os.popen2, os.popen3. Estas funciones son equivalentes a la llamadasal sistema POSIX, pero están obsoletas en favor del módulo subprocess.


In [3]:
print(os.popen('ls /').read())


bin
boot
bootx64.efi
dev
dropbox
etc
home
initrd.img
initrd.img.old
lib
lib64
lost+found
media
mnt
opt
proc
root
run
salt-syndic.log
sbin
srv
sys
tmp
usr
var
vmlinuz
vmlinuz.old

Señales

Enviar una señal a un proceso (dado su PID):


In [10]:
import signal

child = os.fork()
os.kill(child, signal.SIGQUIT)
os.wait()


Out[10]:
(28184, 3)

Enviar una señal a un grupo de procesos


In [11]:
pid = os.fork()
if not pid:
    os.setsid()
    os.system('sleep 100')
    os.exit(0)

os.killpg(pid, signal.SIGKILL)
os.wait()


Out[11]:
(28185, 9)

In [12]:
def handler(num, *args):
    print num, args

signal.signal(signal.SIGQUIT, handler)

Usuarios


In [13]:
os.getlogin()


Out[13]:
'david'

In [ ]: