当前位置:文档之家› linux源代码分析实验报告格式

linux源代码分析实验报告格式

linux源代码分析实验报告格式
linux源代码分析实验报告格式

linux源代码分析实验报告格式

Linux的fork、exec、wait代码的分析

指导老师:景建笃

组员:王步月

张少恒

完成日期:2005-12-16

一、 设计目的

1.通过对Linux 的fork 、exec 、wait 代码的分析,了解一个操作系统进程的创建、

执行、等待、退出的过程,锻炼学生分析大型软件代码的能力;

2.通过与同组同学的合作,锻炼学生的合作能力。

二、准备知识

由于我们选的是题目二,所以为了明确分工,我们必须明白进程的定义。经过

查阅资料,我们得知进程必须具备以下四个要素:

1、有一段程序供其执行。这段程序不一定是进程专有,可以与其他进程共用。

2、有起码的“私有财产”,这就是进程专用的系统堆栈空间

3、有“户口”,这就是在内核中有一个task_struct 结构,操作系统称为“进程控制

块”。有了这个结构,进程才能成为内核调度的一个基本单位。同时,这个结构又

是进程的“财产登记卡”,记录着进程所占用的各项资源。

4、有独立的存储空间,意味着拥有专有的用户空间:进一步,还意味着除前述的

系统空间堆栈外,还有其专用的用户空间堆栈。系统为每个进程分配了一个

task_struct 结构,实际分配了两个连续的物理页面(共8192字节),其图如下: Struct task_struct (大约1K)

系统空间堆栈 (大约7KB )两个

连续

的物

理页

对这些基本的知识有了初步了解之后,我们按老师的建议,商量分工。如下:

四、 小组成员以及任务分配

1、王步月:分析进程的创建函数fork.c ,其中包含了get_pid 和do_fork get_pid,

写出代码分析结果,并画出流程图来表示相关函数之间的相互调用关系。所占工作

比例35%。

2、张少恒:分析进程的执行函数exec.c,其中包含了do_execve 。写出代码分析结

果,并画出流程图来表示相关函数之间的相互调用关系。所占工作比例35% 。

3、余波:分析进程的退出函数exit.c,其中包含了do_exit 、sys_wait4。写出代码

分析结果,并画出流程图来表示相关函数之间的相互调用关系。所占工作比例30% 。

五、各模块分析:

1、fork.c

一)、概述

进程大多数是由FORK 系统调用创建的.fork 能满足非常高效的生灭机制.除了

0进程等少数一,两个进程外,几乎所有的进程都是被另一个进程执行fork 系统调

用创建的.调用fork 的进程是父进程,由fork 创建的程是子进程.每个进程都有一

个父进程.而一个进程可以有多个子进程.父进程创建一个子进程完成一定的工作时,往往希望子进程结束后,还要把控制权交给父进程,因此子进程不应把父进程覆盖掉.fork系统调用创建子进程的做法,是把自己复制给子进程,也就是说,新创建的子进程是父进程的一个副本.继而子进程通过exec系统调用,用一个新的程序来覆盖子进程的内存空间,从而执行那个新程序.系统调用exit可以终止一个进程的执行,子进程也常常用exit系统调用来自我终止.子进程终止之后,进入僵死(zombie)状态,父进程可通过执行wait系统调用来实现与子进程的终止同步,接受子进程的返回状态和返回参数.

二)、代码分析

int do_fork(unsigned long clone_flags, unsigned long stack_start,

struct pt_regs *regs, unsigned long stack_size)

{

int retval;

unsigned long flags;

struct task_struct *p;

struct completion vfork;

if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))

return -EINV AL;

retval = -EPERM;/* 将retval赋值-ENOMEM,作为task_struct结构申请失败时的返回值*/

if (clone_flags & CLONE_PID) {/* 若clone_flags的位是置位的*/

/* 若调用do_fork的当前(父)进程不是idle进程(其pid=0)*/

if (current->pid)

goto fork_out;

}

retval = -ENOMEM;/*返回错误信息*/

p = alloc_task_struct(); /* 申请一个新的task_struct结构*/

if (!p)

goto fork_out;

*p = *current;/* 将当前(父)进程task_struct结构值赋给新创建的(子)进程*/ p->tux_info = NULL;

p->cpus_allowed_mask &= p->cpus_allowed;

retval = -EAGAIN;

/* 若子(新)进程所属的用户拥有的进程数已达到规定的限制值,

* 则跳转至bad_fork_fre */?

if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur

&& !capable(CAP_SYS_ADMIN)

&& !capable(CAP_SYS_RESOURCE))

goto bad_fork_free;

/* user->__count增一,user->processes(用户拥有的进程数)增一*/ atomic_inc(&p->user->__count);

atomic_inc(&p->user->processes);

/* 若系统进程数超过最大进程数则跳转至bad_fork_cleanup_count */

if (nr_threads >= max_threads)

goto bad_fork_cleanup_count;

get_exec_domain(p->exec_domain);/* 若正在执行的代码是符合iBCS2标准的程序,则增加相对应模块的引用数目*/

/* 若正在执行的代码属于全局执行文件结构格式则增加相对应模块的引用数目*/ if (p->binfmt && p->binfmt->module)

__MOD_INC_USE_COUNT(p->binfmt->module);

p->did_exec = 0;/* 将子进程标志为尚未执行*/

p->swappable = 0; /* 清标志,使内存页面不可换出*/

p->state = TASK_UNINTERRUPTIBLE;/* 将子进程的状态置为uninterruptible */

copy_flags(clone_flags, p);/* 将clone_flags略加修改写入p->flags */

p->pid = get_pid(clone_flags);/* 调用kernel/fork.c:get_pid()为子进程分配一个pid. 若是clone系统调用且

* clone_flags中CLONE_PID位为1,那么父子进程共享一个pid号;否则要分配给子进

* 程一个从未用过的pid */

if (p->pid == 0 && current->pid != 0)

goto bad_fork_cleanup;

/* 对运行队列接口初始化*/

INIT_LIST_HEAD(&p->run_list);

p->p_cptr = NULL;

init_waitqueue_head(&p->wait_chldexit);/* 初始化wait_chldexit等待队列wait_chldexit用于在进程结束时,或发出

* 系统调用wait4后,为了等待子进程结束,而将自己(父进程)睡眠在该队列上*/ p->vfork_done = NULL;

if (clone_flags & CLONE_VFORK) {

p->vfork_done = &vfork;

init_completion(&vfork);

}

spin_lock_init(&p->alloc_lock);

p->sigpending = 0;

init_sigpending(&p->pending);

p->it_real_value = p->it_virt_value = p->it_prof_value = 0;

p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0;

init_timer(&p->real_timer);

p->real_timer.data = (unsigned long) p;

p->leader = 0; /* session leadership doesn't inherit */

p->tty_old_pgrp = 0;

p->times.tms_utime = p->times.tms_stime = 0;

p->times.tms_cutime = p->times.tms_cstime = 0;

#ifdef CONFIG_SMP

{

int i;

/* ?? should we just memset this ?? */

for(i = 0; i < smp_num_cpus; i++)

p->per_cpu_utime[cpu_logical_map(i)] =

p->per_cpu_stime[cpu_logical_map(i)] = 0;

spin_lock_init(&p->sigmask_lock);

}

#endif

p->array = NULL;

p->lock_depth = -1; /* -1 = 没有锁*/

p->start_time = jiffies_64;/* 将当前的jiffies值作为子进程的创建时间*/

/* task_struct结构初始化完毕*/

retval = -ENOMEM;

/* copy all the process information */

if (copy_files(clone_flags, p))/* 复制所有的进程信息,根据clone_flags复制或共享父进程的打开文件表*/

goto bad_fork_cleanup;

if (copy_fs(clone_flags, p))/* 根据clone_flags复制或共享父进程的系统信息*/ goto bad_fork_cleanup_files;

if (copy_sighand(clone_flags, p))/* 根据clone_flags复制或共享父进程的信号处理句柄*/

