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);