实现一个linux命令,简单linux命令

【Linux】实现一个简单的shell命令解释器

姓名:罗学元       学号:21181214375     学院:广州研究院

成都创新互联公司主要从事做网站、成都网站制作、网页设计、企业做网站、公司建网站等业务。立足成都服务双牌,10余年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:13518219792

【嵌牛导读】shell命令解释器该包含哪些部分

【嵌牛鼻子】shell命令解释器该包含哪些部分

【嵌牛提问】shell命令解释器该包含哪些部分

我们所做的这个简单的shell命令解释器可以实现简单的常用的基本命令,如ls、pwd、cd、cd - 、cd ~ 等

根据简单命令的定义,它的第一个参数是要执行的命令,后面的参数作为该命令的参数。

要执行的命令有两种情况:

一种是外部命令: 也就是对应着磁盘上的某个程序,例如 pwd、ls等等。对于这种外部命令,我们首先要到指定的路径下找到它,然后再执行它。

另一种是内部命令:内部命令并不对应磁盘上的程序,例如cd等等,它需要shell自己来决定该如何执行。例如对 cd 命令,shell就应该根据它后面的参数改变当前路径。

对于外部命令,需要创建一个子进程来执行它,本质就是fork+exec

#include stdio.h

#include stdlib.h

#include assert.h

#include string.h

#include pwd.h

#include sys/utsname.h

#include sys/types.h

#include unistd.h

#define MAX 10

#define STRLEN 128

#define PATH "/bin/" //系统bin路径位置

char OLDPWD[STRLEN]={0}; //记录上一次的命令,为了cd -这条命令

//================================================================================

//每次敲回车输出当前所在用户信息

//普通用户和root用户的提示符区别

void Printf_Info()

{

char flag='$';

struct passwd *pw=getpwuid(getuid());

assert(pw!=NULL);

//uid为0则为root用户

if(pw-pw_uid==0)

{

flag='#';

}

struct utsname hostname; //主机名

uname(hostname);

char node[STRLEN]={0};

strcpy(node,hostname.nodename); //获取网络上的名称

char* name=strtok(node,".");

//获取绝对路径

char path[STRLEN]={0};

getcwd(path,STRLEN-1);

char*p=path+strlen(path); //p指向绝对路径的末尾

while(*p!='/')

{

p--;

}

//p指向路径末尾往前的第一个‘/’位置处

if(strlen(path)!=1)

{

p++; //++前,p-'/'

}

if(strcmp(path,pw-pw_dir)==0)

{

p="~";

}

printf("\033[;32mMyBash[%s@%s %s]%c\033[0m",pw-pw_name,name,p,flag);

//  \033[47;31mThis is a color test\033[0m  设置打印结果的颜色

fflush(stdout);

}

//================================================================================

void Mycd(char*path)

{

//第一个字符串为cd而第二为空 如:cd 则结束本轮循环

if(path==NULL)

{

exit(0);

}

//cd ~ 回到用户根目录

if(strcmp(path,"~")==0)

{

    struct passwd*pw=getpwuid(getuid());

    path=pw-pw_dir;

}

//cd - 回到上一次的位置

if(strcmp(path,"-")==0) 

{

  //若是第一次输入命令,则cd -命令不存在!

    if(strlen(OLDPWD)==0)

    {

        printf("\033[;31mMyBash:cd:OLDPWD not set\n\033[0m");

        return ;

    }

    //否则把上一次的命令给path

    path=OLDPWD;

}

//getpwd记录当前工作目录的绝对路径

char oldpwd[STRLEN]={0};

getcwd(oldpwd,STRLEN-1);

if(-1==chdir(path))//反之则不是空,则通过chdir系统调用进入到该目录中

{

    char err[128]="\033[;31mMybash: cd \033[0m";

    strcat(err,path);

    perror(err);

}

//每次执行完cd命令后,把工作路径赋给OLDPWD

strcpy(OLDPWD,oldpwd);

}

//================================================================================

//命令分割函数

void Strtok_cmd(char*buff,char*myargv[])

