UNIX基础知识
1.1引言
所有的操作系统都需要向它们运行的程序提供执行新程序、打开文件、读文件、分配存储器及获得当前时间等各种服务
1.2unix体系结构
相邻的层之间,外层可以调用内层的接口
1.3登陆shell
root:x:0:0:root:/root:/bin/bash
...
登录名:加密口令:用户ID:组ID:注释:家目录:shell
1.4文件和目录
-
[root@node3 apue.2e]# cat fig1.3.c
-
#include "apue.h"
-
#include <dirent.h>
-
-
int
-
main(int argc, char *argv[])
-
{
-
DIR *dp;
-
struct dirent *dirp;
-
-
if (argc != 2) #argc命令行参数的个数
-
err_quit("usage: ls directory_name");
-
-
if ((dp = opendir(argv[1])) == NULL) #argv数组,用来存放命令行参数;opendir打开一个目录
-
err_sys("can't open %s", argv[1]); #err_sys & err_quit函数的实现在error.c中
-
while ((dirp = readdir(dp)) != NULL) #readdir读opendir打开的目录下面的每个目录项
-
printf("%s\n", dirp->d_name);
-
-
closedir(dp);
-
exit(0);
-
}
-
[root@node3 apue.2e]# gcc fig1.3.c
-
[root@node3 apue.2e]# ./a.out /root/
-
.ssh
-
.cshrc
-
.esd_auth
-
apue.2e
-
src.2e.tar.gz
-
.viminfo
-
.bash_logout
-
.gnome2_private
-
.....
工作目录: 当前目录 (pwd查看)
起始目录: 当前用户的家目录
1.5输入和输出
-
文件描述符:非负数,内核用它来标识一个特定进程正在访问的文件。
标准出错
-
不带缓冲的I/O的函数:open、read、write、lseek、close(系统不用缓冲,用户使用的时候就要自己加上缓冲)
-
[root@node3 apue.2e]# cat fig1.4
-
#include "apue.h"
-
-
#define BUFFSIZE 4096
-
-
int
-
main(void)
-
{
-
int n;
-
char buf[BUFFSIZE]; #缓冲区的大小
-
-
while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0) # 将STDIN_FILENO的数据读到buf中,大小为BUFFSIZE
-
if (write(STDOUT_FILENO, buf, n) != n)
-
err_sys("write error");
-
-
if (n < 0)
-
err_sys("read error");
-
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.4 fig1.4.c
-
[root@node3 apue.2e]# gcc fig1.4.c
-
[root@node3 apue.2e]# ./a.out
-
hello world
-
hello world
-
bye
-
bye
-
-
[root@node3 apue.2e]#
注释:
STDIN_FILENO 标准输入的文件描述符
STDOUT_FILENO 标准输出的文件描述符
STDERR_FILENO 标准出错的文件描述符
这三个文件描述符都定义在unistd.h ,值分别为0、1、2
[root@node3 apue.2e]# cat /usr/include/unistd.h
-
带缓冲的I/O的函数:getc、putc、gets、puts、printf(系统自己带缓冲了,用户使用该函数的时候就不用考虑了)
-
[root@node3 apue.2e]# cat fig1.5
-
#include "apue.h"
-
-
int
-
main(void)
-
{
-
int c;
-
-
while ((c = getc(stdin)) != EOF) #getc一次读1个字符
-
if (putc(c, stdout) == EOF) #putc将字符写到标准输出
-
err_sys("output error");
-
-
if (ferror(stdin))
-
err_sys("input error");
-
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.5 fig1.5.c
-
[root@node3 apue.2e]# gcc fig1.5.c
-
[root@node3 apue.2e]# ./a.out
-
hello world
-
hello world
-
bye
-
bye
-
-
[root@node3 apue.2e]#
1.6程序和进程
程序:存放在磁盘里的可执行文件
进程:运行起来的可执行程序
进程ID:每个进程的唯一数字标识符
-
[root@node3 apue.2e]# cat fig1.6
-
#include "apue.h"
-
-
int
-
main(void)
-
{
-
printf("hello world from process ID %d\n", getpid());
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.6 fig1.6.c
-
[root@node3 apue.2e]# gcc fig1.6.c
-
[root@node3 apue.2e]# ./a.out
-
hello world from process ID 406
-
[root@node3 apue.2e]# ./a.out
-
hello world from process ID 407
进程控制的主要函数:fork 、exec家族、waitpid
-
[root@node3 apue.2e]# cat fig1.7
-
#include "apue.h"
-
#include <sys/wait.h>
-
-
int
-
main(void)
-
{
-
char buf[MAXLINE]; /* from apue.h */
-
pid_t pid;
-
int status;
-
-
printf("%% "); /* print prompt (printf requires %% to print %) */
-
while (fgets(buf, MAXLINE, stdin) != NULL) {
-
if (buf[strlen(buf) - 1] == '\n')
-
buf[strlen(buf) - 1] = 0; /* replace newline with null */
-
-
if ((pid = fork()) < 0) {
-
err_sys("fork error");
-
} else if (pid == 0) { /* child */
-
execlp(buf, buf, (char *)0); #子进程调用execlp执行从标准输入读入的命令
-
err_ret("couldn't execute: %s", buf);
-
exit(127);
-
}
-
-
/* parent */
-
if ((pid = waitpid(pid, &status, 0)) < 0) #waitpid函数返回子进程的终止状态(status变量)
-
err_sys("waitpid error");
-
printf("%% ");
-
}
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.7 fig1.7.c
-
[root@node3 apue.2e]# gcc fig1.7.c
-
[root@node3 apue.2e]# ./a.out
-
% pwd
-
/root/apue.2e
-
% ls
-
advio fig12.11 fig16.16 fig18.11 fig5.4 figC.20
-
a.out fig12.12 fig16.17 fig18.12 fig5.5 figC.21
-
call fig12.13 fig16.18 fig18.13 fig6.2 figC.3
线程:资源执行的基本单位(线程可以共享同一地址空间、文件描述符、栈、进程相关的属性)
线程ID:唯一地标识了一个进程的线程,它只在所属进程中有效,一个进程的线程ID到了另一个进程中毫无意义
1.7出错处理
当UNIX函数出错时常常返回一个负值,并把全局的整型变量errno设置为含有附加信息的一个值,常见值可以查看errno-base.h
[
root@node3 apue.2e]# vi /usr/include/asm-generic/errno-base.h
#include
char *strerror(int errnum);
返回值:指向消息字符串的指针
解析:通过全局变量errno的值获取出错消息,每种出错都对应于相关的出错提示信息,当调用该接口函数时,可以把相应出错号的出错提示信息返回给调用者
示例:
-
[root@node3 apue.2e]# cat strerror.c
-
#include <apue.h>
-
-
int
-
main(void)
-
{
-
int fd;
-
extern int errno;
-
-
if ((fd = open("/dev/dsp",'w')) < 0)
-
{
-
printf("error = %d\n",errno);
-
// errno = 13;
-
char *mesg = strerror(errno);
-
printf("Mesg: %s\n",mesg);
-
}
-
exit(0);
-
}
-
[root@node3 apue.2e]# gcc strerror.c
-
[root@node3 apue.2e]# ./a.out
-
error = 22
-
Mesg: Invalid argument
#include
void perror(const char *msg);
解析:该函数首先输出msg指向的字符串,然后输出一个冒号,一个空格,接着是对应于当前的errno值对应的出错信息。
-
[root@node3 apue.2e]# cat perror.c
-
#include "apue.h"
-
-
int
-
main(void)
-
{
-
FILE *fp;
-
fp = fopen("/root/nonexistfile","r+");
-
if (NULL == fp)
-
{
-
perror("/root/nonexistfile");
-
}
-
return 0;
-
}
-
-
[root@node3 apue.2e]# gcc perror.c
-
[root@node3 apue.2e]# ./a.out
-
/root/nonexistfile: No such file or directory
-
[root@node3 apue.2e]# cat fig1.8
-
#include "apue.h"
-
#include <errno.h>
-
-
int
-
main(int argc, char *argv[])
-
{
-
fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
-
errno = ENOENT;
-
perror(argv[0]);
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.8 fig1.8.c
-
[root@node3 apue.2e]# gcc fig1.8.c
-
[root@node3 apue.2e]# ./a.out
-
EACCES: Permission denied
-
./a.out: No such file or directory
1.8用户标识
用户ID(第三个字段)
-
[root@node3 apue.2e]# cat /etc/passwd
-
root:x:0:0:root:/root:/bin/bash
-
bin:x:1:1:bin:/bin:/sbin/nologin
-
....
组ID(第四个字段)
-
[root@node3 apue.2e]# cat fig1.9
-
#include "apue.h"
-
-
int
-
main(void)
-
{
-
printf("uid = %d, gid = %d\n", getuid(), getgid());
-
exit(0);
-
}
-
[root@node3 apue.2e]# mv fig1.9 fig1.9.c
-
[root@node3 apue.2e]# gcc fig1.9.c
-
[root@node3 apue.2e]# ./a.out
-
uid = 0, gid = 0
阅读(1117) | 评论(0) | 转发(0) |