goto bad_fork_cleanup_fs;

if (copy_mm(clone_flags, p))/* 根据clone_flags复制或共享父进程的存储管理信息*/

goto bad_fork_cleanup_sighand;

if (copy_namespace(clone_flags, p))/* 为子进程复制父进程系统空间堆栈*/ goto bad_fork_cleanup_mm;/* 若系统空间堆栈复制失败跳转至bad_fork_cleanup_mm */

retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);

if (retval)

goto bad_fork_cleanup_namespace;

p->semundo = NULL;

/* 将子进程task_struct结构的self_exec_id赋给parent_exec_id */ p->parent_exec_id = p->self_exec_id;

p->swappable = 1;/* 新进程已经完成初始化,可以换出内存,所以将p->swappable赋1 */

p->exit_signal = clone_flags & CSIGNAL;/* 设置系统强行退出时发出的信号*/

p->pdeath_signal = 0;/* 设置p->pdeath_signal */

/* * Share the timeslice between parent and child, thus the

* total amount of pending timeslices in the system doesnt change,

* resulting in more scheduling fairness.*/

__save_flags(flags);

__cli();

if (!current->time_slice)/* 将父进程的时间片减半*/

BUG();

p->time_slice = (current->time_slice + 1) >> 1;

p->first_time_slice = 1;

current->time_slice >>= 1;

p->sleep_timestamp = jiffies;

if (!current->time_slice) {

current->time_slice = 1;

scheduler_tick(0,0);

}

__restore_flags(flags);

retval = p->pid;/* 如果一切顺利,将子进程的pid作为返回值*/

p->tgid = retval;

INIT_LIST_HEAD(&p->thread_group);

/* Need tasklist lock for parent etc handling! */

write_lock_irq(&tasklist_lock);/* 给进程队列加锁*/

/* CLONE_PARENT re-uses the old parent */

p->p_opptr = current->p_opptr;

p->p_pptr = current->p_pptr;

if (!(clone_flags & CLONE_PARENT)) {

p->p_opptr = current;

if (!(p->ptrace & PT_PTRACED))

p->p_pptr = current;

}

if (clone_flags & CLONE_THREAD) {

p->tgid = current->tgid;

list_add(&p->thread_group, ¤t->thread_group);

}

SET_LINKS(p);/* 将子进程的task_struct结构链入进程队列*/

hash_pid(p);/* 将子进程的task_struct结构链入进程hash表*/

nr_threads++;/* 系统进程计数递增一*/

write_unlock_irq(&tasklist_lock);/* 解除对进程队列的封锁*/

if (p->ptrace & PT_PTRACED)

send_sig(SIGSTOP, p, 1);

wake_up_forked_process(p); /* 最后做这件事,唤醒子进程*/

++total_forks;/* total_forks增一*/

if (clone_flags & CLONE_VFORK)

wait_for_completion(&vfork);

else

current->need_resched = 1;

fork_out:/* 若是vfork()调用do_fork,发down信号*/

return retval;/* 退出do_fork(),返回retval值*/

bad_fork_cleanup_namespace:

exit_namespace(p);

bad_fork_cleanup_mm:

exit_mm(p);

bad_fork_cleanup_sighand:/* 处理子进程task_struct结构与信号处理相关的数据成员, 并删除信号队列中与子进程相

* 关的信号量*/

exit_sighand(p);

bad_fork_cleanup_fs:/* 处理子进程task_struct结构与文件系统信息相关的数据成员*/

exit_fs(p); /* blocking */

bad_fork_cleanup_files:/* 处理子进程task_struct结构与打开文件表相关的数据成员, 并释放子进程的files_struct

* 结构*/

exit_files(p); /* blocking */

bad_fork_cleanup:/* 若正在执行的代码是符合iBCS2标准的程序,则减少相对应模块的引用数目*/

put_exec_domain(p->exec_domain);

if (p->binfmt && p->binfmt->module)

__MOD_DEC_USE_COUNT(p->binfmt->module);

bad_fork_cleanup_count:/* 若正在执行的代码属于全局执行文件结构格式则减少相对应模块的引用数目*/

atomic_dec(&p->user->processes);

free_uid(p->user);/* 清除子进程在user队列中的信息*/

bad_fork_free:

free_task_struct(p);/* 释放子进程的task_struct结构*/

goto fork_out;

}

三)、程序框图如下:

开始

进程数是否达到最大出错处理

为子进程分配数据和内存

是否成功复制父进程的数据和堆栈到子

进程相应内存中

找到已空闲的进程表项并把父

进程的表项复制进去

输入子进程的内存映射到进程

为子进程选择一个进程号

告诉内核文件系统子进程的情

向内核报告子进程的内核映射

向父、子进程发送应答消息

并唤醒子进程

2、exec.c

一)、概述 进程通常是由父进程复制出来的(由fork ()或clone ())。假若子进

程只是父进程的“影子”,那么没有什么意义了。所以,执行一个新的可执

行程序才是创建进程的意义所在。在Linux 中,提供了一个系统调用execve

(),其内核入口是sys_execve ()。

二)、代码分析

asmlinkage int sys_execve(struct pt_regs regs )

{

int error;

char *filename;

filename=getname((char*)regs.ebx);

error=PTR_ERR(filename);

if(IS_ERR(filename))

goto out;

error=do_execve(filename,(char**)regs.ecx,(char** )regs.edx,®s);

if(error==0)

current->ptrace &= ~PT_DTRACE;

putname(filename);

out:

return error;

}

regs.ebx中的内容为应用程序中调用相应库函数时的第一个参数。getname()把regs.ebx所指向的字符串从用户空间拷贝到系统空间,在系统空间建立起一个副本。getname()通过dogetname()从用户空间拷贝字符串。

建立起一个可执行文件路径名的副本后,sys_execve()调用do_execve()以完成其主体部分的工作。

int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs) {

struct linux_binprm bprm;

//用于组织运行可执行文件所需的信息,通过此变量与负责处理其部

分工作的其他//函数通信;在do_execve返回时废弃;

struct file *file;

int retval;

int i;

file = open_exec(filename); //找到给定的可执行文件并打开;

retval = PTR_ERR(file);

if (IS_ERR(file))

return retval; //检测打开文件是否有错;

首先将给定路径名的可执行文件找到并打开,因而调用open_exec()来实现。函数返回一个file结构指针,代表读入可执行文件的上下文,保存在变量bprm中。代码开始定义了一个linux_binprm结构的变量bprm,用于将运行一个可执行文件所需的信息组织在一起。linux_binprm结构定义(在include/linux/binfmts.h中)如下:

struct linux_binprm{

char buf[BINPRM_BUF_SIZE];

struct page *page[MAX_ARG_PAGES];

unsigned long p; /* current top of mem */

int sh_bang;

struct file * file;

int e_uid, e_gid;

kernel_cap_t cap_inheritable, cap_permitted, cap_effective;

int argc, envc;

char * filename; /* Name of binary */

unsigned long loader, exec;

};

在do_execve()中,接下来的代码是:

bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);//初始化bprm结构的128k页表除去第一个argv[0]);

memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));

//将参数页面指针数组初始化为零;

bprm.file = file; //可执行文件的上下文;

bprm.filename = filename; //可执行文件的路径名;

bprm.sh_bang = 0; //可执行文件的性质;

bprm.loader = 0;

bprm.exec = 0;

if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) {

allow_write_access(file);

fput(file);

return bprm.argc;

} //根据argv数组计算非空指针个数并赋给argc成员;

if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) {

allow_write_access(file);

fput(file);

return bprm.envc;

} //统计环境变量个数并且赋值给envc的各个成员;

retval = prepare_binprm(&bprm); ////进行访问权限等内容的安全检测后,读入可执行文件前128字节;

if (retval < 0)

goto out;