{

char *s=strtok(buff," "); //分割输入的字符串

if(s==NULL) //如果s为空,则进入下一轮循环

{

exit(0);

}

myargv[0]=s; //把分割出来的第一个字符串放在myargv[0]中

int i=1;

while((s=strtok(NULL,""))!=NULL) //把后续分割出来的字符串依次存放在数组中

{

myargv[i++]=s;

}

}

//===============================================================

int main()

{

while(1)

{

char buff[128]={0};

Printf_Info();

//从终端获取命令存入buff中

fgets(buff,128,stdin);

buff[strlen(buff)-1]=0;

char *myargv[MAX]={0};

//分割输入的命令

Strtok_cmd(buff,myargv);

//如果输入exit则退出循环

if(strcmp(myargv[0],"exit")==0)

{

exit(0);

}

//如果分割出来的第一个字符串为cd

else if(strcmp(myargv[0],"cd")==0)

{

Mycd(myargv[1]);

continue;

}

//若是系统调用,直接替换fork+exec

pid_t pid=fork();

assert(pid!=-1);

if(pid==0)

{

char path[256]={0};

if(strncmp(myargv[0],"./",2)!=0 strncmp(myargv[0],"/",1)!=0)

{

//先把路径放入path中

strcpy(path,PATH);

}

//进行命令拼接,路径+名称

strcat(path,myargv[0]);

//替换进程 例如:/bin/ls

execv(path,myargv);

perror("\033[;31mexecv error\033[0m");

}

//处理僵死进程

else

{

wait(NULL);

}

}

}

运行结果如下 :

异常处理如下:

若是第一次运行程序,则不能使用cd - 命令,因为此时还没有历史路径

若进入一个不存在的目录则会报错,没有这个文件或目录

若直接输入一个不存在的无法识别的命令,也会报错。

Linux命令大全

linux命令格式:

说明:command: 命令名,相应功能的英文单词或单词的缩写 [-options]:选项,可用来对命令进行控制,也可以省略,[]代表可选 parameter1 …:传给命令的参数:可以是零个一个或多个

一般是linux命令自带的帮助信息

如:

man是linux提供的一个手册,包含了绝大部分的命令、函数使用说明

该手册分成很多章节(section),使用man时可以指定不同的章节来浏览。

例:man ls ; man 2 printf

man中各个section意义如下:

man是按照手册的章节号的顺序进行搜索的。

man设置了如下的功能键:

在敲出命令的前几个字母的同时,按下tab键,系统会自动帮我们补全命令

当系统执行过一些命令后,可按上下键翻看以前的命令,history将执行过的命令列举出来

ls是英文单词list的简写,其功能为列出目录的内容,是用户最常用的命令之一,它类似于DOS下的dir命令。

Linux文件或者目录名称最长可以有265个字符,“.”代表当前目录,“..”代表上一级目录,以“.”开头的文件为隐藏文件,需要用 -a 参数才能显示。

ls常用参数:

Linux允许将命令执行结果重定向到一个文件,本应显示在终端上的内容保存到指定文件中。

如:ls test.txt ( test.txt 如果不存在,则创建,存在则覆盖其内容 )

注意: 输出重定向会覆盖原来的内容,输出重定向则会追加到文件的尾部。

查看内容时,在信息过长无法在一屏上显示时,会出现快速滚屏,使得用户无法看清文件的内容,此时可以使用more命令,每次只显示一页,按下空格键可以显示下一页,按下q键退出显示,按下h键可以获取帮助。

管道:一个命令的输出可以通过管道做为另一个命令的输入。

管道我们可以理解现实生活中的管子,管子的一头塞东西进去,另一头取出来,这里“ | ”的左右分为两端,左端塞东西(写),右端取东西(读)。

clear作用为清除终端上的显示(类似于DOS的cls清屏功能),也可使用快捷键:Ctrl + l ( “l” 为字母 )。

在使用Unix/Linux的时候,经常需要更换工作目录。cd命令可以帮助用户切换工作目录。Linux所有的目录和文件名大小写敏感

cd后面可跟绝对路径,也可以跟相对路径。如果省略目录,则默认切换到当前用户的主目录。

使用pwd命令可以显示当前的工作目录,该命令很简单,直接输入pwd即可,后面不带参数。

