使用 Linux 命令行的人来说,pwd命令是非常有用的,执行 pwd 命令可立刻得知您目前所在的工作目录的绝对路径名称。

认识pwd命令

顾名思义,pwd命令打印当前工作目录或简单的目录用户,目前。 它使用从根 (/) 开始的完整路径打印当前目录名称。 此命令内置于 shell 命令中。

对于内置命令就是shell当做自带的,因为shell当中自己要进行管理,那么就需要一些命令进行管理,不同的shell肯定有不同的shell命令。

我们用type命令就可以看到其的类型,内置shell命令其实就是bash当中内部的命令,就好比我们一个软件内部的嵌套的不同的功能一样;

pwd 的基本语法:

pwd [OPTION]

选项 :

-L (logical) 目录连接链接时,输出连接路径
-P (physical) 输出物理路径

使用默认方式,用 pwd 命令查看默认工作目录的完整路径


使用pwd -P 显示出实际路径


目录连接链接时,pwd显示的是连接路径;pwd -P 显示出实际路径,而非使用连接(link)路径;

POSIX 要求默认值为 -L,但大多数脚本都需要 -P。当前外壳默认为 -L,而独立时
pwd 实现默认为 -P。

最简单的pwd命令实现

实现pwd真的太简单了,只要在程序中使用getcwd()函数就可以实现获得绝对路径的功能了。

#include <stdlib.h>
#include <unistd.h>//getcwd
#include <stdio.h>int main(int argc, char **argv)
{char *wd =getcwd(NULL, 0);if (NULL == wd) {printf("Get cerrent working directory fail.\n");exit(-1);} else {printf("%s\n", wd);}return 0;
}

编译运行:

上面其实已经实现了pwd的功能,但这显然只能实现其功能,而不能了解其工作原理;我们接着往下来!

快速理解inode

在一个文件系统中,一个inode代表一个文件,并使用一个整数值来表示该inode,里面包含了与该文件有关的一些信息。

inode包含很多的文件元信息,但不包含文件名,利用stat命令可以查看一个文件更加详细的inode信息,包括inode编号,占用的块数量,块大小,硬链接个数,atime, mtime, ctime

总之,除了文件名以外的所有文件信息,都存在inode之中。

Linux中的目录

Linux文件系统是目录和文件组成的一种层次结构,目录的起点称为根(root),其名字是一个字符 / 。

在作为路径使用时, 根目录 / 是一个绝对路径,而Linux中也有一些相对路径可用,比如 . 或 ./ 表示当前目录、 … 或 …/ 表示上一级目录、 ~ 或 ~/ 表示当前用户的主目录(家目录)。

在Linux目录中,每个名字有一个inode number,inode number指出了存储数据的硬盘空间的位置。通过ls -i看到名字和inode对应关系。

综上,Linux中,一个文件(包括目录)的文件名,及文件名与inode的对应关系,都是由包含该文件的目录所描述的。

pwd实现