变量bprm.sh_bang表示可执行文件的性质,此时初始化为0。其他两个变量也设置为0,因为现在还不知道文件性质。Bprm中定义了一个参数页面指针数组,通过memset()将此数组全设置为0;将bprm.p设置为这些页面的总和减去一个指针的大小,原因是argv[0]是可执行文件的路径名。函数count()对用户空间作为参数传过来的字符串指针数组argv[]和环境变量envp[]进行计数。

完成计数后,do_execve()调用prepare_binprm()对bprm中的其他成员准备信息。可执行文件的开头128个字节包含了文件属性的一些重要信息,并将这128个信息读入到bprm的缓冲区中。

retval = copy_strings_kernel(1, &bprm.filename, &bprm); //从系统空间中拷

贝可执行文件路径名;

if (retval < 0)

goto out;

bprm.exec = bprm.p;

retval = copy_strings(bprm.envc, envp, &bprm); //从用户空间拷贝环境信息;

if (retval < 0)

goto out;

retval = copy_strings(bprm.argc, argv, &bprm); //从用户空间拷贝参数信息;

if (retval < 0)

goto out;

由于可执行文件的路径名已经在系统空间中了,所以调用copy_strings_kernel ()拷贝到bprm中;其他的argv[]和envp[]还存在于用户空间,调用copy_strings ()拷贝到bprm中。

至此,可执行文件运行所需的所有信息都已组织到变量bprm中了,接下来的代码就是装入并运行了。

retval = search_binary_handler(&bprm,regs); //从formats中搜索能够识别的二进制处理程序并将其装入内核,以便执行;

if (retval >= 0) //找到能够识别的二进制处理程序;

/* execve success */

return retval;

out:

/* Something went wrong, return the inode and free the argument pages*/

allow_write_access(bprm.file);

if (bprm.file)

fput(bprm.file);

for (i = 0 ; i < MAX_ARG_PAGES ; i++) {

struct page * page = bprm.page[i];

if (page)

__free_page(page); //释放为参数和环境所分配的物理页面,并返回一个负数通知调用者调用失败;

}

return retval;

}

在此段代码中,最重要的的是函数search_binary_handler(),其中有两个for()循环。内层循环是每个formats队列(每个成员是认识并处理唯一一种文件格式的二进制处理程序)成员的循环,让每个成员调用自己的load_binary()去识别;若能识别则装入可执行文件并运行,返回一个正数或零;不能则返回一个负数。内层寻常结束后,如果返回的负数是

-ENOEXEC,表示所有的formats成员都不能识别此文件格式。如果内核支持动态安装模块,就根据目标文件的第2、3个字节生成一个binfmt模块名,通过request_module()试着将模块装入,以便外层for()循环在装入模块后再来一次内层循环。

三)、程序框图如下:

建立s t r u c t l i n u x _b i n p n n

用c o p y _s t r i n g s 来把参数和环境变量拷贝到新进程中

初始化新进程的参数和环境

继续填充b p r m 的a r g c 和a r g v

可执行文件是否存在

用s e a r c h _b i n a r y _h a n d l e r 来找到要执行的二进制处理程序

出错处理

3、exit.c

一)、概述 Exit.c 中核心是do-exit(),cpu 不会从do-exit()返回,中断服务程序不调用do-exit,in-interrupt()对此加以检查.因此在分析程序时,先浏览整段代码,然后开始分析do-exit()函数.在这个主函数中涉及到几个函数的调用,分别对这些函数进行分析,分析每个函数的功能和作用.

进程在结束退出前要释放所有系统资源.比如存储空间,已打开文件,工作目录,信号处理表等是通过函数_exit_mm(),

_exit_files(),_exit_fs(),_exit_sighand()来完成的. _exit_mm()存储空间的释放,调用mm_release()唤醒睡眠中的父进程,当前进程状态改成TASK_ZOMBIE,调用exit-notify(),通知父进程子进程已退出.cpu完成exit-notify()后,回到do-exit(),调用schedule().

Sys_wait4()函数中,参数pid为某一子进程的进程号,此函数的作用是等待子进程变成TASK_ZOMBIE.task-struct结构一开始就在当前进程的系统堆栈分配一个等待队列. 当task-struct 结构释放后,子进程就结束.在这个过程中,父进程正在wait4中等待.unhash_process()把子进程删除,把子进程的其他统计信息也合并入父进程.然后就调用task_release()释放子进程残存的资源.

二)、代码分析

NORET_TYPE void do_exit(long code)//将退出代码作为参数处理,在其类型前用到特殊符号NORET_TYPE

{

struct task_struct *tsk = current;

if (in_interrupt())

panic("Aiee, killing interrupt handler!");

if (!tsk->pid)

panic("Attempted to kill the idle task!");

if (tsk->pid == 1)

panic("Attempted to kill init!");

tsk->flags |= PF_EXITING;

del_timer_sync(&tsk->real_timer);

fake_volatile:

#ifdef CONFIG_BSD_PROCESS_ACCT

acct_process(code);

#endif

if (current->tux_info) {

#ifdef CONFIG_TUX_DEBUG

printk("Possibly unexpected TUX-thread exit(%ld) at %p?\n",

code, __builtin_return_address(0));

#endif

current->tux_exit();

}

__exit_mm(tsk);//释放分配给它的内存

lock_kernel();

sem_exit();//释放信号量和其他system VIPC结构

__exit_files(tsk);//释放分配给它的文件

__exit_fs(tsk);//释放文件系统的数据

exit_namespace(tsk);

exit_sighand(tsk);//释放信号量处理程序表

exit_thread();

if (current->leader)

disassociate_ctty(1);

put_exec_domain(tsk->exec_domain);

if (tsk->binfmt && tsk->binfmt->module)

__MOD_DEC_USE_COUNT(tsk->binfmt->mo dule);

tsk->exit_code = code;

exit_notify();//调用exit_notify,它会警告当前退出任务的祖先进程和其进程组中的所有成员该进程正在退出

schedule();/*调用schedule(),释放CPU,这对schedule()

的调用从来不返回因为它跳转到下一个进程的上下文,

不会再跳转回来,这是现在正在退出的进程最后一次

拥有CPU的机会*/

BUG();

asmlinkage long sys_exit(int error_code)

{

do_exit((error_code&0xff)<<8);

}

asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)/*sys_wait4有很多参数。pid是目标进程的PID.O和负值是特殊情况如果stat_addr非空,它就是所得子孙进程的退出状态应该拷贝到的地址

options是一些可能定义sys-wait4的操作的标志的集合。如果ru非空,

那么它就是所得子孙进程资源使用信息应该拷贝到的地址*/