通过mkdir命令可以创建一个新的目录。参数-p可递归创建目录。

需要注意的是新建目录的名称不能与当前目录中已有的目录或文件同名,并且目录创建者必须对当前目录具有写权限。

可使用rmdir命令删除一个目录。必须离开目录,并且目录必须为空目录,不然提示删除失败。

可通过rm删除文件或目录。使用rm命令要小心,因为文件删除后不能恢复。为了防止文件误删,可以在rm后使用-i参数以逐个确认要删除的文件。

常用参数及含义如下表所示:

Linux链接文件类似于Windows下的快捷方式。

链接文件分为软链接和硬链接。

软链接:软链接不占用磁盘空间,源文件删除则软链接失效。

硬链接:硬链接只能链接普通文件,不能链接目录。

使用格式:

如果没有-s选项代表建立一个硬链接文件,两个文件占用相同大小的硬盘空间,即使删除了源文件,链接文件还是存在,所以-s选项是更常见的形式。

注意:如果软链接文件和源文件不在同一个目录,源文件要使用绝对路径,不能使用相对路径。

Linux系统中grep命令是一种强大的文本搜索工具,grep允许对文本文件进行模式查找。如果找到匹配模式, grep打印包含模式的所有行。

grep一般格式为:

在grep命令中输入字符串参数时,最好引号或双引号括起来。例如:grep‘a ’1.txt。

常用选项说明:

find命令功能非常强大,通常用来在特定的目录下搜索符合条件的文件,也可以用来搜索特定用户属主的文件。

常用用法:

cp命令的功能是将给出的文件或目录复制到另一个文件或目录中,相当于DOS下的copy命令。

常用选项说明:

用户可以使用mv命令来移动文件或目录,也可以给文件或目录重命名。

常用选项说明:

计算机中的数据经常需要备份,tar是Unix/Linux中最常用的备份工具,此命令可以把一系列文件归档到一个大文件中,也可以把档案文件解开以恢复数据。

tar使用格式 tar [参数] 打包文件名 文件

tar命令很特殊,其参数前面可以使用“-”,也可以不使用。

常用参数:

tar与gzip命令结合使用实现文件打包、压缩。 tar只负责打包文件,但不压缩,用gzip压缩tar打包后的文件,其扩展名一般用xxxx.tar.gz。

gzip使用格式如下:

gzip [选项] 被压缩文件

常用选项:

tar与bzip2命令结合使用实现文件打包、压缩(用法和gzip一样)。

tar只负责打包文件,但不压缩,用bzip2压缩tar打包后的文件,其扩展名一般用xxxx.tar.gz2。

在tar命令中增加一个选项(-j)可以调用bzip2实现了一个压缩的功能,实行一个先打包后压缩的过程。

压缩用法:tar -jcvf 压缩包包名 文件...(tar jcvf bk.tar.bz2 *.c)

解压用法:tar -jxvf 压缩包包名 (tar jxvf bk.tar.bz2)

通过zip压缩文件的目标文件不需要指定扩展名,默认扩展名为zip。

压缩文件:zip [-r] 目标文件(没有扩展名) 源文件

解压文件:unzip -d 解压后目录文件 压缩文件

whoami该命令用户查看当前系统当前账号的用户名。可通过cat /etc/passwd查看系统用户信息。

由于系统管理员通常需要使用多种身份登录系统,例如通常使用普通用户登录系统,然后再以su命令切换到root身份对传统进行管理。这时候就可以使用whoami来查看当前用户的身份。

who命令用于查看当前所有登录系统的用户信息。

常用选项:

如果是图形界面,退出当前终端;

如果是使用ssh远程登录,退出登陆账户;

如果是切换后的登陆用户,退出则返回上一个登陆账号。

在Unix/Linux中添加用户账号可以使用adduser或useradd命令,因为adduser命令是指向useradd命令的一个链接,因此,这两个命令的使用格式完全一样。

useradd命令的使用格式如下:

useradd [参数] 新建用户账号

在Unix/Linux中,超级用户可以使用passwd命令为普通用户设置或修改用户口令。用户也可以直接使用该命令来修改自己的口令,而无需在命令后面使用用户名。

