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. 关于SpringBoot开发微信模板推送

    在这里演示一下微信的模板消息推送: 这里使用微信测试号 来演示: 先看下效果吧: 1.首先需要申请一个  微信测试号   https://mp.weixin.qq.com/wiki?t=resourc ...

  2. 02_python_while循环/格式化输出/逻辑运算

    一. while循环 1.基本形式 while 条件: 循环体 # 判断条件是否为真,如果真,执行代码块.然后再次判断条件是否为真.如果真继续执行代码块...直到条件变成了假.循环退出 ps:死循环 ...

  3. 分组,命名分组,url的命名和反向解析

    1.位置分组 匹配到参数,按照位置参数的方式传递给视图函数 视图函数需要定义形参接收变量 1.写在url里面的: # 删除 url(r'^del_class/(\d+)',views.del_clas ...

  4. Windows Service 项目中 Entity Framework 无法加载的问题

    Windows Service 项目引用了别的类库项目,别的项目用到了 Entity Framework(通过Nuget引入),但是我的 Windows Service 无法开启,于是我修改了 App ...

  5. 修改ssh远程默认端口

    修改ssh远程默认端口 Linuxssh端口修改 1. 修改ssh配置文件 [root@distzabbix ~]# vim /etc/ssh/sshd_config 找到第17行附近#Port 22 ...

  6. flask框架--模板

    今天又是一个精彩又无聊的一天,不过随着知识的缓慢的增加我的内心也充满了干劲,虽然前进的有些缓慢 但我不会这么容易放弃的,一定要相信自己,不要灰心 好了 ~ 不说废话了 , 我自己听的都有些受不了了 . ...

  7. flask中邮件发送方法

    from flask import Flask from flask_mail import Mail, Message app = Flask(__name__) #配置邮件:服务器/端口/传输层安 ...

  8. python批量拷贝文件

    普通批量拷贝文件 import os import shutil import logging from logging import handlers from colorama import Fo ...

  9. KMP算法的next函数求解和分析过程

    转自 wang0606120221:http://blog.csdn.net/wang0606120221/article/details/7402688 假设KMP算法中的模式串为P,主串为S,那么 ...

  10. Notification 浏览器的消息推送

    Notification 对象,存在于window上,可以生成一个通知对象以推送推送浏览器消息通知. 这玩意兼容性不咋地,实不实用看场景.对外用户的应用,自然是鸡肋功能,因为你无法知道用户使用的是哪家 ...