{

int flag, retval;

DECLARE_WAITQUEUE(wait, current); struct task_struct *tsk;

if (options & ~(WNOHANG|WUNTRACED|__WNOTHREAD| __WCLONE|__WALL))//如果提供了无效选项sys_wait4就返回错误代码

return -EINV AL;

add_wait_queue(¤t->wait_chldexit,&wa it);//增加到等待队列中

repeat:

flag = 0;

current->state = TASK_INTERRUPTIBLE; read_lock(&tasklist_lock);

tsk = current;

do {

struct task_struct *p;

for (p = tsk->p_cptr ; p ; p = p->p_osptr)//循环遍历该进程的直接子进程

{

if (pid>0) {//根据pid参数的值筛选出不匹

配的PID

if (p->pid != pid)

continue;

} else if (!pid) {

if (p->pgrp != current->pgrp)

continue;

} else if (pid != -1) {

if (p->pgrp != -pid)

continue;

}

if (((p->exit_signal != SIGCHLD) ^ ((options & __WCLONE) != 0))

&& !(options & __WALL))

continue;

flag = 1;

switch (p->state) {

case TASK_STOPPED:

if (!p->exit_code)

continue;

if (!(options & WUNTRACED) && !(p->ptrace & PT_PTRACED))

continue;

read_unlock(&tasklist_lock);

retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;

if (!retval && stat_addr)

retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);

if (!retval) {

p->exit_code = 0;

retval = p->pid;

}

goto end_wait4;

case TASK_ZOMBIE://祖先进程正在等待一个已经结束了的进程

current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;

current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;

read_unlock(&tasklist_lock);

retval = ru ?

getrusage(p,

RUSAGE_BOTH, ru) :

0;/*其他的资源使用信息

被收集起来,子孙进程的退

出状态被传递到特定的地

址中*/

if (!retval && stat_addr)

retval = put_user(p->exit_code, stat_addr);

if (retval)

goto end_wait4;

retval = p->pid;//设置retval为当前

得到的死亡子孙进程的

PID;retval不会在改变

if (p->p_opptr != p->p_pptr) {/*如果

这个垂死进程的当前祖先进

程不是原来的祖先进程,进

程就会离开进程图表中的当

前位置,在其原始祖先的控

制下,重新安装自己,接着给

其祖先进程发送SIGCHLD

信号量,这样祖先进程就知

道其子孙进程已推出*/

write_lock_irq(&tasklist_lock);

REMOVE_LINKS(p);

p->p_pptr = p->p_opptr;

SET_LINKS(p);

do_notify_parent(p, SIGCHLD);

write_unlock_irq(&tasklist_lock);

} else

release_task(p);//调用release释放所得子孙进程的struct task_struct结构

goto end_wait4;//成功获取了子孙进程,sys_wait4返回到retval

default:/*执行前面的for循环,因为只有既没有停止运行,也不是僵进程

的进程才会执行default的情况*/ continue;

}

}

linux实验报告

实验一 实验名称:Linux 基本命令的使用 实验时间:2学时 实验目的:熟练使用Linux字符界面、窗口系统的常用命令。 实验内容 (一)Linux操作基础 1.重新启动linux或关机(poweroff,shutdown,reboot,init 0,init 6) 2.显示系统信息(uname),显示系统日期与时间,查看2014年日历(date,cal) ①uname:查看系统与内核相关信息 uname -asrmpi 参数: -a :所有系统相关的信息; -s: 系统内核名称; -r: 内核的版本; -m:本系统的硬件名称,如i686或x86_64; -p: CPU的类型,与-m类似,只是显示的是CPU的类型; -i :硬件的平台(ix86). ②date:显示日期的命令 ③cal:显示日历 单独cal:列出当前月份的日历 cal 2014:列出2014年的日历 cal 5 2014:列出2014年五月的目录 3.使用帮助命令(man,help) ①man:是manual(操作说明)的简写,是在线帮助系统 man后跟某个命令就会详细说明此命令,例如:man man就会详细说明man 这个命令的用法; ②help:也是帮助命令,一般会在命令后,例如:cd --help 就会列出cd命令的使用说明。 4.查看当前登陆用户列表(who),显示当前用户(whoami) ①who:显示目前已登录在系统上面的用户信息; ②whoami:查询当前系统账户 5.建立一个新用户mytest,设定密码(useradd,passwd) ①useradd mytest(建立新用户mytest);

LINUX实验报告

实验报告 ( 2014/ 2015 学年第一学期) 课程名称操作系统A 实验名称文件系统 实验时间2014 年12 月8 日指导单位计算机学院计算机科学与技术系 指导教师徐鹤 学生姓名王生荣班级学号B12040809 学院(系) 计算机学院专业软件工程

实验名称文件系统指导教师徐鹤 实验类型设计实验学时 2 实验时间2014.12.08 一、实验目的和要求 1. 学习LINUX系统下对文件进行操作的各种命令和图形化界面的使用方法。 2. 深入学习和掌握文件管理系统的基本原理和LINUX等操作系统下常用的系统调用,编写一个使用系统调用的例程。 3.实现一个文本文件的某信息的插入和删除 4.实现一个记录文件的某记录的插入和删除 二、实验环境(实验设备) Windows XP + VMWare + RedHat Linux 8

三、实验过程描述与结果分析 1. 目录/proc下与系统相关的文件和目录 (1) /proc/$pid/fd:这是一个目录,该进程($PID号码进程)每个打开的文件在该目录下有一个对应的文件。 例如:#ls /proc/851/fd 0 1 2 255 这表示,851号进程目前正在使用(已经打开的)文件有4个,它们的描述符分别是0、1、2、255。其中,0、1、2 依次分别是进程的标准输入、标准输出和标准错误输出设备。 (2)/proc/filesystems:该文件记录了可用的文件系统类型。 (3)/proc/mounts:该记录了当前被安装的文件系统信息 例如:#cat /proc/mount (4)/proc/$pid/maps:该文件记录了进程的映射内存区信息。 例如:#cat /proc/851/maps 2.常用命令讲解 ls 命令 用来查看用户有执行权限的任意目录中的文件列表,该命令有许多有趣的选项。例如: $ ls -liah * 22684 -rw-r--r-- 1 bluher users 952 Dec 28 18:43 .profile

浙江大学Linux程序设计实验报告

Linux程序设计实验报告1 ——操作系统基本命令使用 一、实验目的 1.通过对Emacs、vi、vim、gedit文本编辑器的使用,掌握在Linux环境下文本文件的编辑方法; 2.通过对常用命令mkdir、cp、cd、ls、mv、chmod、rm等文件命令的操作,掌握Linux操作系统中文件命令的用法。 二、实验任务与要求 1.emacs的使用,要求能新建、编辑、保存一个文本文件 2.vi或vim的使用,要求能新建、编辑、保存一个文本文件 3.gedit的使用,要求能新建、编辑、保存一个文本文件 4.掌握mkdir、cd命令的操作,要求能建立目录、进入与退出目录 5.掌握cp、ls、mv、chmod、rm命令的操作,要求能拷贝文件、新建文件、查看文件、文件重命名、删除文件等操作。 三、实验工具与准备 计算机PC机,Linux Redhat Fedora Core6操作系统 四、实验步骤与操作指导 任务1.学习emacs的使用,要求能新建、编辑、保存一个文本文件 (1)启动emacs (2)输入以下C程序 (3)保存文件为kk.c (4)用emacs打开文件kk.c (5)修改程序 (6)另存为文件aa.txt并退出。 任务2.vi或vim的使用,要求能新建、编辑、保存一个文本文件 (1)点击”应用程序”→ “附件”→“终端”,打开终端,在终端输入命令: [root@localhost root]#vi kk.c 按i键,进入插入状态。 (2)输入以下C程序 #include int main( ) {

printf(“Hello world!\n”); return 0; } 此时可以用Backspace、→、←、↑、↓键编辑文本。 (3)保存文件为kk.c 按Esc键,进入最后行状态,在最后行状态输入:wq保存文件,退出vi。 (4)用vi打开文件kk.c,输入命令: [root@localhost root]#vi kk.c (5)修改程序为: #include int main( ) { printf(" Hello world!\n"); printf("*****************\n"); return 0; } (6)按Esc键,进入最后行状态,在最后行状态输入:wq aa.txt保存文件,如图1所示,另存为文件aa.txt并退出vi。。 图1 程序编辑环境 任务3.gedit的使用,要求能新建、编辑、保存一个文本文件 (1)启动gedit,点击”应用程序”→ “附件”→“文本编辑器”,打开文本编辑器,如图所示。

2《Linux基础》实验报告 基本配置Linux

实验序号: 2 《Linux基础》 实验报告 实验名称:基本配置Linux操作系统 姓名: 学院:计算机学院 专业: 班级: 学号: 指导教师: 实验地址:N6-113 实验日期:2017.3.7

说明 一.排版要求 1.实验报告“文件名”按模板要求填写。 2.一级标题:顶格排版。汉字用宋体,阿拉伯数字用Times New Roman字 体,四号字体,加粗。 3.二级标题:顶格排版。汉字用宋体,阿拉伯数字用Times New Roman字 体,小四号字体,加粗。 4.三级标题:顶格排版。汉字用宋体,阿拉伯数字用Times New Roman字 体,五号字体。 5.正文:每段缩进量:2个汉字。两端对齐;汉字用宋体,阿拉伯数字用 Times New Roman字体,五号字体。 6.图形要求 (1)在正文中要有引用。 (2)要有图名,图名位于图的下方,汉字用宋体,阿拉伯数字用Times New Roman字体,五号字体。 (3)图和图名“居中”。 7.表格要求 (1)在正文中要有引用。 (2)要有表名,表名位于表的上方,汉字用宋体,阿拉伯数字用Times New Roman字体,五号字体。 (3)表和表名“居中”。 二.注意事项 1.复制、拷贝、抄袭者取消成绩。 2.没有安实验报告排版要求者不及格。