可以通过su命令切换用户,su后面可以加“-”。su和su –命令不同之处在于,su -切换到对应的用户时会将当前的工作目录自动转换到切换后的用户主目录:

注意:如果是ubuntu平台,需要在命令前加“sudo”,如果在某些操作需要管理员才能操作,ubuntu无需切换到root用户即可操作,只需加“sudo”即可。sudo是ubuntu平台下允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,减少了root 用户的登陆和管理时间,提高了安全性。

方法一:

方法二:

groupadd 新建组账号 groupdel 组账号 cat /etc/group 查看用户组

使用方法:usermod -g 用户组 用户名

新创建的用户,默认不能sudo,需要进行一下操作

-g用来制定这个用户默认的用户组

-G一般配合'-a'来完成向其它组添加

chmod 修改文件权限有两种使用格式:字母法与数字法。

字母法:chmod u/g/o/a +/-/= rwx 文件

cal命令用于查看当前日历,-y显示整年日历

设置时间格式(需要管理员权限):

date [MMDDhhmm[[CC]YY][.ss]] +format

CC为年前两位yy为年的后两位,前两位的mm为月,后两位的mm为分钟,dd为天,hh为小时,ss为秒。如: date 010203042016.55。

显示时间格式(date '+%y,%m,%d,%H,%M,%S'):

进程是一个具有一定独立功能的程序,它是操作系统动态执行的基本单元。

ps命令可以查看进程的详细状况,常用选项(选项可以不加“-”)如下:

top命令用来动态显示运行中的进程。top命令能够在运行后,在指定的时间间隔更新显示信息。可以在使用top命令时加上-d 来指定显示信息更新的时间间隔。

在top命令执行后,可以按下按键得到对显示的结果进行排序:

kill命令指定进程号的进程,需要配合 ps 使用。有些进程不能直接杀死,这时候我们需要加一个参数“ -9 ”,“ -9 ” 代表强制结束.

使用格式:

kill [-signal] pid

df命令用于检测文件系统的磁盘空间占用和空余情况,可以显示所有文件系统对节点和磁盘块的使用情况。

du命令用于统计目录或文件所占磁盘空间的大小,该命令的执行结果与df类似,du更侧重于磁盘的使用状况。

du命令的使用格式如下: du [选项] 目录或文件名

Linux实用命令有哪些?

1选择

1.1一个文件的名字为rr.Z,可以用来解压缩的命令时()

tar

gzip

compress

uncompress

1.2可以结束进程命令()

kill

ctrl+c

shutdown

halt

1.3 Linux下对文件进行归档的命令为:(多选)

dd

tar

zip

unzip

1.4 Linux查当前目录下30天以前的文件并移动到/dev/null下的命令:(多选)

find.-mtime 30-type f xargs mv{}/dev/null;

find.-mtime+30-type xargs mv{}/dev/null;

find.-mtime+30-type f-exec mv{}/dev/null;

find.-mtime+30-type f-exec rm–rf{};

1.5 dstat与下面哪个命令类似

vmstat

sar

iotop

abc

1.6 rpm安装软件的参数

rpm-ivh

rpm-Ivh

rpm-Uvh

rpm-Iuvh

1.7 yum升级软件包选项

rpm-uvh

rpm-Uvh

1.8查看网络流量命令是?

iftop

nsload

ifstatd

以上命令全可以

1.9停止进程的命令,除了kill还有谁?

pkill

killa

allkill

以上命令都不正确

1.10服务器之间传文件的命令有?

wget

scp

ftp

以上命令都可以

1.11对文件进行归档的命令为

dd

cpio

gzip

tar

1.12在rpm命令中,安装新的rpm包软件使用的参数是()

-i

-v

-h

-e

1.13du命令中,使用友好的方式显示信息的参数是()

-h

-f

-a

-t

1.14将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现如此任务的tar命令格式___

tar zxvf/home/stud1/wang.tar.gz/home/wang

tar xcvf/home/stud1/wang/home/wang

tar zcv/home/stud1/wang/home/wang

tar zcvf/home/stud1/wang/home/wang.tar.gz

1.15终止一个前台进程可能用到的命令和操作()A:kill

B:CTRL+C

C:shutdown

