pwd命令:打印当前的工作目录

我们都知道每个目录下面都有两个特殊的目录( . 和 .. ), .: 当前目录, ..: 上层目录,  每个目录都有一个i节点与之相关联

ghostwu@ubuntu:~$ ls -i
bak examples.desktop python
core Music shell_script
c_program note software
data php tags
Desktop php_study Templates
Documents Pictures unix
Downloads Public Videos

通过ls -i就可以显示每个文件和目录的inode值,比如下面我用ls -ia显示所有文件的inode

1,当工作在basic目录下面的时候,   当前目录basic( 也就是. )他的inode值为1573909,   ..: 1507

2,当把路径切换到python时候, .: 1507 刚好就跟basic的 .. 相等。后面依次类推

通过inode的关联就把目录的层级关系给找出来了,下一个问题:如何知道,已经到达根目录?

ghostwu@ubuntu:~/python/basic$ ls -ia
. person2.class.py test1.py
.. person3.class.py test2.py
func2.py person4.class.py test3.py
func3.py person.class.py test4.py
func.py superlist.class.py
ghostwu@ubuntu:~/python/basic$ cd ..
ghostwu@ubuntu:~/python$ ls -ia
. .. advance basic django
ghostwu@ubuntu:~/python$ cd ..
ghostwu@ubuntu:~$ ls -ia
. .mysql_history
.. .navicat64
.adobe note
.atom php
...

在根目录(/)下面的. 和 ..,他们的inode节点有个特点, 都是相等的,所以只要判断当前目录的inode等于上层目录的inode,就可以断定,到达根目录了

ghostwu@ubuntu:/$ ls -1ia
.
..
bin
boot
cdrom
dev
etc
home
...

1,第一个要解决的问题: 如果通过路径/文件名,得到对应的inode值,通过stat函数,获得文件/目录的struct stat结构体,文件信息都在这里保存,包括inode

 /*================================================================
* Copyright (C) 2018 . All rights reserved.
*
* 文件名称:pwd.c
* 创 建 者:ghostwu(吴华)
* 创建日期:2018年01月10日
* 描 述:pwd命令编写
*
================================================================*/ #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h> //读取当前文件的i节点
ino_t get_inode( char* name ); int main(int argc, char *argv[])
{
printf( "当前目录.的inode=%ld\n", get_inode( "." ) );
printf( "上层目录..的inode=%ld\n", get_inode( ".." ) );
return ;
} ino_t get_inode( char* name ) {
struct stat statinfo;
if( - == stat( name, &statinfo ) ) {
printf( "文件%s打开失败\n", name );
exit( - );
}
return statinfo.st_ino;
}

2,完整的pwd源码

 /*================================================================
* Copyright (C) 2018 . All rights reserved.
*
* 文件名称:pwd.c
* 创 建 者:ghostwu(吴华)
* 创建日期:2018年01月10日
* 描 述:pwd命令编写
*
================================================================*/ #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h> #ifndef BUFSIZE
#define BUFSIZE 100
#endif //读取当前文件的i节点
ino_t get_inode( char* name );
void printpathto( ino_t cur_node );
//根据当前inode节点,找到它对应的路径名称
void inode_to_name( ino_t cur_node, char* str, int bufsize ); int main(int argc, char *argv[])
{
//printf( "当前目录.的inode=%ld\n", get_inode( "." ) );
//printf( "上层目录..的inode=%ld\n", get_inode( ".." ) );
printpathto( get_inode( "." ) );
putchar( '\n' );
return ;
} void printpathto( ino_t cur_node ) { char dir_name[BUFSIZE];
ino_t my_node;
//如果当前节点不等于..,说明没有到达根目录
if( cur_node != get_inode( ".." ) ) {
//切换到上层目录, 当前目录(.)的名称在上层目录(..)
//所以找名称之前,先要切换到上层目录
chdir( ".." );
inode_to_name( cur_node, dir_name, BUFSIZE );
//chdir( ".." ); //不能放在这里,放在这里 找不到目录的名称
my_node = get_inode( "." );
printpathto( my_node );
printf( "/%s", dir_name );
}
} void inode_to_name( ino_t cur_node, char* str, int bufsize ) {
DIR* dir_entry;
struct dirent* pCurDir;
if( ( dir_entry = opendir( "." ) ) == NULL ) {
printf( "open cur directory error\n" );
exit( - );
}
//printf( "cur inode=%ld\n", cur_node );
while( ( pCurDir = readdir( dir_entry ) ) != NULL ) {
if( cur_node == pCurDir->d_ino ) {
//printf( "%s\n", pCurDir->d_name );
strncpy( str, pCurDir->d_name, bufsize );
str[bufsize-] = '\0';
closedir( dir_entry );
return;
}
}
} ino_t get_inode( char* name ) {
struct stat statinfo;
if( - == stat( name, &statinfo ) ) {
printf( "文件%s打开失败\n", name );
exit( - );
}
return statinfo.st_ino;
}

运行之后的效果:

ghostwu@ubuntu:~/c_program/linux_unix/chapter4$ ./pwd
/ghostwu/c_program/linux_unix/chapter4

还少了一层home,在home这层停止了

ghostwu@ubuntu:/home$ ls -ia
. .. ghostwu lost+found

home这层确实是 . 和 ..相等? 为什么会有这样的情况? 因为/home这个是一个分区,在linux中,每个分区都有独立的根目录结构,  /home就是这个分区的根节点,只不过被挂载到根分区( / )下面