实验2基本配置Linux操作系统实验 【实验目的】 1.。。。。 2.。。。。 3.。。。。 4.思考: (1)Linux默认的系统超级管理员帐户是什么? (2)Linux的操作系统引导器是什么?它有哪几种的操作界面? (3)RHEL的支持哪几种X-Window图形管理器?默认是使用哪一种?(4)RHEL支持哪几种Shell?默认是使用哪一种? 【实验原理】 1.。。。 。。。 2.。。。 。。。 (1)。。。 。。。 (2)。。。 。。。 3.。。 【实验环境】 1.实验配置 本实验所需的软硬件配置如表1所示。 表1 实验配置 本实验的环境如图1所示。

linux操作系统实验报告要点

LINUX操作系统实验报告 姓名 班级学号 指导教师 2011 年05月16 日 实验一在LINUX下获取帮助、Shell实用功能 实验目的: 1、掌握字符界面下关机及重启的命令。 2、掌握LINUX下获取帮助信息的命令:man、help。 3、掌握LINUX中Shell的实用功能,命令行自动补全,命令历史记录,命令的排列、替

换与别名,管道及输入输出重定向。 实验内容: 1、使用shutdown命令设定在30分钟之后关闭计算机。 2、使用命令“cat /etc/cron.daliy”设置为别名named,然后再取消别名。 3、使用echo命令和输出重定向创建文本文件/root/nn,内容是hello,然后再使用追加重定向输入内容为word。 4、使用管道方式分页显示/var目录下的内容。 5、使用cat显示文件/etc/passwd和/etc/shadow,只有正确显示第一个文件时才显示第二个文件。 实验步骤及结果: 1.用shutdown命令安全关闭系统,先开机在图形界面中右击鼠标选中新建终端选项中输入 命令Shutdown -h 30 2、使用命令alias将/etc/cron.daliy文件设置为别名named,左边是要设置的名称右边是要更改的文件。查看目录下的内容,只要在终端输入命令即可。取消更改的名称用命令unalias 命令:在命令后输入要取消的名称,再输入名称。 3.输入命令将文件内容HELLO重定向创建文本文件/root/nn,然后用然后再使用追加重定向输入内容为word。步骤与输入内容HELLO一样,然后用命令显示文件的全部内容。 4.使用命令ls /etc显示/etc目录下的内容,命令是分页显示。“|”是管道符号,它可以将多个命令输出信息当作某个命令的输入。

操作系统-Linux课程实验报告材料

实验1.1、1.2 Linux Ubuntu的安装、创建新的虚拟机VMWare

实验1.3 Shell编程 1.实验目的与内容 通过本实验,了解Linux系统的shell机制,掌握简单的shell编程技巧。 编制简单的Shell程序,该程序在用户登录时自动执行,显示某些提示信息,如“Welcome to Linux”, 并在命令提示符中包含当前时间、当前目录和当前用户名等基本信息。 2.程序源代码清单 #include #include int main(){ printf("Hello Linux\n"); int pid; int state; int pfd[2]; pipe(pfd); if (fork()==0){ printf("In the grep progress\n"); dup2(pfd[0],0); close(pfd[0]); close(pfd[1]); execlp("grep","grep","sh",0); perror("exelp grep error");

} esle if(fork()==0){ printf("In the ps progress\n"); dup2(pfd[1],1); close(pfd[0]); close(pfd[1]); execlp("ps","ps","-ef",0); perror("execlp ps -ef"); } close(pfd[1]); close(pfd[0]); wait(&state); wait(&state); } 实验2.3 内核模块 实验步骤: (1).编写内核模块 文件中主要包含init_clock(),exit_clock(),read_clock()三个函数。其中init_clock(),exit_clock()负责将模块从系统中加载或卸载,以及增加或删除模块在/proc中的入口。read_clock()负责产生/proc/clock被读时的动作。(2).编译内核模块Makefile文件 # Makefile under 2.6.25

Linux文件系统实验报告

黄冈师学院 提高型实验报告 实验课题文件系统的设计与实现(实验类型:□综合性 设计性□应用性) 实验课程操作系统原理 实验时间2015-2016 第二学期 学生何正发 专业班级软件工程1401 学号07

成绩: 一、实验目的和要求 1、熟悉操作系统设计的过程,巩固操作系统的基本知识,加深对操作原理、功能及各种不同的存储管理方法理解与应用; 2、学会运用各种语言、软件开发新软件的基本方法; 3、增强实际应用能力和动手操作能力。 二、实验条件 Win7 /Windows 8.1/Linux等操作系统,装有java、C、C++、C#等语言工具的环境。 三、实验原理分析 可以选择最佳适应算法,按照从小到大的次序组成空闲区自由链,当用户作业或进程申请一个空闲区时,存储管理 程序从表头开始查找,当找到第一个満足要求的空闲区时,停止查找。如果该空闲区大于请求表中的请求长 度,将减去请求长度后的剩余空闲区部分留在可用表中。回收时,从作链中删去要回收的作业块,同时在空 闲链中插入该作业大小的空闲区,并按顺序排列 四、实验方案或步骤 1、应用环境、需求分析 本模拟系统主要针对文件的管理和操作名主要有:创建用户、文件、文件夹,读文件,写文件,执行文件,关闭文件,删除用户、文件夹、文件的功能。 创建用户、文件、文件夹:在对系统发出操作命令之前必须先登录用户,然而登录之前必须创建该用户。在创建完后,可通过登录用户来创建文件和文件夹。在创建文件时可设置文件的属性和输入文件的容。 读文件:读取任何已创建的只读或读写文件的容;如果所要读的文件不是可读文件时,系统会显示该文件不可读;如果所读文件不存在,系统会显示文件不存在。 写文件用户可写或重写读写文件中的容,并保存文件中的重写容,以供下次读取;当所要写的文件不是可写的文件时,系统会显示该文件不可写;当所要写的文件并不存在时,系统会显示该文件不存在。

Linux常用命令实验报告

实验二 姓名:陈辉龙学号:201407010201 班级:14计科(1)一.实验目的: 掌握Linux常见命令,为今后的实验打下良好的基础。 二.实验内容 1.新建用户为chenhuilong,配置密码为passwd: 2.切换到chenhuilong用户,并在/home/chenhuilong目录下新建文件夹dir: 3.在文件夹dir下新建文件hello(内容为"printf hello world!"),并将其拷贝至/home/user目录: 4.统计/home/user目录下文件的个数,包括子目录里的首字符为-的普通文件:

5.统计/home下目录的个数,包括子目录里的目录: 6.显示/home/user目录下名为hello的文件的行数、字数以及字符数(使用输入重定向): 7.将上步的结果输出重定向到名为cnt_hello的文件: 8.删除/home/user目录下的hello文件: 9.进入/home/user/dir文件夹,将hello文件属性变为-rwxrw-r--(使用符号标记方式),并为hello文件在/home/user目录下建立软链接,链接文件名为link_hello:

10.查看/home/user/dir/hello文件的详细信息: 11.切换至根目录下查找hello文件: 12.打包home/user/dir/hello文件,并进行压缩,然后再进行解压缩解包: 13.退出user用户,删除/home/user文件夹:

14.将文件夹/home的所有者改为user用户,并删除user用户: 三.实验总结: 本实验旨在熟悉Unix的常用命令,实验较简单,操作起来还算顺利,做了一遍感觉还不是很熟悉,因此做了两遍,第二遍就很得心顺手。通过这次实验,熟悉了一些常用的命令操作,为以后的学习打下坚实的基础,提高自己的动手能力。

