Linux Bash/C 文件读写相关练习

子任务一 系统文件读写

(1)读取/etc/passwd内容

(2)将/etc/passwd系统文件内容复制到新建文件passwd中

(3)将/etc/passwd系统文件内容一半复制到新建文件passwd_half中

C源代码

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <stdio.h>

#define MAXLINE 80

int main(int argc, char **argv)
{
    int fd1, fd2, n, size = 0;
    char buf[MAXLINE];

    fd1 = open("/etc/passwd", O_RDONLY);
    fd2 = open("passwd", O_WRONLY | O_CREAT);

    while ((n = read(fd1, buf, MAXLINE)) > 0) {
        write(STDOUT_FILENO, buf, n);
        write(fd2, buf, n);
        size += n;
    }

    close(fd1);
    close(fd2);

    fd1 = open("/etc/passwd", O_RDONLY);
    fd2 = open("passwd_half", O_WRONLY | O_CREAT);

    size /= 2;

    while (size > MAXLINE) {
        read(fd1, buf, MAXLINE);
        write(fd2, buf, MAXLINE);
        size -= MAXLINE;
    }
    read(fd1, buf, size);
    write(fd2, buf, size);

    close(fd2);
    close(fd1);

    return 0;
}

python写法

MAXLINE = 80

# os.copy('/etc/passwd', 'passwd')
size = 0
with open('/etc/passwd', 'r') as fd1:
    with open('passwd', 'w') as fd2:
        buf = 'buf'
        while buf:
            buf = fd1.read(MAXLINE)
            print(buf, end='')
            fd2.write(buf)
            size += len(buf)

size = int(size/2)
with open('passwd', 'r') as fd1:
    with open('passwd_half', 'w') as fd2:
        while size > 0:
            if size < MAXLINE:
                buf = fd1.read(size)
            else:
                buf = fd1.read(MAXLINE)
            fd2.write(buf)
            size -= MAXLINE

子任务二 文件内容统计

(1)生成系统软件包名和版本文件

(2) 去除版本号信息

(3) 在一行中显示

(4) 查找带有lsb字样的软件包个数

bash源代码

#!/bin/bash
#

filename=filesystem.manifest

dpkg-query -W --showformat='${Package} ${Version}\n' > $filename

cat $filename | awk '{print $1}' > ${filename}.name

cat ${filename}.name | xargs > ${filename}.name.oneline

cat ${filename}.name | grep "lsb" | wc -l

python写法

import re

filename = 'filesystem.manifest'

with open(filename, 'r') as f:
    lst = f.read().split('\n')
    with open(''.join([filename, '.name']), 'w') as fn:
        for item in lst:
            fn.write(item.split(' ')[0])
            fn.write('\n')


with open(''.join([filename, '.name']), 'r') as fn:
    lst = fn.read().split('\n')
    with open(''.join([filename, '.name', '.oneline']), 'w') as fl:
        for item in lst:
            fl.write(item)
            fl.write(' ')

pattern = re.compile('lsb')
cnt = 0

with open(''.join([filename, '.name', '.oneline']), 'r') as fc:
    lst = fc.read().split(' ')
    for item in lst:
        if pattern.match(item):
            cnt += 1
        
print(cnt)

 

子任务三 文件描述符获取

(1)打印STDIN STDOUT STDERR文件描述符

(2)打开文件a 打印文件描述符

(3)不关闭文件a 定义新的文件描述符重新打开a并打印文件描述符

(4)关闭文件a 定义新的文件描述符重新打开a并打印文件描述符

C源代码

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int STDIN = fileno(stdin);
    int STDOUT = fileno(stdout);
    int STDERR = fileno(stderr);
    int fd, newfd;
    FILE *fp;

    fp = fopen("a", "r");
    if (!fp) return -1;
    fd = fileno(fp);

    printf("STDIN: %d\n", STDIN);
    printf("STDOUT: %d\n", STDOUT);
    printf("STDERR: %d\n", STDERR);
    printf("FD: %d\n", fd);

    newfd = open("a", O_RDONLY);
    printf("NEWFD(OPEN): %d\n", newfd);

    fclose(fp);
    newfd = open("a", O_RDONLY);
    printf("NEWFD(CLOSE): %d\n", newfd);

    close(newfd);

    return 0;
}

 

知识: 

标准输入 输出 错误输出 的文件描述符分别为0, 1, 2

打开文件时 操作系统会分配一个文件描述符(从3开始)

多个程序同时打开一个文件时 会分配多个文件描述符

而当文件描述符关闭时 会释放此文件描述符

当有新的文件打开时 再把文件描述符分配给它

 

子任务四 检测文件读写权限

C源代码

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int fd, fl, mode;

    fd = open("a", O_RDONLY);

    fl = fcntl(fd, F_GETFL);

    mode = fl & O_ACCMODE;

    if (mode == O_RDONLY) {
        printf("read only\n");
    } else if (mode == O_WRONLY) {
        printf("write only\n");
    } else if (mode == O_RDWR) {
        printf("read write\n");
    } else {
        printf("unknown mode\n");
    }

    return 0;
}

 

子任务五 锁定/解锁文件

C源代码 懒的判断锁状态了

(1) 锁定读 10-30偏移量

(2) 锁定写 40-50 偏移量

(3) 打印相关信息

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    int fd, fl, stat;
    struct flock lock1;
    struct flock lock2;

    fd = open("/tmp/test_lock", O_RDWR);

    if (fd < 0) {
        printf("open err!\n");
        return -1;
    }

    lock1.l_type = F_RDLCK;
    lock1.l_start = 10;
    lock1.l_len = 20;
    lock1.l_whence = SEEK_SET;

    stat = fcntl(fd, F_SETLK, &lock1);

    if (stat < 0) {
        printf("read lock err !\n");
        return -2;
    } else {
        printf("locking file(read)\n");
    }

    sleep(2);
    printf("process %d closing file\n", getpid());



    lock2.l_type = F_WRLCK;
    lock2.l_start = 40;
    lock2.l_len = 10;
    lock2.l_whence = SEEK_SET;

    stat = fcntl(fd, F_SETLK, &lock2);

    if (stat < 0) {
        printf("write lock err !\n");
        return -2;
    } else {
        printf("locking file(write)\n");
    }

    sleep(2);
    close(fd);
    printf("process %d closing file\n", getpid());

    return 0;
}

 

子任务六 获得/修改文件权限

(1)判断owner others对test01 02 03的读写情况

(2)修改test01 02 03 权限为

rw-rw-r--

rw-rwxr--

rw-rw--w-

C源代码

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

void getPerm(char *filename)
{
    struct stat buf;
    int acc = stat(filename, &buf);
    if (acc < 0) {
        printf("stat err!\n");
        exit(-1);
    }

    if (buf.st_mode & S_IRUSR) {
        printf("owner can read %s\n", filename);
    }
    if (buf.st_mode & S_IWUSR) {
        printf("owner can write %s\n", filename);
    }

    if (buf.st_mode & S_IROTH) {
        printf("others can read %s\n", filename);
    }
    if (buf.st_mode & S_IWOTH) {
        printf("others can write %s\n", filename);
    }

}

int main(int argc, char **argv)
{
    int i;
    char *filename[3] = {
        "test01", "test02", "test03"
    };

    for (i = 0; i < 3; i++) {
        getPerm(filename[i]);
    }

    chmod(filename[0], S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH);
    chmod(filename[1], S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH);
    chmod(filename[2], S_IWUSR | S_IRUSR | S_IWGRP | S_IWOTH);

    return 0;
}

 

转载于:https://my.oschina.net/nichijou/blog/756089

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值