2012-01-11 16 views
5

He configurado una secuencia de comandos de Python que simula un sistema operativo. Tiene un símbolo del sistema y un sistema de archivos virtual. Estoy usando el módulo shelve para simular el sistema de archivos, ya que es multidimensional para admitir una jerarquía de directorios. Sin embargo, tengo problemas para implementar un comando 'cd'. No sé cómo entrar y salir de directorios, a pesar de que tengo un pequeño conjunto de directorios creados la primera vez que inicias el programa. Aquí está mi código:Cómo implementar un sistema de archivos virtual Python usando shelve

import shelve 

fs = shelve.open('filesystem.fs') 
directory = 'root' 
raw_dir = None 
est_dir = None 

def install(fs): 
    fs['System'] = {} 
    fs['Users'] = {} 
    username = raw_input('What do you want your username to be? ') 
    fs['Users'][username] = {} 

try: 
    test = fs['runbefore'] 
    del test 
except: 
    fs['runbefore'] = None 
    install(fs) 

def ls(args): 
    print 'Contents of directory', directory + ':' 
    if raw_dir: 
     for i in fs[raw_dir[0]][raw_dir[1]][raw_dir[2]][raw_dir[3]]: 
      print i 
    else: 
     for i in fs: 
      print i 

def cd(args): 
    if len(args.split()) > 1: 
     if args.split()[1] == '..': 
      if raw_dir[3]: 
       raw_dir[3] = 0 
      elif raw_dir[2]: 
       raw_dir[2] = 0 
      elif raw_dir[1]: 
       raw_dir[1] = 0 
      else: 
       print "cd : cannot go above root" 

COMMANDS = {'ls' : ls} 

while True: 
    raw = raw_input('> ') 
    cmd = raw.split()[0] 
    if cmd in COMMANDS: 
     COMMANDS[cmd](raw) 

#Use break instead of exit, so you will get to this point. 
raw_input('Press the Enter key to shutdown...') 

ahora no recibo un error, sólo tengo ni idea de cómo hacerlo y no tenía idea de qué buscar, además de 'sistema de archivos estantería pitón', y que no lo hace obtener algo útil.

+1

¡Interesante! ¿Te importaría compartir para qué sirve esto? –

+0

Configuré tu código para trabajar con python3.x en mi Eclipse ... jugando con él ahora mismo. Estoy un poco confundido hasta ahora. Pero eso está bien. Como David mencionó, ¿podrías darnos un contexto? – Bry6n

+0

Es así que puedo probarlo. Solo por diversión. – elijaheac

Respuesta

7

que proporcionan algo de código para ayudarle a salir adelante, pero en primer lugar, un consejo general que debe ayudar con su diseño:

  • La razón por la que está teniendo dificultades con el cambio de directorios es que se está representando la variable del directorio actual de la manera incorrecta. Su directorio actual debería ser algo así como una lista, desde su directorio de nivel superior hasta el actual. Una vez que tenga eso, simplemente haga una elección sobre cómo almacenar archivos usando shelve según su directorio (considerando que todas las claves en Shelve deben ser cadenas).

  • Parece que estaba pensando en representar el sistema de archivos como una serie de diccionarios anidados, una buena opción. Pero tenga en cuenta que si cambia los objetos mutables en shelve, tiene que a) establecer la reescritura en True yb) llamar a fs.sync() para configurarlos.

  • Debe estructurar todo su sistema de archivos en una clase en lugar de en una serie de funciones. Le ayudará a mantener sus datos compartidos organizados. El siguiente código no sigue eso, pero vale la pena pensar.

Por lo tanto, me fijo hasta cd y también escribió un comando mkdir rudimentaria para usted. Lo crítico para hacer que funcionen es, como dije antes, tener current_dir una lista que muestre tu ruta actual, y también para tener una manera fácil (la función current_dictionary) para ir desde esa lista al directorio apropiado del sistema de archivos.

Con esto, aquí está el código para empezar:

import shelve 

fs = shelve.open('filesystem.fs', writeback=True) 
current_dir = [] 

def install(fs): 
    # create root and others 
    username = raw_input('What do you want your username to be? ') 

    fs[""] = {"System": {}, "Users": {username: {}}} 

def current_dictionary(): 
    """Return a dictionary representing the files in the current directory""" 
    d = fs[""] 
    for key in current_dir: 
     d = d[key] 
    return d 

def ls(args): 
    print 'Contents of directory', "/" + "/".join(current_dir) + ':' 
    for i in current_dictionary(): 
     print i 

def cd(args): 
    if len(args) != 1: 
     print "Usage: cd <directory>" 
     return 

    if args[0] == "..": 
     if len(current_dir) == 0: 
      print "Cannot go above root" 
     else: 
      current_dir.pop() 
    elif args[0] not in current_dictionary(): 
     print "Directory " + args[0] + " not found" 
    else: 
     current_dir.append(args[0]) 


def mkdir(args): 
    if len(args) != 1: 
     print "Usage: mkdir <directory>" 
     return 
    # create an empty directory there and sync back to shelve dictionary! 
    d = current_dictionary()[args[0]] = {} 
    fs.sync() 

COMMANDS = {'ls' : ls, 'cd': cd, 'mkdir': mkdir} 

install(fs) 

while True: 
    raw = raw_input('> ') 
    cmd = raw.split()[0] 
    if cmd in COMMANDS: 
     COMMANDS[cmd](raw.split()[1:]) 

#Use break instead of exit, so you will get to this point. 
raw_input('Press the Enter key to shutdown...') 

Y aquí es una demostración:

What do you want your username to be? David 
> ls 
Contents of directory /: 
System 
Users 
> cd Users 
> ls 
Contents of directory /Users: 
David 
> cd David 
> ls 
Contents of directory /Users/David: 
> cd .. 
> ls 
Contents of directory /Users: 
David 
> cd .. 
> mkdir Other 
> ls 
Contents of directory /: 
System 
Users 
Other 
> cd Other 
> ls 
Contents of directory /Other: 
> mkdir WithinOther 
> ls 
Contents of directory /Other: 
WithinOther 

Es importante tener en cuenta que esto es hasta ahora sólo un juguete: existe Todavía queda una tonelada por hacer. Aquí hay algunos ejemplos:

  • En este momento solo existe un directorio: no hay archivos comunes.

  • no comprueba si un directorio ya existe, sobrescribiría uno con un directorio vacío.

  • No se puede ls con un directorio específico como argumento, (como ls Users), solo su directorio actual.

Aún así, esto debería mostrar un ejemplo de un diseño para realizar un seguimiento de su directorio actual. ¡Buena suerte!

+1

Tiene un pequeño error en la línea 35. Debe ser 'print' Directorio/"+ '/' .join(current_dir) +" no encontrado "'. En este momento es agregar cadena y lista – jdi

+0

Whoops. En realidad, se suponía que era args [0] que no se encontró (que es, por supuesto, una cadena. Gracias –

+1

Buen trabajo. En realidad, estaba trabajando en esto al mismo tiempo y casi con el mismo enfoque :-) Aunque Solo estaba haciendo que el comando 'cd' creara el directorio vacío sobre la marcha. Pero una buena llamada sobre el atributo writeback – jdi

Cuestiones relacionadas