2017-01-30 25 views
-1

我正在實現一個使用Python的Shell,而且我有一個小錯誤,那是幾個小時,我正在嘗試修復,但無法弄清楚問題。在我的noob python代碼中找不到命令「cat」的bug

當我運行我的程序時,我開始用「cat」命令輸入一行,一切正常,直到我在stdout和文件名之間放置一個空格。

例如:

1)cat <test >toto奔跑完美,現在TOTO具有裏面有什麼測試。

2)cat <test>toto完美運行,現在toto有什麼裏面的測試。

3)cat <test> toto奔跑完美,現在TOTO具有裏面有什麼考驗,但我得到的終端以下行(貓:TOTO:輸入文件輸出文件)

4)cat <test > toto不工作,我得到相同的行(cat:toto ....)

當我在「>」和文件名之間放一個空格時,爲什麼它會一直說輸入文件與輸出文件相同? ! 這裏是我的代碼

#!/usr/bin/python3 

import os 
import sys 
from shutil import copyfile 
def main(): 
    while True: 
     sys.stdout.write("%% ") 
     line = input() 
     line2 = line[0:len(line)] 
     line = "" 
     dirs = os.listdir() 
     d = "" 
     for j in range(0, len(dirs)): 
      d += dirs[j] + " " 
     for i in range(0, len(line2)): 
      if line2[i] == "*": 
       line += d 
      else: 
       line += line2[i] 
     args=list(filter(None,line.split(" "))) 
     list_arg=[] 
     src="" 
     dst="" 
     sr_c=0 
     ds_t=0 
     cmd=args[0] 
     for temp in args: 
      if temp=="<": 
       sr_c=1 
       src=args[args.index("<")+1]    
      elif temp[0]=="<": 
       sr_c=1 
       src+=temp[1:] 
      elif temp==">": 
       ds_t=1 
       dst=args[args.index(">")+1] 
      elif temp[0]==">": 
       ds_t=1 
       dst+=temp[1:] 
      else: 
       list_arg+=[temp] 
     if ds_t: 
      output=os.open(dst,os.O_CREAT |os.O_WRONLY |os.O_TRUNC) 
     else: output=1 

     if sr_c: 
      inputt=os.open(src,os.O_RDONLY) 
     else: inputt=0 

     pid = os.fork() 
     if pid == 0: 
      os.dup2(inputt,0) 
      os.dup2(output,1) 
      os.execvp(cmd,list_arg) 
     else: 
      os.waitpid(pid,0)  
    sys.stdout.write("Bye!\n") 
    sys.exit(0) 

     main() 
+0

我建議你瞭解他是德比自己的代碼。將打印語句添加到您的代碼中以瞭解它在做什麼。或者使用調試器。 –

+0

我在任何地方都使用過打印,仍然無法找到問題所在。 通過引用list_arg來看看裏面還有什麼 – Zok

+0

使用更多的'print()'並打印你在所有變量中的含義,以及代碼的哪個部分被執行。或者學習如何使用調試器:) – furas

回答

1

cat <test> toto問題是你不刪除testtoto所以你得到['cat', 'test', 'toto']和分配testtotostdinstdout所以最後系統將此視爲cat test toto <test >toto讓你從讀toto和寫入toto

您可以使用data = iter(args)創建iterator,您可以用for temp in data像以前一樣使用,但你可以人所以用next(data)從數據獲取下一個元素和for將跳過這個元素 - 所以它沒有這個元素添加到list_arg

import os 
import sys 
from shutil import copyfile 

def main(): 
    while True: 
     sys.stdout.write("%% ") 
     line = input() 

     dirs = os.listdir() 
     d = " ".join(dirs) 

     print('[DEBUG] d:', d) 

     new_line = "" 

     for char in line: 
      if char == "*": 
       new_line += d 
      else: 
       new_line += char 

     args = list(filter(None, new_line.split(" "))) 

     list_arg = [] 

     src = None 
     dst = None 

     cmd = args[0] 

     data = iter(args) 

     for temp in data: 
      if temp == "<": 
       src = next(data) 
      elif temp[0] == "<": 
       src = temp[1:] 
      elif temp == ">": 
       dst = next(data) 
      elif temp[0] == ">": 
       dst = temp[1:] 
      else: 
       list_arg.append(temp) 

     if dst: 
      output = os.open(dst, os.O_CREAT |os.O_WRONLY |os.O_TRUNC) 
     else: 
      output = 0 

     if src: 
      input_ = os.open(src, os.O_RDONLY) 
     else: 
      input_ = 1 

     print('[DEBUG] src:', src) 
     print('[DEBUG] dst:', dst) 
     print('[DEBUG] arg:', list_arg) 

     pid = os.fork() 

     if pid == 0: 
      os.dup2(input_, 0) 
      os.dup2(output, 1) 
      os.execvp(cmd, list_arg) 
     else: 
      os.waitpid(pid, 0) 

    sys.stdout.write("Bye!\n") 
    sys.exit(0) 

main() 
+0

您的代碼不工作,請嘗試使用狀回聲任何命令*或貓測試 list_arg將有類似[「O」] 甚至回聲*將有一個字符串[我的資料庫中的所有文件] .. – Zok

+0

你在'範圍內的'(0,len(dirs))中執行相同的操作:d + = dirs [j] +「」' - 它創建包含目錄中所有文件的字符串。所以程序中的'echo *'也一樣。用'print('[DEBUG]'')去除行,你在我的程序中得到完全相同的結果。 – furas

+0

好吧,我看到:)謝謝你的幫助,我現在知道如何在Python中使用迭代器。原諒我上面的第一個代碼,對我來說,Python已經有2天了。 – Zok