D:halt

1.16关闭Linux系统(不重新启动)可使用命令()

A:Ctrl+Alt+Del

B:halt

C:shutdown-r now

D:reboot

1.17下列提法中,不属于ifconfig命令作用范围的是__

A:配置本地环回地址

B:配置网卡的IP地址

C:激活网络适配器

D:加载网卡到内核中

1.18有关归档和压缩命令,下面描述正确的是()

A:用uncompress命令解压缩由compress命令生成地后缀为.zip的压缩文件

B:upzip命令和gzip命令可以解压相同类型文件

C:tar归档其压缩的文件可以有gzip命令解压缩

D:tar命令归档后的文件也是一种压缩文件

1.19终止一共前台进程可能用到的命令和操作

kill

ctrl+c

shut down

halt

1.22为了将当前目录下的归档文档myftp,tar解压缩到/tmp目录下,用户可以使用命令

tar xvzf my

tar xvzf my

tar vzf my

tar xvzf my

1.23下面有关linux查看系统负载的命令,说法错误的是?

uptime命令主要用于获取主机运行时间和查询linux系统负载等信息

vmstat命令可以查看cpu负载

sar命令可以查看网络接口信息

free命令可以查看磁盘负载情况

1.24以下哪些方式/命令不可以查看某ip是否可达?

telnet

ping

tracert

top

1.25 tar命令用于解压的参数是?-v-x-c-f

1.26下面哪个命令不是用来查看网络故障?

telnet

ping

init

netstat

1.28为了知道谁在正注册到你的机器上,可以用命令:___

Who users finger ping

1.29查看本网段其他计算机的MAC地址,可先ping对方主机,然后;

arp-g

arp-n

arp-a

arp-d

1.3014日下午2点date+%y%m%d%H%M输出的时间是什么

201711141212

1711141212

2017111412

201711021212

1.31以下哪个命令可以得出1487进程的线程运行情况()

top-Hp 1487

top-Pp 1487

ps-mp 1487

sat-p 1487

1.32从/home/oracle下搜索一个日志文件alert.log,以下哪种方式可达到目的()

find/home./oracle-name alert.log

locate alert.log

find./-mtime 7 alert.log

find/home/oracle-exec alert.log

1.34以下哪些命令可以用来测试网络中特定主机的80端口是否可以访问()

Ping telnet netstat lsof

2填空

2.1测试网络中主机的连通性用什么命令

2.2如何查看numa是否关闭_**_

2.3将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现如此任务的tar命令格式_**

2.4某个进程使用端口7001,如何快速找到该进程的PID

2.5结束后台进程的命令是**_**

2.6将/home/studl/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此存到/home目录下,实现此任务的tar命令格式******__******

2.7 ping100个包的命令——

2.8 linux下,解压缩bz2格式文件的命令是**_**

2.9 linux下,查看网络连接状态的命令是**___**

2.10Linux查看文件系统的命令为__,显示目录或文件占用磁盘的命令为___

2.11通常我们测试网络连通性使用的ping命令,它是通过____协议进行工作的

2.12简述下列命令的各自作用

nslookup

dig

top

traceroute

2.13将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此问价保存到/home目录下,实现此任务的tar命令格****_****

2.14Linux系统查看进程数的命令___

2.15Linux系统查看系统内存的命令:____,**__**

2.16Linux系统查看cpu使用率的命令:____,**__**

2.17Linux系统查看硬盘空间使用率的命令:___

2.18Linux系统将某一文件下的所有.log文件进行打包压缩,命令为___

2.19Linux常用的性能监控命令是:_、_、_、_、_、_等

2.20假设output程序可能输出标准输出和标准错误,请写出一条命令把这两者都忽略__

2.21 rpm软件包安装命令**_**

3简答

3.1查看硬盘结构显示的命令?查看文档命令?编辑文档命令?

3.2配置网络环境的命令,手工修改IP,主机名,DNS和网关

3.3有压缩包a.tar.gz,如何解压该包?如何不解压该包,如何查看该包的内容?

3.4某进程abcd在系统中起了很多,数量难以统计,造成系统负荷较高,如何一条命令确保将此进程全部杀掉

