linux命令行解释器 linux文件解释

【Linux】实现一个简单的shell命令解释器姓名linux命令行解释器:罗学元学号linux命令行解释器:21181214375学院:广州研究院
【嵌牛导读】shell命令解释器该包含哪些部分
【嵌牛鼻子】shell命令解释器该包含哪些部分
【嵌牛提问】shell命令解释器该包含哪些部分
我们所做linux命令行解释器的这个简单的shell命令解释器可以实现简单的常用的基本命令linux命令行解释器,如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}; //记录上一次的命令,为linux命令行解释器了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)!=0strncmp(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 - 命令,因为此时还没有历史路径
若进入一个不存在的目录则会报错,没有这个文件或目录
若直接输入一个不存在的无法识别的命令,也会报错 。
bash(shell)命令解释器,Linux界面介绍Linux bash命令行:bash命令行解释器或者翻译官,命令行输入命令都是由bash解释执行的 。
一、命令行
二、查询当前登录的用户:
root
三、查询当前用户主机名:
oldboy
四、查询当前用户所在的路径:
/root
五、切换用户:
#切换到oldboy用户
(#$是普通用户的提示符 。一般大臣,布衣 。)
oldboy
六、符号的意思
~用户家目录
-上一次所在的目录
.表示当前目录
..上一级目录
../..表示上一级的上一级目录
LINUX快速入门第八章:Shell基础 我们平时所说的 Shell 可以理解为 Linux 系统提供给用户的使用界面 。Shell 为用户提供了输入命令和参数并可得到命令执行结果的环境 。当一个用户登录 Linux 之后,系统初始化程序 init 就根据 /etc/passwd 文件中的设定 , 为每个用户运行一个被称为 Shell(外壳)的程序 。
确切地说 , Shell 是一个命令行解释器 , 它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至编写一些程序 。
Shell 处在内核与外层应用程序之间,起着协调用户与系统的一致性、在用户与系统之间进行交互的作用 。图 1 是 Linux 系统层次结构图 , Shell 接收用户输入的命令,并把用户的命令从类似 abed 的 ASCII 码解释为类似 0101 的机器语言 , 然后把命令提交到系统内核处理;当内核处理完毕之后 , 把处理结果再通过 Shell 返回给用户 。
换句话说:
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁 。Shell 既是一种命令语言,又是一种程序设计语言 。
Shell 是指一种应用程序 , 这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务 。
Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell 。
Shell 与其他 Linux 命令一样,都是实用程序,但它们之间还是有区别的 。一旦用户注册到系统后,Shell 就被系统装入内存并一直运行到用户退出系统为止;而一般命令仅当被调用时 , 才由系统装入内存执行 。
与一般命令相比,Shell 除了是一个命令行解释器,同时还是一门功能强大的编程语言,易编写 , 易调试,灵活性较强 。作为一种命令级语言 , Shell 是解释性的,组合功能很强,与操作系统有密切的关系 , 可以在 Shell 脚本中直接使用系统命令 。大多数 Linux 系统的启动相关文件(一般在 /etc/rc.d 目录下)都是使用 Shell 脚本编写的 。
同传统的编程语言一样,Shell 提供了很多特性,这些特性可以使 Shell 脚本编程更为有用 , 如数据变量、参数传递、判断、流程控制、数据输入和输出、子程序及中断处理等 。
说了这么多,其实我们在 Linux 中操作的命令行界面就是 Linux 的 Shell , 也就是 Bash,但是我们的图形界面是 Shell 吗?其实从广义讲,图形界面当然也是 Shell,因为它同样用来接收用户的操作,并传递到内核进行处理 。不过 , 这里的 Shell 主要指的是 Bash 。
Shell 脚本
Shell 脚本(shell script),是一种为 shell 编写的脚本程序 。
业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念 。
由于习惯的原因,简洁起见,本文出现的 "shell编程" 都是指 shell 脚本编程 , 不是指开发 shell 自身 。
Shell的分类
目前 Shell 的版本有很多种,如 Bourne Shell、C Shell、Bash、ksh、tcsh 等,它们各有特点,下面简要介绍一下 。
最重要的 Shell 是 Bourne Shell,这个命名是为了纪念此 Shell 的发明者 Steven Bourne 。从 1979 年起,UNIX 就开始使用 Boume Shell 。Bourne Shell 的主文件名为 sh,开发人员便以 sh 作为 Bourne Shell 的主要识别名称 。
虽然 Linux 与 UNIX 一样,可以支持多种 Shell,但 Boume Shell 的重要地位至今仍然没有改变,许多 UNIX 系统中仍然使用 sh 作为重要的管理工具 。它的工作从开机到关机,几乎无所不包 。在 Linux 中,用户 Shell 主要是 Bash,但在启动脚本、编辑等很多工作中仍然使用 Bourne Shell 。
C Shell 是广为流行的 Shell 变种 。C Shell 主要在 BSD 版的 UNIX 系统中使用,发明者是柏克莱大学的 Bill Joy 。C Shell 因为其语法和 C 语言类似而得名,这也使得 UNIX 的系统工程师在学习 C Shell 时感到相当方便 。
Bourne Shell 和 C Shell 形成了 Shell 的两大主流派别,后来的变种大都吸取这两种 Shell 的特点,如 Korn、 tcsh 及 Bash 。
Bash Shell 是 GNU 计划的重要工具之一,也是 GNU 系统中标准的 Shell 。Bash 与 sh 兼容,所以许多早期开发出来的 Bourne Shell 程序都可以继续在 Bash 中运行 。现在使用的 Linux 就使用 Bash 作为用户的基本 Shell 。
Bash 于 1988 年发布,并在 1995-1996年推出Bash 2.0 。在这之前,广为使用的版本是1.14,Bash 2.0增加了许多新的功能,以及具备更好的兼容性 。表 2 中详细列出了各版本的具体情况 。
注意 , Shell 的两种主要语法类型有 Bourne 和 C , 这两种语法彼此不兼容 。Boume 家族主要包括 sh、ksh、Bash、psh、zsh;C 家族主要包括 csh、tcsh(Bash 和 zsh 在不同程序上支持 csh 的语法) 。
本章讲述的脚本编程就是在 Bash 环境中进行的 。不过,在 Linux 中除了可以支持 Bash,还可以支持很多其他的 Shell 。我们可以通过 /etc/shells 文件来査询 Linux 支持的 Shell 。命令如下:
在 Linux 中 , 这些 Shell 是可以任意切换的,命令如下:
用户信息文件 /etc/passwd 的最后一列就是这个用户的登录 Shell 。命令如下:
大家可以看到 , root 用户和其他可以登录系统的普通用户的登录 Shell 都是 /bin/bash,也就是 Linux 的标准 Shell,所以这些用户登录之后可以执行权限允许范围内的所有命令 。不过,所有的系统用户(伪用户)因为登录 Shell 是 /sbin/ndogin,所以不能登录系统 。
笔记:
sh/bash/csh/Tcsh/ksh/pdksh等shell的区别
Linux系统入门-BashShell 是一种命令行解释器, 其读取用户输入linux命令行解释器的字符串命令, 解释并且执行命令;它是一种特殊的应用程序, 介于系统调用/库与应用程序之间, 其提供了运行其他程序的的接口;它可以是交互式的, 即读取用户输入的字符串;也可以是非交互式的, 即读取脚本文件并解释执行, 直至文件结束. 无论是在类 UNIX, Linux 系统, 还是 Windows, 有很多不同种类的 Shell: 如类 UNIX, Linux 系统上的 Bash, Zsh 等; Windows 系统上的 cmd, PowerShell 等.
Bash 是 Bourne Again SHell 的缩写, 是 GNU 计划中的 Shell, 也是一些类 UNIX 系统与多数 Linux 发行版的默认 Shell
使用Shell可以实现对Linux系统实现绝大部分的管理linux命令行解释器,例如:
#获取当前时间
[root@CentOS7 ~]# date
Mon Mar 15 22:59:47 CST 2021
#创建文件
[root@CentOS7 opt]# touch xcz
[root@CentOS7 opt]# ll
-rw-r--r--. 1 root root 0 Mar 15 23:01 xcz
#创建一百个文件linux命令行解释器 , 我们一般就会使用shell script进行创建
[root@CentOS7 opt]# cat touch.sh
#!/bin/bash
for n in `seq 100`;do
touch xcz$n
echo "文件xcz$n创建成功哦!"
done
[root@CentOS7 opt]# sh touch.sh
命令行输入方式:效率较低,适用于工作量不大的工作;
shell script 脚本方式:效率高,适用于工作量大且复杂的工作 。
[root@CentOS7 opt]# bash --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3 : GNU GPL version 3 or later
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
'#39; = 普通用户
'#' = root用户(超级管理员)
#查看当前用户
[root@CentOS7 ~]# whoami
root
#查看当前命令提示符
[root@CentOS7 ~]# echo $PS1
[u@h W]$
root:当前系统的用户
CentOS7:当前系统的主机名
~:当前所在的位置
#:超级管理员身份(root用户)
$:普通用户
提示符参数及含义
d :代表日期;
H :完整的主机名称
h :仅取主机名中的第一个名字
:显示时间为24小时格式,如:HH:MM:SS
T :显示时间为12小时格式
A :显示时间为24小时格式:HH:MM
u :当前用户的账号名称
v :BASH的版本信息
w :完整的工作目录名称
W :利用basename取得工作目录名称,只显示最后一个目录名
# :下达的第几个命令
$ :提示字符,如果是root用户 , 提示符为 "#" ,普通用户则为 "#34;
#颜色
30 40 黑色
31 41 红色
32 42 绿色
33 43 黄色
34 44 蓝色
35 45 紫红色
36 46 青蓝色
37 47 白色
PS1='[e[32;40m] [[u@h w]$ [e[0m]'
PS1="[e[37;40m][[e[32;40m]u[e[37;40m]@h [e[36;40m]w[e[0m]]$ "
PS1="[e[37;40m][[e[32;40m]u[e[37;40m]@[e[35;40m]h[e[0m] [e[36;40m]w[e[0m]]$ "
#提示符的应用
[root@CentOS7 ~]# vi .bashrc
#最后一行下面添加
PS1="[e[37;40m][[e[32;40m]u[e[37;40m]@[e[35;40m]h[e[0m] [e[36;40m]w[e[0m]]$ "
#使用source生效
[root@CentOS7 ~]# source .bashrc
#命令 选项 参数
command [-options] [arguments]
[root@CentOS7 ~]# ls -l /opt/
#命令:整条shell命令的主体
#选项:用于调节命令的具体功能
#以'-'引导段个事选项(单个字符),例如”-l“
#以'--'引导长格式选项(多个字符),例如”--list“
#多个短格式选项可以卸载一起,只用一个”-“引导 , 例如”-la“
#参数:命令操作与偶的对象,如文件、目录名等
#命令必须开头,选项和参数位置可以发生变化
我们在使用Linux系统进行查找一个多层级的文件时,我们可以使用键盘上的Tab键进行快速补全
补全的形式有:
#如果我们忘记网络配置文件具体路径,那么我们就可以使用补全的形式进行配置
[root@CentOS7 ~]# vi /etc/sysconfig/
anaconda cpupower grub irqbalance modules/ rdisc selinux
authconfig crond init kdump netconsole readonly-root sshd
cbq/ ebtables-config ip6tables-config kernel network rsyslog wpa_supplicant
console/ firewalld iptables-config man-db network-scripts/ run-parts
[root@CentOS7 ~]# vi /etc/sysconfig/network
network network-scripts/
[root@CentOS7 ~]# vi /etc/sysconfig/network-scripts/if
ifcfg-ens33 ifdown-eth ifdown-post ifdown-Team ifup-aliases ifup-ipv6 ifup-post ifup-Team
ifcfg-lo ifdown-ippp ifdown-ppp ifdown-TeamPort ifup-bnep ifup-isdn ifup-ppp ifup-TeamPort
ifdown ifdown-ipv6 ifdown-routes ifdown-tunnel ifup-eth ifup-plip ifup-routes ifup-tunnel
ifdown-bnep ifdown-isdn ifdown-sit ifup ifup-ippp ifup-plusb ifup-sit ifup-wireless
[root@CentOS7 ~]# vi /etc/sysconfig/network-scripts/ifcfg-
ifcfg-ens33 ifcfg-lo
[root@CentOS7 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
#如果你的Linux系统无法进行补全,那么咱们可以安装一个扩展包即可
[root@CentOS7 ~]# yum install -y bash-completion
clear #或者用快捷键 ctrll
ctrl c #有些程序也可以用q键退出
ctrl z # 进程会挂起到后台
bg jobid # 让进程在后台继续执行
fg jobid # 让进程回到前台
Ctrl键 a #将当前光标移动到命令行的行首
Ctrl键 e #将当前光标移动到命令行的行尾
Ctrl键 u #将当前光标之前的所有字符剪切
Ctrl键 k #将当前光标之后的所有字符剪切
Ctrl键 w #将当前光标之前的字符剪切,以空格为结尾
Ctrl键 d #退出当前会话窗口
Ctrl键 z #将当前前台运行的程序,放到后台运行
Ctrl键 r #搜索 历史 命令
Ctrl键 y #粘贴剪切板上的内容
Ctrl键 左右方向键 #向指定的方向键移动一组字符,以空格为分隔符
ESC键 . #使用上一条命令的最后的参数或者路径,以空格为分隔符,空格之后的内容,delete键 从前往后删除一个字符
!命令 #执行最近的一次以该命令为开头的命令
!! #执行上一条命令
#使用格式:
[命令][--help] 或者[man][命令] 即可
#例如touch命令帮助
[root@CentOS7 ~]# touch --help
Usage: touch [OPTION]... FILE...
Update the access and modification times of each FILE to the current time.
A FILE argument that does not exist is created empty, unless -c or -h
is supplied.
A FILE argument string of - is handled specially and causes touch to
change the times of the file associated with standard output.
Mandatory arguments to long options are mandatory for short options too.
-a change only the access time
-c, --no-create do not create any files
-d, --date=STRING parse STRING and use it instead of current time
-f (ignored)
-h, --no-dereference affect each symbolic link instead of any referenced
file (useful only on systems that can change the
timestamps of a symlink)
-m change only the modification time
-r, --reference=FILE use this file's times instead of current time
-t STAMP use [[CC]YY]MMDDhhmm[.ss] instead of current time
--time=WORD change the specified time:
WORD is access, atime, or use: equivalent to -a
WORD is modify or mtime: equivalent to -m
--help display this help and exit
--version output version information and exit
Note that the -d and -t options accept different time-date formats.
GNU coreutils online help:
For complete documentation, run: info coreutils 'touch invocation'
【linux命令行解释器 linux文件解释】关于linux命令行解释器和linux文件解释的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息 , 记得收藏关注本站 。

    推荐阅读