linux应用程序开发实验报告3

实验报告 学生姓名:白迪学生学号:222014********* 日期:2016年11月15日与11月29日 院(系):计算机与信息科学学院软件学院专业(班级):网络工程实验题目:终端驱动属性编程及利用属性特性的应用程序编程 一. 实验目的 掌握终端驱动属性的特殊功能,掌握终端驱动属性的显示与修改方法编程,掌握利用终端驱动属性的特属性编写需要特殊功能的应用程序技巧。 二. 实验原理 三. 实验器材 安装有Windows操作系统PC机一台,实验环境为LINUX虚拟机(包含gcc 与gdb). 四. 实验分析与设计 补全终端设备属性位与控制字符的信息输出: Main函数

Flags的补充 显示flags函数

Setecho函数,设置echo的状态位Echostate函数。显示echo状态 Setecho函数

忽略特殊的一些按键,CTRL+C、CTRL+\,不能一直阻塞等待键盘输入,设置等待一定的时间的非阻塞。 预处理 Main函数 Tty—mode set_nodelay_mode()//没阻塞 set_nobuf_noecho_mode()//没回显,没缓冲

Getresponse() 中断处理函数 五. 实验结果 属性位与控制字符的信息输出

stty控制字符的修改功能,setecho 忽略特殊的一些按键,CTRL+C、CTRL+\,不能一直阻塞等待键盘输入,设置等待一定的时间的非阻塞。当按下的键不是y或者n就显示f。 六. 实验心得 通过本次试验中对终端文件更加的了解了,还学会了对中断文件的一些基本的设置,前面的实验做起来就是一些验证比较简单,但是收获很大,最后一个做的时候先看过书后,自己编写的,调试过程中总是出错,做到最后跟书上的代码比较发现自己的代码跟书上比差了好远,修改了很多,自己用的是Redhat5,cc—

实验一 Linux基本操作实验报告

实验一Linux基本操作 一.实验目的: 1. 二.实验环境: 虚拟机+Red Hat Enterprise Server 5.0 三.实验内容: 根据以下的文字提示,调用相应的命令来完成,记录相应的运行结果。一)用户和组基本操作 1.添加一个user01用户,家目录为/home/sub2,并设置密码 2.添加一个group1 组 3.将user01用户添加到group1组中 4.修改group1组名称为group2 5.修改user01的家目录为/home/user01 6.判断/etc/password这个目录是否包含user01这个用户 7.修改user01的shell为/bin/tcsh 8.添加一个group3组,把user01和root用户都添加到该组

https://www.doczj.com/doc/434941103.html,er01用户从group2组切换到group3组 10.设置user01的密码在2012-5-20过期 11.把/home/user01目录所属的组修改为group3 12.删除user01帐号 13.查看内核版本号 二)进程管理 1.运行cat命令:vi test,输入若干字符如this is a example,挂起vi进程 2.显示当前所有作业 3.将vi进程调度到前台运行

4.将vi进程调度到后台并分别用kill/pkill/killall命令结束该该进程。 三)磁盘管理 1.通过fdisk 将为硬盘增加一个分区(主分区或者逻辑分区)。 2.并格式化ext3系统,

3.检测分区是否有坏道 4.检测分区的完整性 5.加载分区到/mnt目录(或者其他分区)下,并拷贝一些文件到该目录下 6.(选做)为test用户设置磁盘配额(软限制和硬限制参数自行设定) 7.退出/mnt目录后卸载该分区 8.用du查看/usr目录的大小

linux编程实验报告

linux编程实验报告 篇一:Linux程序设计实验报告 《Linux程序设计》 实验报告 安徽工业大学计算机学院 XX年6月 1 实验一 Linux基本 命令的使用 1、实验目的 学习和掌握Linux的基本命令。 2、实验内容和步骤 步骤1:以user_login用户身份并使用telnet登录Linux服务器,按照提示创建自己的账户和口令。 步骤 2:使用新创建的用户账户和口令登录Linux系统,察看登录后的界面。 步骤3:使用pwd命令察看当前的工作目录,然后用ls 命令查看当前目录下的内容,尝试使用-a,-l,-F,-A,-lF等不同选项并比较不同之处。 步骤4:在当前目录下建立一个名为test的新目录,然后将工作目录切换到test下,尝试将/etc目录下的文件passwd拷贝到该目录下(cp 源文件目的目录)。察看当前目录下的passwd文件的属主和文件权限。

2 步骤5:尝试向当前目录下的passwd文件和/etc/passwd 文件分别写入一些新内容(可使用echo “字符串” >>文件的命令),看看操作能否成功,如果不能成功,请说明原因。用cat命令浏览文件password的内容,用more命令进行浏览翻页操作,再用less命令浏览文件的内容。比较这几个命令的不同之处 步骤6:用ls命令查看test下文件的权限,用mv命令更改文件password的文件名为test.txt,尝试用chown和chgrp更改文件的属主为root、组为root,看看能否成功,不成功,请说明原因。尝试用chomd将文件权限为“-rw-------”。看看能否成功,不成功,请说明原因。 3 步骤7:用rm命令删除test目录下的所有文件,再用rmdir命令删除test目录。(想一想有没有一条命令将目录及目录下的所有文件删除,写出这条命令) 步骤8:使用ps命令查看当前系统内的进程,并利用man命令获取ps命令的参数,写出获取当前终端进程执行情况的ps命令。 4 步骤9:使用df命令查看当前系统已安装的文件系统的空间使用情况,记录结果。

Linux实验报告_大三上

实验三普通文件和目录编程 1.编写程序mycp.c,实现从命令行读入文件的复制功能,用原始文件系统调用。 实验流程图: 判断输入main 函数参数个数 argc argc!=3 no Exit(0) fd1=Open(argv[1],O_RDONLY); fd2=open(argv[2],O_RDWR|O_CREA T); 1 read(fd1,buf,bufsize); write(fd2,buf,i); if(i!=bufsize) break;

实验程序代码: //mycp.c #include #include #include #include #define bufsize 5 int main(int argc,char * argv[]) { int fd1,fd2; int i; char buf[bufsize]; if(argc!=3) { printf("argument error\n"); exit(1); } fd1=open(argv[1],O_RDONL Y); if(fd1==-1) { printf("file %s can not opened\n",argv[1]); exit(1); } fd2=open(argv[2],O_RDWR|O_CREAT); if(fd2==-1) { printf("Can not open file %s\n",argv[2]); exit(1); } while(1) { i=read(fd1,buf,bufsize); write(fd2,buf,i); if(i!=bufsize) break; }

Linux实验报告

Linux实验 一、实验目的 1. 了解Linux基本使用方法; 2. 掌握Linux基本设置方式; 3. 掌握Linux基本操作命令使用。 二、内容要求 1. 了解进程管理、文件管理与内存管理 2.掌握系统设置文件与命令 3. 熟练使用系统操作与维护命令 4. 熟练使用系统操作与维护命令 三、实验原理 Linux 系统常用命令格式: command [option] [argument1] [argument2] ... 其中option以“-”开始,多个option可用一个“-”连起来,如 “ls-l -a”与“ls-la”的效果是一样的。根据命令的不同,参数 分为可选的或必须的;所有的命令从标准输入接受输入,输出结果显示在 标准输出,而错误信息则显示在标准错误输出设备。可使用重定向功能对这 些设备进行重定向。如: ls –lh > a.txt 命令在正常执行结果后返回一个0值,如果命令出错可未完全完成,则返回 一个非零值(在shell中可用变量$?查看)。在shell script中可用此返 回值作为控制逻辑的一部分。 DSL命令操作: 帮助命令: man 获取相关命令的帮助信息 例如:man dir 可以获取关于dir的使用信息。 info 获取相关命令的详细使用方法 例如:info info 可以获取如何使用info的详细信息。 基本操作: echo 显示字符串 pwd 显示当前工作目录 ls 查看当前文件夹内容 ls -a 查看当前文件夹内容(包括隐藏项) ls -l 查看当前文件夹内容(详细) ls / 查看根目录内容 cd / 移动到根目录