static void file_name_free(struct file_name *p)
{free (p->buf);free (p);
}static struct file_name *file_name_init (void)
{struct file_name *p = (struct file_name *)malloc (sizeof *p);/* 从大于 PATH_MAX 的缓冲区开始,但要注意系统
其中 PATH_MAX 非常大——例如,INT_MAX。  */p->n_alloc = MIN (2 * PATH_MAX, 32 * 1024);p->buf = (char *)malloc (p->n_alloc);p->start = p->buf + (p->n_alloc - 1);p->start[0] = '\0';return p;
}/* 将长度为 S_LEN 的名称 S 附加到不断增长的文件名 P 之前。  */
static void file_name_prepend (struct file_name *p, char const *s, size_t s_len)
{size_t n_free = p->start - p->buf;if (n_free < 1 + s_len){size_t half = p->n_alloc + 1 + s_len;char *q = (char *)calloc (2, half);size_t n_used = p->n_alloc - n_free;p->start = q + 2 * half - n_used;memcpy (p->start, p->buf + n_free, n_used);free (p->buf);p->buf = q;p->n_alloc = 2 * half;}p->start -= 1 + s_len;p->start[0] = '/';memcpy (p->start + 1, s, s_len);
}/* 返回一个由 N 个 '/' 分隔的“..”组件组成的字符串(malloc'd)。  */
static char *nth_parent(size_t n)
{char *buf = (char *)calloc(3, n);char *p = buf;for (size_t i = 0; i < n; i++){memcpy (p, "../", 3);p += 3;}p[-1] = '\0';return buf;
}static inline bool dot_or_dotdot (char const *file_name)
{if (file_name[0] == '.'){char sep = file_name[(file_name[1] == '.') + 1];return (! sep || ISSLASH (sep));}elsereturn false;
}/* readdir 的包装器,以便调用者看不到 '.' 的条目。 或“……”。  */
static inline struct dirent const *readdir_ignoring_dot_and_dotdot (DIR *dirp)
{while (1){struct dirent const *dp = readdir(dirp);if (dp == NULL || ! dot_or_dotdot(dp->d_name))return dp;}
}static void find_dir_entry (struct stat *dot_sb, struct file_name *file_name,size_t parent_height)
{DIR *dirp;int fd;struct stat parent_sb;bool use_lstat;bool found;dirp = opendir("..");if (dirp == NULL)printf("cannot open directory %s\n",strdup(nth_parent(parent_height)));fd = dirfd (dirp);
/*chdir()这个系统调用,是改变当前程序的工作目录,不是改变bash的工作目录*/ if ((0 <= fd ? fchdir(fd) : chdir("..")) < 0)printf("failed to chdir to %s\n",strdup(nth_parent(parent_height)));if ((0 <= fd ? fstat(fd, &parent_sb) : stat(".", &parent_sb)) < 0)printf("failed to stat %s\n",strdup(nth_parent(parent_height)));/*如果父目录和子目录在不同的设备上,那么我们
不能依赖 d_ino 来获取有用的 i-node 编号; 请改用 lstat。  */use_lstat = (parent_sb.st_dev != dot_sb->st_dev);found = false;while (1){struct dirent const *dp;struct stat ent_sb;unsigned long long int ino = 0;errno = 0;if ((dp = readdir_ignoring_dot_and_dotdot (dirp)) == NULL){if (errno){/* 在 closedir 调用中保存/恢复 errno。   */int e = errno;closedir (dirp);errno = e;/* 安排在退出此循环后进行诊断。   */dirp = NULL;}break;}ino = dp->d_ino;if (ino == NOT_AN_INODE_NUMBER || use_lstat){if (lstat (dp->d_name, &ent_sb) < 0){/* 跳过我们无法统计的任何条目。  */continue;}ino = ent_sb.st_ino;}if (ino != dot_sb->st_ino)continue;/* 如果我们不跨越设备边界,那么一个简单的 i-node
匹配就足够了。  */if ( ! use_lstat || ent_sb.st_dev == dot_sb->st_dev){file_name_prepend(file_name, dp->d_name, strlen(dp->d_name));found = true;break;}}if (dirp == NULL || closedir (dirp) != 0){/* N请注意,此诊断适用于 readdir
和关闭失败。  */printf("reading directory %s\n",strdup(nth_parent(parent_height)));}if ( ! found)printf("couldn't find directory entry in %s with matching i-node",strdup(nth_parent(parent_height)));;*dot_sb = parent_sb;
}/* 调用 lstat 以获取“/”的设备和 inode 编号。失败时,返回NULL。 否则,设置成员*ROOT_D_I 相应地并返回 ROOT_D_I。  */
struct dev_ino *get_root_dev_ino (struct dev_ino *root_d_i)
{struct stat statbuf;if (lstat ("/", &statbuf))return NULL;root_d_i->st_ino = statbuf.st_ino;root_d_i->st_dev = statbuf.st_dev;return root_d_i;
}static void robust_getcwd (struct file_name *file_name)
{size_t height = 1;struct dev_ino dev_ino_buf;struct dev_ino *root_dev_ino = get_root_dev_ino (&dev_ino_buf);struct stat dot_sb;if (root_dev_ino == NULL)printf("failed to get attributes of %s\n",strdup("/"));if (stat (".", &dot_sb) < 0)printf("failed to stat %s\n",strdup("."));while (1){find_dir_entry (&dot_sb, file_name, height++);}/* 查看是否需要前导斜线; file_name_prepend 添加一个。   */if (file_name->start[0] == '\0')file_name_prepend (file_name, "", 0);
}/* 如果“pwd -L”可接受,则从环境中返回 PWD输出,否则为 NULL。   */
static char *logical_getcwd (void)
{struct stat st1;struct stat st2;char *wd = getenv("PWD");char *p;/* 首先进行文本验证。  */if (!wd || wd[0] != '/')return NULL;p = wd;while ((p = strstr(p, "/."))){if (!p[2] || p[2] == '/'|| (p[2] == '.' && (!p[3] || p[3] == '/')))return NULL;p++;}/* 系统调用验证  */if (stat(wd, &st1) == 0 && stat (".", &st2) == 0)return wd;return NULL;
}int main(int argc, char **argv)
{char *wd;/* POSIX 要求默认值为 -L,但大多数脚本都需要 -P。
当前外壳默认为 -L,而独立时
pwd 实现默认为 -P。 */bool logical = (getenv ("POSIXLY_CORRECT") != NULL);while (1){int c = getopt(argc, argv, "LP");if (c == -1)break;switch (c){case 'L':logical = true;break;case 'P':logical = false;break;default:break;}}if (optind < argc)printf("ignoring non-option arguments\n");if(logical){wd = logical_getcwd();if (wd){puts(wd);return 0;}}wd = getcwd(NULL, 0);if (wd != NULL){puts(wd);free(wd);}else{struct file_name *file_name = file_name_init();robust_getcwd(file_name);puts (file_name->start);file_name_free(file_name);}return 0;
}

