實驗報告:Project2:Creating a Shell Interface

Project2:

Creating a Shell Interface

 

一、實驗環境

Ubuntu  10.04系統

Eclipse開發平臺

 

二、實驗過程:

1、新建java project,編寫代碼
程序大體思路:

1、程序初始化:初始化數組commandHistory以存儲歷史命令、MyPath存放當前路徑、commandLine存放讀入的命令,以及其他變量

2、做while主循環,不停讀入用戶輸入的命令

3、對命令進行判斷、操作

3.1  如果命令是以“!”開頭,判斷後面的數據未超範圍後,讀取歷史命令:把歷史命令賦值給commandLine。之後進行其他命令的判斷,就可以在一個循環中完成讀取歷史名利的操作。

3.2  以“ ”(空格)分隔命令,存入lineSplit中。

3.3  如果是退出命令,調用System.exit(0)退出。

3.4  如果首個命令是cd命令:根據後邊參數是否以“/”開頭分爲絕對路徑、相對路徑兩部分。

絕對路徑:以“/”分隔路徑,存入currentSplit中。之後逐層對路徑進行判斷,currentPath存放當前判斷路徑:新建ls命令的進程,並使進程路徑爲currentPath,以其輸出與下一級路徑比對,無誤進行下次判斷,否則提示錯誤,開始下次主循環。路徑全對後,對MyPath修改,cd命令執行完畢。

相對路徑:與絕對路徑大體相似,但currentPath初值爲當前路徑,最後對MyPath賦值是在原來MyPath基礎上改變。

3.5  其餘命令,新建輸入命令的進程,設置進程路徑爲MyPath後執行,輸出進程輸出。

 

2、運行並測試

此程序可實現較簡單的shell功能:1、基本命令:如ls、pwd等等;2、工作路徑的變換:cd命令;3、記錄命令歷史,並可通過“!!”“!*”調用。

此shell中存在很多bug,尤其是在!操作、cd操作中,已經添加代碼如測試cd命令路徑等改正一些問題,但還並不完善。

 

3、在實驗中遇到的一些問題

在對修改路徑cd命令處理時,想用System.setProperty()函數對程序的路徑進行直接修改,發現始終無法達到效果。網上查詢後,得知這個路徑是寫保護的,無法通過此方法修改。之後想到解決辦法:cd命令先把路徑記錄在MyPath中,在之後的命令新建進程時,通過調用

public     ProsessBuilder      director(File       director)函數對進程路徑修改後,開啓進程即可。

 

在cd命令對路徑的判斷上,我也下了較大力氣。首先想到新建“ls”進程進行以此判斷,然後發現cd可以有相對路徑、絕對路徑兩種輸入,又進行了判斷。後來又想到多個路徑連在一起的輸入,又通過“/”分隔,加入for循環逐層對路徑進行判斷,某層路徑錯誤後就報錯,停止下層判斷。現在本程序支持絕對、相對路徑輸入,並支持“/home/rongry/experiment/”類型了輸入,但有時候會出現錯誤。

 

三、實驗總結

在這個實驗中,我首次接觸了java語言,遇到了不上語言上的麻煩錯誤。最後通過網絡查詢、查看java幫助文檔、老師所給材料還是一一解決了。

這次實驗,在“cd”命令等問題上上下了不少功夫。通過這個實驗加深了我對process、shell等內容的理解,也讓我學習了一下java語言的內容。

 

 

附:原代碼如下:

import java.io.BufferedReader;

import java.io.File;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.ArrayList;

 

public class SimpleShell

{