pwd 显示当前工作目录 ls -al 查看根目录文件夹内容(详细情况并包括隐藏项) cd /home/dsl 回到“家”目录 pwd 显示当前工作目录 df -h 显示剩余磁盘空间,参数“-h”表示适合人读取(human readable) du -h 显示文件夹(及子文件夹)所占空间 mkdir fd0 在当前目录下创建目录fd0 touch a.txt 创建一个空文件a.txt ls / -lh > a.txt 利用重定向功能将根目录中的内容写入a.txt。 cat a.txt 显示a.txt内容 wc a.txt 显示a.txt的行数,字数与字节数 find / -name *conf 在根目录下(包括子目录)查找以conf结尾的文件 sudo mount /dev/fd0 fd0 将软盘镜像挂载到目录fd0上 cd fd0 进入软盘镜像所挂载的目录 ls -lh 查看软盘镜像中的文件 cd .. “..”表示进入上一层目录 gzip a.txt 使用gzip压缩a.txt ls -lh 查看当前文件夹 sudo cp a.txt.gz fd0/ 将a.txt复制到fd0目录下,即将其复制到软盘镜像中 sudo mv fd0/a.txt.gz ./ 将a.txt移动到当前目录下,“.”表示当前目录 sudo umount /dev/fd0 将软盘镜像卸载 ls fd0 显示fd0 目录内容 gzip -d a.txt.gz 解压缩a.txt.gz ls -lh 查看当前文件夹 权限管理: 假设当前处于/home/dsl 目录下,且有a.txt(文件)与fd0(目录),当前用户名为dsl。 sudo cat /etc/passwd 用户 sudo cat /etc/shadow 密码 sudo cat /etc/group 组 users 查看当前登录用户 sudo chmod -x fd0 更改文件夹权限 ls fd0 fd0不能被执行,则意味着无法打开! sudo chmod +x fd0 更改文件夹权限 ls fd0 fd0能被打开 sudo chown root fd0 更改目录fd0的所有者 ls -lh 注意看fd0目录的属性 sudo chown dsl:root fd0 更改目录fd0的所有者为dsl,所属组为root ls -lh 注意看fd0目录的属性 chmod a-r a.txt 现在a.txt不具有“读”权限,不能被读取

linux基础实验报告含代码

Linux基础实验

目录 实验一 (3) 实验二 (4) 实验三 (6) 实验四 (9) 实验五 (11) 实验六 (14) 实验七 (16)

实验一螺旋矩阵 一、实验目的 1.熟悉linux下c程序编写。 2.掌握Makefile编写方法。 二、实验环境和工具 Red Hat Linux 三、实验流程 1.编写螺旋矩阵程序 2.编写Makefile文件 四、实验结果 五、实验心得 通过这次实验,我熟悉了linux下c语言程序的编写,掌握了vi的一些常用操作,学会了使用gcc命令和makefile文件两种方法编译程序。同时也使我熟悉了linux里常用命令的使 用,还有,学会了挂载U盘的方法,可以很方便的往linux里传送文件。 六、关键代码 Makefile 文件 CC=gcc EXEC=juzhen OBJS=juzhen.o all:$(EXEC) $(EXEC):$(OBJS) $(CC) -o $@ $(OBJS) clean: -rm -f $(EXEC) $(OBJS)

实验二添加、删除用户 一、实验目的 1.设计一个shell程序,分组批量添加用户。 2.再设计一个批量删除用户的shell程序。 二、实验环境和工具 Red Hat Linux 三、实验流程 1.编写shell程序 2.修改文件权限 chmod +x addusers 3.运行脚本 四、实验结果 添加用户: 删除用户:

五、实验心得 通过本次实验,我了解了shell脚本编程的方法和其语法规则。掌握了使用shell脚本程序添加、删除用户的方法。需要注意的是:shell脚本直接用vi编写,要特别注意空格。 六、关键代码 添加用户: 删除用户:

Linux实验报告

Linux程序设计 实验报告 姓名:杨帆 班级:计1242 学号: 121842284 专业:计算机科学与技术指导老师:赵帼英

实验一 Linux系统安装与启动(选做实验) 一、实验目的(通过实践及查阅资料完成如下实验) 1.掌握虚拟机的配置过程。 2.掌握Linux系统的安装过程和简单配置方法。 3.掌握与Linux相关的多操作系统的安装方法。 4.掌握Linux系统的启动、关闭步骤。 5.了解Linux文件系统和目录结构。 二、实验内容 1.安装虚拟机软件(如VMware、Virtualbox)。 2.在虚拟机软件中安装Linux操作系统(如Fedora、Ubuntu、redhat等)。 3.配置Linux系统运行环境。 4.正确地启动、关闭系统。 三、实验步骤 1 .安装虚拟机软件(VMware Workstation 7.0) 。 2.在虚拟机软件中新建Linux虚拟机 2.1设置内存大小(建议大于256MB) 2.2设置虚拟硬盘大小(建议大于8GB) 2.3设置虚拟光驱(虚拟方式,镜像文件) 2.4设置网络连接模式(建议采用桥接方式) 2.5设置共享目录(建议英文目录名) 1.在Linux虚拟机中安装Linux操作系统(fedora10 )。 3.1选择安装界面 3.2检测安装截介质(建议跳过) 3.3安装过程中的语言、键盘选择 3.4磁盘分区(采用自动分区,总大小与2.2相匹配) 3.5引导程序选择(采用GRUB) 3.6注意事项(禁用SELinux) 2.通过相关命令实现对操作系统的登录、退出与关机 3.使用文件浏览器査看Linux操作系统目录结构

Linux实验报告

燕山大学 Linux技术上机实验指导

实验一Linux系统安装与简单配置 一、实验目的 1.掌握Linux系统安装的分区准备。 2.掌握Linux系统的安装步骤。 3.掌握Linux系统分区的挂载和卸载。 4.掌握Linux系统的启动和关闭操作。 二、实验内容 1.安装VMware虚拟机,设置光盘驱动器,为Linux系统安装做准备。2.在虚拟机下安装Linux操作系统(如Ubuntu桌面版本)。 3.配置Linux系统运行环境。 4.利用空闲分区创建新的Linux系统分区。 5.将新的Linux系统分区挂载到系统中;卸载新挂载的分区,重新挂载到目录树中的其他位置。 三、主要的实验步骤 1.制定安装系统的分区计划。 2.配置光驱引导镜像文件iso,启动系统,开始安装过程。 3.根据安装计划,对磁盘空间进行分区设置。 4.根据系统安装指导,完成Linux系统的安装过程。 5.安装成功后,退出系统,重新启动虚拟机,登陆Linux操作系统。6.对Linux系统进行配置,如网络设备等。 7.利用磁盘使用工具和mount,将新创建的Linux系统分区挂载到系统中。将新挂载的分区卸载,并重新挂载到目录树的其他位置。

实验二Linux常用命令使用 一、实验目的 1.掌握Linux一般命令格式。 2.掌握有关文件和目录操作的常用命令。 3.熟练使用man命令。 二、实验内容 1.熟悉cd、date、pwd、cal、who、echo、clear、passwd等常用命令。2.在用户主目录下对文件进行操作:复制一个文件、显示文件内容、查找指定内容、排序、文件比较、文件删除等。 3.对目录进行管理:创建和删除子目录、改变和显示工作目录、列出和更改文件权限、链接文件等。 4.利用man命令显示date、echo等命令的手册页。 5.显示系统中的进程信息。 三、主要实验步骤 1.登陆进入系统,修改个人密码。 2.使用简单命令:date、cal、who、echo、clear等,了解Linux命令格式。

Linux操作系统实验实验报告