总结:

1)linux文件分区与结构

2)目录和文件通过inode组成级联关系

linux系统编程:自己动手写一个pwd命令的更多相关文章

  1. Linux系统编程【2】——编写who命令

    学到的知识点 通过实现who命令,学到了: 1.使用man命令寻找相关信息 2.基于文件编程 3.体会到c库函数与系统调用的不同 4.加深对缓冲技术的理解 who命令的作用 who命令的使用 在控制终 ...

  2. linux系统编程综合练习-实现一个小型的shell程序(一)

    之前已经花了不少篇幅学习了linux系统编程的很多知识点:文件与io.进程.信号.管道,而零散的知识点,怎么能够综合的串接起来是学习的一个很重要的目的,当然最好的方式就是用所学的知识点做一个项目了,所 ...

  3. Linux系统编程【3.2】——ls命令优化版和ls -l实现

    前情提要 在笔者的上一篇博客Linux系统编程[3.1]--编写ls命令中,实现了初级版的ls命令,但是与原版ls命令相比,还存在着显示格式和无颜色标记的不同.经过笔者近两天的学习,基本解决了这两个问 ...

  4. linux系统编程:自己动手写一个cp命令

    cp命令的基本用法: cp 源文件 目标文件 如果目标文件不存在 就创建, 如果存在就覆盖 实现一个cp命令其实就是读写文件的操作: 对于源文件: 把内容全部读取到缓存中,用到的函数read 对于目标 ...

  5. linux系统编程综合练习-实现一个小型的shell程序(四)

    上节中已经对后台作业进行了简单处理,基本上要实现的功能已经完了,下面回过头来,对代码进行一个调整,把写得不好的地方梳理一下,给代码加入适当的注释,这种习惯其实是比较好了,由于在开发的时候时间都比较紧, ...

  6. linux系统编程综合练习-实现一个小型的shell程序(三)

    上节中已经实现了对普通命令的解析,包括输入重定向,输出重定向,管道,后台作业,这次就来执行已经解析好的命令,对应的函数为:execute_command(),首先对带有管道的命令进行执行: 比如:&q ...

  7. linux系统编程综合练习-实现一个小型的shell程序(二)

    上节minishell当中,已经初步实现了一个简单命令的解析,这节来继续对更加复杂命令进行解析,包含:输入重定向的解析.管道行的解析.输出重定向的解析以及是否有后台作业的解析,如下: 下面对其进行实现 ...

  8. Linux系统编程(14)——shell常用命令

    1. ls命令 ls命令是列出目录内容(ListDirectory Contents)的意思.运行它就是列出文件夹里的内容,可能是文件也可能是文件夹. "ls -l"命令已详情模式 ...

  9. Linux系统编程【1】——编写more命令

    背景介绍 笔者知识背景 笔者接触Linux快一年了.理论知识方面:学习了操作系统基础知识,了解进程调度.内存分配.文件管理.磁盘I/O这些基本的概念. 实操方面:会使用Linux简单命令,在嵌入式系统 ...

随机推荐

  1. cad2015卸载/安装失败/如何彻底卸载清除干净cad2015注册表和文件的方法

    cad2015提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装cad2015失败提示cad2015安装未完成,某些产品无法安装,也有时候想重新安装cad2015 ...

  2. Django(ORM常用字段)

    day68 参考:http://www.cnblogs.com/liwenzhou/p/8688919.html 1. Django ORM常用字段:             1. AutoField ...

  3. [JavaScript] Nginx实现跨域设置

    假如跨域请求的接口为:http://xxx.cn/was5/web/search Nginx配置: 在conf/nginx.conf文件中 location / { root html; index ...

  4. POJ 2696

    #include<iostream> #define MAXN 1005 #include<stdio.h> using namespace std; int _m[MAXN] ...

  5. 跨站请求伪造(CSRF攻击)理解

    一  概念 你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的 ...

  6. C# 多线程八之并行Linq(ParallelEnumerable)

    1.简介 关于并行Linq,Ms官方叫做并行语言集成(PLINQ)查询,其实本质就是Linq的多线程版本,常规的Linq是单线程的,也就是同步的过程处理完所有的查询.如果你的Linq查询足够简单,而且 ...

  7. webstorm引用ESLint进行静态代码检查

    安装 ESLint 基于 Node 平台,所以 Nodejs 是必须安装的,然后通过 npm 安装 ESLint 包,至于全局安装还是作为开发依赖安装,取决于个人. 然后在 WebStorm 中,打开 ...

  8. sql server 主从库设计和数据库镜像设计

    sql server 主从设计可以通过sql server 的发布订阅实现,在大数据量的时候不要用快照发布,要使用事务发布的方式实现. 主从的设计后,要将数据库的读写分离,实现数据库效率的提示 而数据 ...

  9. notecase的下载与安装(全网最详细)(图文详解)

    不多说,直接上干货! notecase是什么? 一个按照树状结构来组织文档内容的笔记管理程序 1.双击 2.aceept 3.选择安装所放置的目录路径 4.选择开启目录文件夹 我这里,保持默认 建议默 ...

  10. 一段奇妙的vim编辑器之旅

    一.背景 对于Linux服务器上的操作,我们往往少不了使用vim,而有时候我对vim的使用并没有那么的熟练和深入,这周就深入的学习了vim的使用,包括入门和进阶,先分享给你们,也方便自己以后复习查询. ...