编译运行

总结

Linux中用 pwd 命令来查看”当前工作目录“的完整路径。 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录。在不太确定当前位置时,就会使用pwd来判定当前目录在文件系统内的确切位置。

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792)交流学习。

常见Linux命令pwd实现相关推荐

  1. linux命令pwd

    linux命令pwd命令用来显示当前路径 -L 显示逻辑路径 这个命令也是经常用到

  2. linux进程 面试题,Linux面试题,浅析常见Linux命令面试题及答案

    原标题:Linux面试题,浅析常见Linux命令面试题及答案 对于Linux面试来说如果面试官问到你不会的问题,你就说这个不太熟悉,没有具体研究过,千万别不懂装懂,还扯一堆没用的话题来掩饰,这样只会让 ...

  3. 常见linux命令介绍-ps

    原文地址:常见linux命令介绍-ps 前言 ps(Process Status)命令是linux中最常见的命令之一,它用来列出当前系统中运行的那些进程的状态信息,当然了,它只显示命令执行时的进程状态 ...

  4. Linux命令 - pwd命令

    Linux命令 - pwd命令   pwd是print working directory的缩写,Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在 ...

  5. Linux命令·pwd

    Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文 ...

  6. linux命令——pwd

    pwd是一个linux下一个简单的命令,主要功能是输出当前工作的绝对路径,可能有人觉得这个没什么用,不是一看命令前面就可以知道了吗?但是如果命令前面的标识看不见呢? 在渗透测试过程中,往往涉及到文件上 ...

  7. 常见linux命令使用方法(二)

    下面是我在工作中使用linux时,整理的一些命令,按字母表顺序进行编号.虽然不详细,但是记录的基本上都是常见的或有用的用法,自己感觉很有用哦!希望在你有时忘了.或者手足无措的时候会忽然给你一个惊喜. ...

  8. 常见Linux命令整理

    linux 常用命令--------雪松整理 Q 群: 198173206 欢迎 linux 系统运维朋友加入! 博客: http://hi.baidu.com/quanzhou722/blog 错误 ...

  9. Linux命令--pwd

    pwd 命令 说明 pwd命令以绝对路径的方式显示用户当前工作目录.命令将当前目录的全路径名称(从根目录)写入标准输出.全部目录使用/分隔.第一个/表示根目录,最后一个目录是当前目录.执行pwd命令可 ...

最新文章

  1. Linux下root密码忘记的解决办法
  2. python变量类型之间转换_Python变量赋值类型转换
  3. 胡言乱语集锦-大数据,手机,传统,养生
  4. PHP导入Excel和导出Excel
  5. jsp java注释_jsp注释方式
  6. javafx 打印控件_Java的新视差控件(JavaFX)
  7. How to activate an Anaconda environment
  8. zabbix agent报错 :cannot connect to [[127.0.0.1]:10051]: [111] Connection refused
  9. SCI论文编辑教你如何准备SCI论文和写作
  10. 系统学习机器学习之线性判别式(三)--广义线性模型(Generalized Linear Models)
  11. [NOIP2016]愤怒的小鸟
  12. tomcat打印日志 linux,linux服务器修改tomcat日志输出路径方法
  13. 坐着童年纸飞机的C语言for循环!超好玩!超详细!
  14. PS亮度蒙版插件TKActions V5 Mac版
  15. github注册,使用方法
  16. Android Google Map集成以及部分功能的实现
  17. Java23种设计模式 适配器模式【Adapter Pattern】
  18. 浪潮优派培训笔记:Tomcat服务器
  19. Eclipse Che安装使用
  20. 值班c语言程序,c语言编程,实验楼值班排班系统。

热门文章

  1. Nebula Graph 招募社区布道师
  2. 为技术发声,因分享发光——最受开发者欢迎的“开发者布道师”评选结果来啦!...
  3. 80后年轻老板创业心经
  4. vlookup匹配的文字显示0_VLOOKUP函数用法大全
  5. 思科网络安全 第七章测验答案
  6. SpringCloud五大神兽03-Hystrix断路器(豪猪)
  7. 兴趣学水彩?业余练习也要准备的画画工具看这里
  8. 电脑、Windows系统下方搜索栏搜不出文件怎么办?如何解决?实测有效
  9. Web_制作页面开场动画并解决自动播放问题
  10. 想将PPT的文字转换到Word文档?看这一篇就够了!!!