实验1:安装Linux系统 【实验目的和要求】:安装Linux系统,掌握操作系统的系统配置,建立应用环境的过程。 【实验内容】: 1、首先在windows系统中安装虚拟机。在网上找到VMware Worksttion Pro版 本,确定安装目录。一直下一步,不需要太多的说明。 2、 图为安装完成后的界面。 3、然后在阿里巴巴开源镜像网站下载centos系统镜像,然后虚拟机创建新的虚 拟机,

进行一些简单的虚拟机设置,设置了网络链接nat模式等等。 安装完成后的界面

实验2:Linux下c语言开发 【实验目的】:学会和掌握用c语言开发一个应用程序的全过程,包括,编译,调试等等。 【实验步骤】:首先在系统中查看是否已经安装有gcc,输入查看命令发现没有,于是需要安装gcc。在centos系统中可以使用比较简便的yum命令。在之前已经配置好了yum源。直接输入yum install gcc。回车自动安装程序和需要的依赖包。 因为虚拟机中和电脑很多地方切换使用不方便,所以安装了xshell软件。图为xshell中的截图。

安装完毕。然后使用vi或者vim编写hello.c 运行,在屏幕上打印出hello,world。

实验3:进程创建 【实验目的和要求】 1. 了解进程的概念及意义;2. 了解子进程和父进程 3. 掌握创建进程的方法。 【实验内容】 1. 子进程和父进程的创建; 2.编写附件中的程序实例 【实验步骤】一1、打开终端,输入命令gedit 1_fork.c,在1_fork.c 文件中输入1_fork.bmp 中的代码; 2、输入命令gcc 1_fork.c -o 1_fork,回车后显示无错误; 3、输入命令:./1_fork 运行程序。 二、1、打开终端,输入命令gedit 2_vfork.c,在2_vfork.c 文件中输入2_vfork.bmp 中的代码; 2、输入命令gcc 2_vfork.c -o 2_vfork,回车后显示无错误: 3、输入命令:./2_vfork 运行程序。 从上面可以看到两次的运行结果不一样。我们知道write 函数是不带缓存的。因为在fork 之前调用write,所以其数据写到标准输出一次。但是,标准I/O 库是带缓存的。如果标准输出连到终端设备,则它是行缓存的,否则它是全缓存的。当以交互方式运行该程序时,只得到printf 输出的行一次,其原因是标准输出缓存由新行符刷新。但是当将标准输出重新定向到一个文件时,却得到printf 输出行两次。其原因是,在fork 之前调用了printf 一次,当调用fork 时,该行数据仍在缓存中,然后在父进程数据空间复制到子进程中时,该缓存数据 也被复制到子进程中。于是那时父、子进程各自有了带该行内容的缓存。在exit 之前的第二个printf 将其数据添加到现存的缓存中。当每个进程终止时,缓存中的内容被写到相应文件中。

Linux实验报告(2)

Linux 实验报告姓名 黄芳恺 班级软件工程114 学号119074258 指导教师阮越

目录 实验一 Linux基本命令的使用 实验二简单Shell程序设计 实验三 Linux下简单C程序设计与文件操作实验四 Linux下进程操作与进程间通信 实验五 Linux线程的使用 实验六 Linux进程间的IPC 实验七 Linux下访问Mysql数据库 实验八 Linux下网络编程 练习题: grep、 bash、生产者消费者

实验一 Linux基本命令的使用 1、实验目的 学习和掌握 Linux 的基本命令。 2、实验内容和步骤 步骤 1:以user_login用户身份并使用telnet登录Linux服务器,按照提示创建自己的账户和口令。 步骤 2 :使用新创建的用户账户和口令登录Linux系统,察看登录后的界面。 步骤 3:使用 pwd 命令察看当前的工作目录,然后用ls命令查看当前目录下的内容,尝试使用 -a,-l,-F,-A,-lF等不同选项并比较不同之处。 -a do not ignore entries starting with -I, --ignore=PATTERN do not list implied entries matching shell PATTERN -l use a long listing format -F, --classify append indicator (one of */=>@|) to entries -A, --almost-all do not list implied . and .. -lF ignore file

Linux实验报告(2)

Linux实验报告 姓名黄芳恺_____________ 班级软件工程114 学号119074258 指导教师阮越

目录 实验一Linux基本命令的使用 实验二简单Shell程序设计实验三Linux下简单C程序设计与文件操作 实验四Linux下进程操作与进程间通信实验五Linux线程的使用 实验六Linux进程间的IPC 实验七Linux下访问Mysql数据库 实验八Linux下网络编程练习题:grep bash生产者消费者

实验一 Linux 基本命令的使用 1、 实验目的 学习和掌握Linux 的基本命令。 2、 实验内容和步骤 步骤1:以user_login 用户身份并使用tel net 登录Lin ux 服务器,按照提示创建自己的账 户和口令。 步骤2 :使用新创建的用户账户和口令登录 Linux 系统,察看登录后的界面。 [max@localhost Documents]f pwd /home/max/Documents [max@localhost Documents]f 步骤3:使用pwd 命令察看当前的工作目录,然后用 使用-a,-l,-F,-A,-IF 等不同选项并比较不同之处。 -a do no t ig nore en tries start ing with [max^localhost Documents]$ Is -a, ?.* VirtualBox Dropped Files -I, --ig nore=PATTERN do not list implied en tries matchi ng shell PATTERN -l use a long listi ng format [max@localhost Documents]f Is -I total 4 drwx -------- ? 3 max max 4096 Apr 27 16:45 VirtualBox Dropped Files appe nd in dicator (one of */=>@|) to en tries [max^localhost Desktop^ Is - F a.c c~ 台?out* firefox ?d 包gnoaedesktop* -A, --almost-all do not list implied . and .. [max@lacailhost Docjments]J Is -A VirtualBox Dropped Files -lF ignore file [maxglacBlhost Deskt 叩]$ Is -IF total 24 -rw- rw- r--. L max max 145 May 22 22:32 a. c -rw- rw- r- - * 1 max max 143 May 22 22:32 a. c- -rwx rwx r ■ x . 1 max max 6707 May 22 22:32 OUt* 1 rwx rwx rwx. 1 max max 39 Hay 18 19:07 firefox .desktop -> /u5r/share/applicatio ns/firefox. desktop -rwxrwxr^x. 1 max max 6333 Apr 27 22:40 eriindl■( iesktop* Is 命令查看当前目录下的内容,尝试 -F, --classify

linux编程SHELL编程实验报告

Linux编程课程设计报告题目: Linux Shell编程 专业 学号姓名 指导教师 日期

题目:Linux Shell编程 一、设计目的和任务 实验目的:1.熟悉Shell环境和Shell的执行 2.熟悉Shell的基本语法和语句 3.了解Shell程序的调试方法 实验内容:1.编写Shell程序 2.调试和执行Shell程序 二、设计原理 Linux是一种开放源码、能够免费使用及自由传播的类似于UNIX操作系统。它可运行于各种平台之上。因为它不但具有UNIX系统的良好性能(如稳定性、安全性),同由于其具有开源和免费的特点,也越来越广泛地应用于各种嵌入式系统中。 Shell是用户和Linux操作系统内核程序间的一个借口。Shell既是命令解释器,有事一种编程语言。作为命令解释器,Shell为用户使用Linux操作系统提供丰富的工具界面。若用户输入命令,Shell负责解释执行该命令并向用户返回结果。作为编程语言,它利用自身的语言结构将工具命令组合起来提供更复杂的功能。 三、实验环境和总体设计 一台 2.安装虚拟机版的Linux操作系统 四、详细设计步骤 1.打开vmware软件,启动Linux系统 2.用root用户名和密码登入系统中 3.将某目录下面所有的文件名后面加上所有者的名字,如的所有者为owner,修改后为a[owner].txt文件。 基本要求: ①使用方法为usage:程序名称目录名称 若没有“目录名称”参数,则修改当前目录下文件名称 ②对目录中的子目录不做变化。 ③ 给出实验结果。 五、结果测试与分析 1. 进入root模式创建2618文件夹和文件 2.编写shell程序

相关主题
文本预览
相关文档 最新文档