您的位置:首页 > 运维架构 > Linux

【Linux】文件结构

2015-10-06 20:59 579 查看

Hard Link 与 Soft Link

Linux 是通过索引号 inode 来访问文件的。







文件目录里面的每一个“文件”都有 inode 号,通过 inode 表 最终指向具体的文件位置。(可以通过 ls -i查看) ls -li 查看时 会有一个列,表示这个 inode 号的硬链接数目,请看下图的第3列(start from 1 OvO)




这个当一个inode号的硬链接数目为0时,则表示它指向的文件可以被回收(一般标记为可覆盖,也就是不完全删除)有兴趣的可以百度一下unlink

创建硬链接和软链接



图片中的第一列中的 4500992 4500993 等就是文件的 inode 索引号。

其中 ln 是创建链接命令, 默认为硬链接, -s 选项表示软链接。

注意到 file 与 它的硬链接 file.hard 的 inode 号码一致,而与软链接 file.soft 不一致。也就是说,硬链接本质上与源文件指向同一个文件,而软链接是额外创建的文件。尝试删除源文件file之后,观察其变化:




除去file之后,硬链接仍能继续访问源文件,软链接不可。原因是硬链接的 inode 号仍能访问到具体文件的位置,而软链接,观察到它的文件命名后接 -> file。它可能是通过目录项名“file”来访问源文件。尝试新建一个新的file,观察其结果:




附上盗图:







结语: linux文件系统是通过目录项(如file file.soft)的 inode 来访问具体文件,硬链接本质上是复制一个新的硬链接,指向同一个 inode。软链接是创建一个新的文件(从系统中获取 inode)其内容指向目录项。由于他指向的是目录项,这也是软链接可跨越不同文件系统的原因。

观察到新建的文件是992 993 994,也就是文件的创建会向系统申请 inode, 据说 当inode用完的时候,即使有剩余空间也无法继续申请。

不知真假,如果要测的话,可能要不停的 open(CREATE) 吧。。。

文件与设备

(1)/dev/console /dev/tty /dev/null

设备功能
console控制台
tty控制终端,echo “abc” > /dev/tty 可以在终端显示出来
null常用于 创建空文件 cp /dev/null empty_file
期待第5章的详细讲解

2015-05-25

tty 是终端对应的文件, 可以通过文件IO往里面读写,相当于终端输入和输出。 一般当我们不希望程序的输出被重定向时(可用 isatty 判断),通过直接对tty文件的读写,直接在终端输入和输出。

dup操作

dup系统调用提供了一种复制文件描述符的方法,使我们能够通过两个或者更多个不同的描述符来访问同一个文件。 ———— 摘自《Linux程序设计》


dup是复制文件描述符,返回新的描述符。而open则是创建文件描述符。那么可以对同一个文件两次打开(open)吗?如果有,那open跟dup的区别是?

[code]#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/types.h>

void jobs(int in1, int in2) 
{
  printf("in1 is %d, in2 is %d", in1, in2);
  if (-1 == in1)
  {
    write (2, "error occur when open in1\n", 100);
    exit(0);
  }
  if (-1 == in2)
  {
    write (2, "error occur when open in2\n", 100);
    exit(0);
  }
  lseek(in1, 10, SEEK_SET);
  char buffer[20];
  int nread;
  printf("\nin1:\n");
  if ((nread = read(in1, buffer, 10)) > 0 ) 
  {
    write(1, buffer, 10);
  }
  printf("\nin2:\n");
  if ((nread = read(in2, buffer, 20)) > 0 ) 
  {
    write(1, buffer, 20);
  }
  printf ("\n");
}

main1:
int main()
{
  int in1, in2;
  in1 = open("file.test", O_RDONLY);
  in2 = open("file.test", O_RDONLY);

  jobs(in1,in2);

  close(in1);
  close(in2);
  exit(0);
}

main2:
int main()
{
  int in1, in2;
  in1 = open("file.test", O_RDONLY);
  in2 = dup(in1);

  jobs(in1, in2);

  close(in1);
  close(in2);
  exit(0);
}

其中file.test的内容片段:
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>


jobs的工作是:

输出in1 in2的值;将in1向前平移10字节(lseek),再从in1读取10字节,in2读取20字节并输出。

其结果如下:

[code]main1:
in1 is 3, in2 is 4

in1:
unistd.h>

in2:
#include <unistd.h>

main2:
in1 is 3, in2 is 4
in1:
unistd.h>

in2:
#include <sys/stat.h


两次的fildes值相同,而对于俩次open的读取文件,in1 与 in2 无影响(读写指针相互独立),而对于dup出来的读写指针是共用的,也就是,in1读到20的位置时,in2接着读的时候是从20开始再读20;

感兴趣的同学可以试一下write情况下的。(open的读写指针不共用,相互覆盖。而dup的读写指针共用,不存在覆盖现象(当然如果你lseek强行指针后移…))

总结:open与dup的最大区别?是读写指针独立问题。对于dup,in1的读取会影响到in2的下一次读取位置。

P.S. 文中提到可以用文件锁保证同步(后续补上)。。。

附件:

1,便捷编译c文件:

[code]#!/bin/bash
if [ "$#" != 1 ]; then
    printf 'the num of parm should be 1'
    exit 0
fi

name=$(echo "$1" | cut -d '.' -f 1)
gcc -c "$1"
echo "compile $1"
gcc ${name}.o -o temp.out
echo "link ${name}.o"
echo "execute temp.out"
echo
./temp.out

echo 
echo "rm ${name}.o & temp.out"

rm ${name}.o 2> /dev/null
rm temp.out 2> /dev/null


这是一个脚本(我取名为c2o),可以将它放在PATH 路径中的某个文件夹中(我的话是mkdir /usr/zhengBin 然后再到~/.bashrc中添加 PATH=/usr/zhengBin:$PATH 记得给c2o x权限)。

可以直接在shell中 c2o xxx.c 运行程序

[code]# 2015-5-24更新
# 新增remain_bin保留生成的binary文件, run_bin选项控制是否执行bin文件
# 本次修改针对于bin文件执行时需要参数的情况
#!/bin/bash
if [ "$#" = "0" ]; then
    printf 'the num of parm should be more than 0'
    exit 0
fi

remain_bin="n"
run_bin="n"
name=""
while [ "$#" -gt 0 ];do
    case "$1" in 
        "--remain_bin")
            echo remain binary file
            remain_bin="y"
        ;;
        "--run_bin")
            echo run the binary file
            run_bin="y"
        ;;
        *)
            name="$1"
            echo name is $name
            echo \$1 is $1
        ;;
    esac
    shift
done

gcc -c $name
echo "compile $name"
name=$(echo $name | cut -d . -f 1)
gcc ${name}.o -o "$name"
echo "link ${name}.o"
if [ "$run_bin" = "y" ]; then
    echo "execute temp.out"
    echo
    TIMEFORMAT="" time ./$name
fi
echo 
echo "rm ${name}.o"
rm ${name}.o 2> /dev/null

if [ "$remain_bin" = "n" ];then
    echo "rm $name"
    rm $name 2> /dev/null
fi
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: