Creando un Script en Python para montar particiones en Ubuntu 12.04

Tengo mi disco duro particionado en dos particiones: C: y D:, ambas NTFS. Al instalar el Ubuntu 12.04 desde Windows XP usando Wubi se crea un doble booteo: Windows y Ubuntu. Todo bien hasta aquí, el Ubuntu inicia y reinicia de lo mejor, al igual que el Windows. El Ubuntu coloca mi partición D: en la carpeta /host/:

Mi partición D: como la ve Ubuntu

Pero por ningún lado veía mi partición C:. El problema estaba en que debía montarla. Las instrucciones para hacerlo las saqué de esta web.

Luego de montar y desmontar la partición C: algunas veces, siguiendo las instrucciones de ubuntu-guia y restaurando el archivo /etc/fstab original, pensé que todos esos pasos podían automatizarse, y entonces recordé que Ubuntu ya viene con un intérprete de Python, el cual justamente se utiliza para automatizar ciertas tareas.

En este caso, la tarea consistía en:

Para acceder a las funciones y características del sistema operativo usando Python, se deben importar dos librerías "os" y "sys". El código para que el script ingrese con privilegios de root pidiendo la contraseña lo saqué de este enlace.

Una vez que ya podía ingresar como root, necesitaba una función de Python que me permitiera ejecutar comandos de sudo y almacenar en una variable los resultados. El primer comando de sudo que debía ejecutar mi script es "fdisk -l":

La función que necesito es os.popen() el cual me devuelve en una lista las particiones halladas y sus características, pero como cadenas de caracteres. Con la función print() puedo mostrar en la terminal el resultado y mostrar las particiones halladas. En mi caso la lista (almacenada en una variabble llamada "rem") tiene tres elementos, el script muestra esta lista y pide al usuario que ingrese la partición a montar con la función raw_input(). Se debe ingresar la partición tal y como se muestra en la terminal, en mi caso es "/dev/sde1" (sin las comillas). Luego el script evalúa si la partición existe, cuyo nombre está almacenado en una variable llamada "part", utilizando la función filter(). Si no existe, el script finaliza. Este chequeo es necesario pues el usuario puede ingresar cualquier otra cosa, desde equivocarse al escribir hasta intentar sabotear el sistema operativo. (la función raw_input() interpreta lo ingresado como caracteres, pero la función input() interpreta lo ingresado como comandos de Python; ambas funciones pertenecen a este lenguaje, mucho cuidado con confundirlas!).

La función filter() es el equivalente en Python de las funciones de C# Linq.Where().

La línea:

n = filter(lambda x: x.find(part, 0, len(x)) > -1, rem) 

en C# 3.0 sería:

var n = rem.Where(c => c.IndexOf(part) != -1);

En Python, si lalongitud de "n" es cero, es que no se ha hallado la partición ingresada.

Luego debo ejecutar el comando de sudo "blkid particion_elegida":

El resultado, guardado en la variable "rem", es una lista con un solo elemento tipo cadena de caracteres, el cual contiene el ID y el tipo de partición. Extraigo ambos con la función filter() y con el código que encontré en este enlace, el cual usa expresiones regulares para extraer la cadena de caracteres que se necesita, por este motivo debo importar también la librería "re".

Una vez que tengo todos los datos que necesito (partición, ID y tipo) le pido al usuario que escriba el nombre de la carpeta dentro de /media/ donde el script montará la partición. Si la carpeta no existe, el script la creará automáticamente. La línea que evalúa si la carpeta existe es:

os.path.isdir("media/carpeta_ingresada")

La variable con la ruta completa es "t2". Para crear la carpeta, si ésta no existe, utilizo el comando "mkdir" de sudo.

Python no posee un "switch" o un "Select Case" como otros lenguajes de programación, pero esto se resuelve con algunos if... else. En este caso, es para evaluar el tipo de partición y "armar" la línea que se añadirá al archivo /etc/fstab.

El código completo es:

#! /usr/bin/env python

import os;

import re;

import sys; 

# http://stackoverflow.com/questions/5222333/authentication-in-python-script-to-run-as-root

euid = os.geteuid()

if euid != 0:

    print "Iniciando sudo para ingresar como root..."

    args = ['sudo', sys.executable] + sys.argv + [os.environ]

    # the next line replaces the currently-running process with the sudo

    os.execlpe('sudo', *args) 

if euid == 0:

    print 'Corriendo, su euid es: ', euid

else:

    print 'No se pudo iniciar como root. Cerrando script'

    sys.exit()

 

# http://mail.python.org/pipermail/python-es/2007-December/019270.html

rem = os.popen("sudo fdisk -l").readlines() # obtengo las particiones 

for i in rem:

    print

# http://www.daniweb.com/software-development/python/threads/12326/how-to-do-input-in-python

# "input" interpreta lo ingresado como comando, se debe usar raw_input 

part = raw_input("Escriba la particion a montar: ")

n = filter(lambda x: x.find(part, 0, len(x)) > -1, rem) 

if len(n) == 0:

    print ("La particion no existe")

else:

    t = ("sudo blkid ", part) # obtengo el UUID

    sudo1 = ''

    sudo1 = sudo1.join(t)

    rem = os.popen(sudo1).readlines() 

    if len(rem) == 0:

        print("Particion no valida")

    else:

        partInfo = rem[0].split()

        IdPart = filter(lambda x: x.upper().find('UUID', 0, len(x)) > -1, partInfo)

        tipoPart = filter(lambda x: x.upper().find('TYPE', 0, len(x)) > -1, partInfo)       

        # http://stackoverflow.com/questions/4666973/how-to-extract-a-substring-from-inside-a-string-in-python

        uuID = re.search('"(.+?)"', IdPart[0]).group(1)

        tipoParticion = re.search('"(.+?)"', tipoPart[0]).group(1)

        print tipoParticion 

        carpeta = raw_input('ingrese el nombre de la carpeta dentro de /media/ donde montar la particion. ')

        t = ('/media/', carpeta)       

        t2 = ''

        t2 = t2.join(t) 

        if not os.path.isdir(t2):

              t = ('sudo mkdir /media/', carpeta)

              sudo1 = ''

              sudo1 = sudo1.join(t)

              rem = os.popen(sudo1).readlines()

        # http://snipplr.com/view/6630/

        # http://www.tutorialspoint.com/python/python_files_io.htm       

        if tipoParticion.upper() == 'NTFS':

            t = ('UUID=', uuID, '      /media/', carpeta, '     ntfs-3g default       0      0')

        elif tipoParticion.upper() == 'FAT':

            t = ('UUID=', uuID, '      /media/', carpeta, '     vfat rw,uid=1000,gid=1000      0      0')

        elif tipoParticion.upper() == 'EXT4':

            t = ('UUID=', uuID, '      /media/', carpeta, '     ext4 errors=remount-ro 0      1')

        else:

            t = ''

           

        if len(t) > 0:

            linea = ''

            linea = linea.join(t)           

            with open('/etc/fstab', 'a') as fstab_file:

                fstab_file.writelines(linea)

                fstab_file.close()

            print 'Se ha montado la particion, reinicie el sistema'

        else:

            print('particion desconocida')

 

 

Como esto es html y no Python, es mejor descargar el script de aquí.

Este script sólo ha sido probado montando particiones NTFS en Ubuntu 12.04 y en carpetas dentro de /media/ cuyos nombres no contengan espacios. La partición no debe estar listada en /host/ o el sistema Ubuntu botará error al iniciar.