3.5某日志路径是/data/logs/a.txt,如何跟踪该日志,以查看当时的运行状态?

3.6 dmesg命令显示的是哪方面信息

3.7寻找名称为mytest.log的文件

3.8写出du-sh与df-h的区别

3.9查看当前linux服务器是否监听80端口,如果监听,请找出其进程ID,并结束该进程。

3.10使用curl或者wget获取http服务的header信息。

3.11写出查看linux系统性能的命令,如cpu、内存、流量、io等

3.12解释下列命令的意思

dd if=/dev/random of=/dev/sda

3.13如何查看占用端口8080的进程

3.14查着占用内存最多的进程

3.15压缩和解压缩目录/opt/gjsy/所有文件命令

3.16Linxu系统下如何查看8080端口上运行的程序状态

3.17ps aux中的VSZ代表什么意思,RSS代表什么意思?

3.18PING是使用TCP/IP协议中的**_**协议

3.19写出网络故障排查常用的命令**__**

3.20写出你常用的网络抓包工具,软件名称**__**

3.21将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现此任务的tar命令格式___

3.22解释该命令的含义:nohup zcat test.gz|grep"x6game"~/log.txt

2/dev/null

3.23查看系统硬件负载工具或命令有哪些

3.24使用lsof命令查看占用80端口的进程

3.25如何使用CURL测试POST接口

3.26怎样在目录/home/user/training/下找到扩展名为txt的文件

3.27最常用的网络测试命令有什么?

3.28ping的测试结果中都包含哪些部分?

3.29如何找出占用22端口的进程及进程号?

3.30如何删除当前目录(包含字目录)下所有30天以前创建的文件名后缀为.log的文件

3.31以下一些Linux命令的作用分别是什么?

init 0

chkconfig--level 3 sendmail on

tar-czvf test.tar.gz./

chown-R

ln-s/data/log//var/log/sina_log

umount-f/data0

rpm-ivh baihui.rpm

rpm-qf/bin/ls

3.32LINUX常用命令pwd、top、df、ifconfig、cat分别代表什么含义?

3.33linux常用命令:关机、重启、编辑某文档文件、删除某文件、更改操作系统密码命令分别是什么?

3.34请使用命令:删除/backup目录下10天前的普通文件

3.35如何查看服务器当前连接ip的列表

3.36写出liunx系统中diff、chmod、grep、kill、tar五个常用命令的功能

3.37简述tar-cjvf/tmp/test.tar.gz/root命令中错误及错误原因

3.38Linux系统从A服务器测试B服务器一个tcp端口是否联通使用___

3.39写一个脚本查找最后创建时间使3天前,后缀是*.log的文件并删除

3.40linux如何根据进程ID查找启动程序的路径

3.41查看占用swap的进程id

3.42列出linux常见打包工具并写相应解压缩参数(至少三种)

3.43Linux中锁定一个文件用什么命令?他和md5sum有什么区别?

3.44如何在系统中查找所有所属用户为user1的文件

3.45查看某个文件或者文件夹占用磁盘空间大小的命令

3.46如何查看远程linux系统运行了多少时间?我的服务器内存,cpu,硬盘都是多少,系统版本,linux会优先将数据缓存到内存中,我的机器真实内存消耗实际上是多少

3.47查看服务器当前开启了哪些端口?如何查看某服务器是否存在IO压力

3.48如何查看某个文件system.log被哪些进程占用

扩展

1.21在退出unix系统账户之后还需要继续运行某个进程,那么可用()

awk sed crontab nohup screen

1.20使用trace命令的目的是()

可用的,十分成功的测试手段

非常基本的测试手段

把IP地址和DNS加入路由表中

在源到目标传输的过程中查找失散点

1.27哪个变量用来指定一个远程x应用程序将输出放到哪个x server上

TERM

DISPLAY

ECHO

OUTPUT

1.33P系列服务器被用做文件服务器,所有的用户文件存都放在一非rootvg的文件系统上,用什么方法可以快速备份和恢复这些数据和文件系统的定义()

tar

cpio

savefs

savevg


文章标题:实现一个linux命令,简单linux命令
本文来源:http://abwzjs.com/article/hodiic.html