 public static void main(String[] args) throws java.io.IOException {

        

//存放讀入的命令

  String commandLine;

  BufferedReader console = new BufferedReader(new InputStreamReader(System.in));

//當前路徑,賦值爲起始路徑

  String MyPath=System.getProperty("user.dir");

//存放歷史命令

  ArrayList<String> commandHistory=new ArrayList<String>();

//表示讀取歷史命令時,讀取之前第tem的命令

  int tem=0;

      

//主循環

while (true) {

  //讀入命令

  System.out.print("jsh>");

  commandLine = console.readLine();

  commandHistory.add(commandLine);

 

//沒有命令輸入,開始下一次循環

  if (commandLine.equalsIgnoreCase("")) {

         commandHistory.remove(commandHistory.size()-1);

              continue;

  }

//輸入命令以“!”開始,進行讀取歷史命令的操作

  if(commandLine.charAt(0)=='!'){

         commandHistory.remove(commandHistory.size()-1);

         tem=0;

         //輸入的“!!”,設置tem=1

         if(commandLine.length()==2&&commandLine.charAt(1)=='!'){

                tem=1;

         }

             //輸入爲“!*”,根據*值設施tem值

         else {

                for(int i=1;i<commandLine.length();i++){

                       tem=tem*10+commandLine.charAt(i)-48;

                }

         }

//判斷是否超範圍

if(tem>commandHistory.size()){

      

       System.out.print(tem);System.out.print("error:event not found! \n");

       System.out.print(commandHistory.size());

       continue;

}

//未超範圍,讀取歷史命令賦給commandLine,繼續之後操作

else{

  String exCommand=commandHistory.get(commandHistory.size()-tem);

       System.out.print(exCommand+"\n");

       commandLine=exCommand;

                }

}

 

//分割所得命令

ArrayList<String> parms = new ArrayList<String>();

String[] lineSplit = commandLine.split(" ");

int size = lineSplit.length;

for (int i=0; i<size; i++)    {

  parms.add(lineSplit[i]);

}

 

//退出命令

if(lineSplit[0].equalsIgnoreCase("exit")||lineSplit[0].equalsIgnoreCase("quit"))  {

    System.out.println("Goodbye");

    commandHistory.clear();

    System.exit(0);

}

//“cd”命令

else if(lineSplit[0].equalsIgnoreCase("cd")){

 

//絕對路徑部分

if (lineSplit[1].charAt(0) == '/') {

 

//以“/”分割,逐層判斷路徑是否正確

String[] currentSplit = lineSplit[1].split("/");

 

String currentPath = "/";

boolean currentFlag=true;

 

//新建“ls”命令的進程,以其輸出爲標準進行判斷

for (int i = 1; i < currentSplit.length; i++) {                                        

    ProcessBuilder pb = new ProcessBuilder("ls");

     File filedir = new File(currentPath);

       pb.directory(filedir);

       Process proc = pb.start();

 

 

       InputStream is = proc.getInputStream();                                      

InputStreamReader isr = new InputStreamReader(is);                                          

BufferedReader br = new BufferedReader(isr);                                               

String line;                                       

boolean flag = false;

       while ((line = br.readLine()) != null) {

  if (currentSplit[i].equalsIgnoreCase(line)) {                                                     

  flag = true;                                                                                                

    break;

  }

       }

 

br.close();

//本層正確,進行下一層判斷,否則報錯,路徑不變

       if (flag) {

              currentPath=currentPath+ "/" +currentSplit[i];

              continue;

       } else {

              System.out.print("error:沒有那個文件或目錄!\n");

              currentFlag=false;

              break;

              }

 

}

//如果全部路徑無誤,更改MyPath                  

       if(currentFlag){

              MyPath = lineSplit[1];

           }

} else {

//相對路徑部分,與絕對路徑相似

       String[] currentSplit = lineSplit[1].split("/");

 

       String currentPath =MyPath;

       boolean currentFlag=true;

 

       for (int i = 0; i < currentSplit.length; i++) {

              ProcessBuilder pb = new ProcessBuilder("ls");

              File filedir = new File(currentPath);

              pb.directory(filedir);

              Process proc = pb.start();

 

                    InputStream is = proc.getInputStream();

              InputStreamReader isr = new InputStreamReader(is);

              BufferedReader br = new BufferedReader(isr);

                     // read what is returned by the command

              String line;

              boolean flag = false;

              while ((line = br.readLine()) != null) {

                     if (currentSplit[i].equalsIgnoreCase(line)) {

                            flag = true;

                            break;

                            }

                     }

 

              br.close();

              if (flag) {

                     currentPath=currentPath+ "/" + currentSplit[i];

                     continue;

                     } else {

                     System.out.print("error: 沒有那個文件或目錄!\n");

                     currentFlag=false;

                     break;

                    }

 

              }

              if(currentFlag){

                     MyPath = MyPath + "/" + lineSplit[1];

                     }

       }

 

  //其餘命令部分

  else{    

         //以此命令啓動進程

         ProcessBuilder pb = new ProcessBuilder(parms);

             //設置進程的路徑爲當前路徑

         File filedir=new File(MyPath);

         pb.directory(filedir);

         Process proc = pb.start();

 

          InputStream is = proc.getInputStream();

          InputStreamReader isr = new InputStreamReader(is);

          BufferedReader br = new BufferedReader(isr);

 

          // 輸出結果

          String line;

          while ( (line = br.readLine()) != null){

              System.out.println(line);

          }

 

          br.close(); 

  }

}

}

}


發佈了21 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章