linux不产生临时文件的命令,linux设置临时环境变量命令

  linux不产生临时文件的命令,linux设置临时环境变量命令

  暂存文件

  通常,程序需要使用文件形式的临时存储。这可能是存储计算的中间结果,也可能是实际操作前做的文件拷贝备份。例如,数据程序在删除记录时会使用临时文件。文件会收集需要保存的数据库实体,然后在操作结束时,临时文件会变成新的数据库,原来的会被删除。

  临时文档的大量使用隐藏了他的一个缺点。我们必须小心确保程序会选择一个唯一的名字来使用临时文件。如果不是,因为Linux是一个多任务系统,可能会有另一个同名的程序,这两个程序会互相影响。

  tmpnam函数可以生成一个唯一的临时文件名:

  #包含stdio.h

  char * tmpnam(char * s);

  tmpnam函数将返回一个不同于现有文件的可用文件名。如果字符串不为空,文件名也将被写入其中。后续的tmpnam函数调用会覆盖用于返回值的语句存储,所以如果多次调用tmpnam函数,实际上会使用一个字符串参数。假定该字符串的长度至少为L_tmpnam个字符。在一个程序中,tmpnam最多可以被调用TMP_MAX,每次都会生成一个不同的文件名。

  如果临时文件被立即使用,那么我们可以使用tmpfile函数来命名它并打开它。这很重要,因为另一个程序将创建一个与tmpnam返回的名称相同的文件。tmpfile函数可以防止这种情况发生:

  #包含stdio.h

  FILE * tmpfile(void);

  tmpfile函数返回一个指向唯一临时文件的流指针。该文件将被打开进行读写,并且在关闭对该文件的所有引用后,该文件将被自动删除。

  如果出现错误,tmpfile将返回一个空指针并设置errno变量。

  测试-tmpnam和tmpfile

  让我们实际看看这两个函数的用法:

  #包含stdio.h

  int main()

  {

  char tmpname[L _ tmpnam];

  char *文件名;

  FILE * tmpfp

  filename=tmpnam(tmpname);

  printf("临时文件名为:%s/n ",文件名);

  tmpfp=tmpfile();

  中频(tmpfp)

  printf("打开一个临时文件OK/n ");

  其他

  perror(" tmpfile ");

  退出(0);

  }

  当我们编译正在运行的程序tmpnam.c时,可以看到tmpnam生成的唯一文件名:

  $ ./tmpnam

  临时文件名是:/tmp/file2S64zc

  打开了一个临时文件OK

  操作原理

  这个程序调用tmpnam来生成一个具有唯一文件名的临时文件。如果我们想使用这个临时文件,我们可以立即打开它,从而降低另一个程序用相同的文件名打开这个文件的风险。tmpfile调用将同时创建并打开一个临时文件,从而避免了这种风险。事实上,在编译使用该函数的程序时,GNU C编译器也会给出使用tmpnam的警告。

  旧的Unix系统有另一种方法,通过使用mktemp和mkstemp函数来生成临时文件名。这些都是Linux系统支持的,类似于tmpnam。不同的是,我们可以为临时文件名指定一个模板,这样我们可以更好地控制它的位置和名称:

  #包含stdlib.h

  char * mktemp(char * template);

  int mkstemp(char * template);

  mktemp函数从指定的模板生成一个唯一的文件名。模板必须以6 x开头。mktemp函数用唯一可用的文件名字符替换这些x字符。他返回一个指向生成的字符串的指针,如果不能生成唯一的文件名,则返回一个空指针。

  mkp函数在创建和打开临时文件方面类似于tmpfile。文件名的生成方式与mktemp相同,但返回的结果是一个开放的底层文件描述符。

  一般情况下,我们应该使用创建和打开函数tmpfile和mkstemp,而不是tmpnam和mktemp。

  用户信息

  除了init,所有的Linux程序都是由其他程序或用户启动的。我们将学习更多关于如何运行程序,或过程,交互等。在第11章。用户通常通过负责命令的外壳来启动程序。我们已经看到,程序可以通过检测其环境变量和读取系统时钟来确定其环境信息。一个程序也可以查看正在使用它的用户的信息。

  当用户登录到Linux系统时,他有一个用户名和密码。如果这些被验证,系统将向用户提供一个外壳。通常,用户有一个唯一的用户ID,称为UID。Linux运行的所有程序都是在用户的行为和与之相关的UID上运行的。

  我们可以设置一个程序运行,使它看起来像是另一个用户启动的。当程序拥有其UID的权限集时,它的运行看起来就像是可执行文件的所有者启动了它。当执行su命令时,该程序就像由超级用户启动一样运行。然后他会验证用户的访问权限,将其UID改为目标用户的UID,然后执行目标用户的登录shell。这允许程序像由另一个不同的用户启动一样运行,这通常由系统管理员用来执行维护任务。

  因为UID是用户识别的关键,我们就从这里开始讨论吧。

  UID有自己的类型——UID _ t——在sys/types.h中定义,他通常是一个小整数。有些是由系统预先定义的;其他的由系统管理员在新用户添加到系统中时创建。通常,用户的UID值大于100。

  #包含sys/types.h

  #包括unistd.h

  uid _ t getuid(void);

  char * getlog in(void);

  getUID函数返回与程序相关的UID值。这通常是启动程序的用户的UID值。

  getlogin函数返回与当前用户相关联的登录名。

  文件/etc/passwd包含一个处理用户帐户的数据库。每个用户一行,包含用户名、加密密码、用户ID UID、组ID GID、全名、主目录和默认shell。这里有一个例子:

  尼尔:zBqxfqedfpk:500:100:尼尔马修:/home/尼尔:/bin/bash

  如果我们想写一个程序来确定启动该程序的用户的UID,我们将扩展它来查看密码文件,以找到用户的登录名和全名。我们不建议这样做,因为目前的类Unix系统已经从使用简单的密码文件迁移到了加强系统安全性。包括Linux在内的许多系统都可以选择使用shadwo密码文件,该文件根本不包含任何有用的加密密码信息(通常存储在/etc/shadow中,用户无法读取)。为此,系统定义了一系列功能,为用户信息提供一个标准高效的程序接口:

  #包含sys/types.h

  #包含pwd.h

  struct passwd * getpwuid(uid _ t uid);

  struct passwd * getpwnam(const char * name);

  密码结构passwd在pwd.h中定义,包含以下成员:

  成员描述

  Char *pw_name用户登录名

  Uid_t pw_uid UID值

  Gid _ tpw _ gidgidgid值

  Char *pw_dir用户主目录

  char *pw_gecos用户的全名

  Char *pw_shell用户默认shell

  一些Unix系统使用不同的名称来表示用户的完整域名:在一些系统上,比如Linux,它是pw_gecos,在另一个系统上,它是pw_comment。这意味着我们不建议使用该域。

  getpwuid和getpwnam函数都返回一个指向对应于用户的密码结构的指针。对于getpwUID函数,用户由UID标识,而对于getpwnam函数,用户由login标识。如果出错,它们都将返回一个空指针并设置errno变量。

  测试用户信息

  下面是一个程序user.c,它将从密码数据库中获取一些用户信息:

  #包含sys/types.h

  #包含pwd.h

  #包含stdio.h

  #包括unistd.h

  int main()

  {

  uid _ t uid

  gid _ t gid

  结构密码* pw

  uid=getuid();

  GID=getgid();

  printf("用户是%s/n ",getlog in());

  printf("用户id:uid=% d,gid=%d/n ",uid,GID);

  pw=getpwuid(uid);

  printf(" UID passwd entry:/n name=% s,uid=%d,gid=%d,home=%s,shell=%s/n ",

  pw- pw_name,pw- pw_uid,pw- pw_gid,pw- pw_dir,pw-pw _ shell);

  pw=getpwnam(" root ");

  printf("根密码条目:/n ");

  printf("名称=%s,uid=%d,gid=%d,主目录=%s,外壳=%s/n ",

  pw- pw_name,pw- pw_uid,pw- pw_gid,pw- pw_dir,pw-pw _ shell);

  退出(0);

  }

  程序输出如下,不同系统上的输出结果可能略有不同:

  $ ./用户

  用户是尼尔

  用户id:uid=500,gid=100

  UID密码条目:

  name=neil,uid=500,gid=100,home=/home/neil,shell=/bin/bash

  根密码条目:

  name=root,uid=0,gid=0,home=/root,shell=/bin/bash

  操作原理

  这个程序将调用getUID函数来获取当前用户的UID值。这个UID将在getpwuid函数中用来获取详细的密码文件信息。作为对比,我们演示了如何在getpwnam函数中指定用户名root来获取用户信息。

  要遍历密码文件信息,我们可以使用getpwent函数。这将获得连续的文档实体:

  #包含pwd.h

  #包含sys/types.h

  void end pwent(void);

  struct passwd * getp went(void);

  void setp pent(void);

  Getpwent函数将依次返回每个用户的信息。当到达文件末尾时,他将返回一个空指针。一旦搜索完所有有效的实体,我们就可以使用endpwent函数来结束处理。setpwent函数可以将密码文件中的指针重置为指向文件的开头,这样下次调用getpwent函数时就可以重新开始遍历。这些函数的操作类似于第三章讨论的目录遍历函数opendir,readdir,closedir CloseDir。

  用户组标识可以通过另一个不常用的功能获得:

  #包含sys/types.h

  #包括unistd.h

  uid _ t geteuid(void);

  GID _ t getgid(void);

  GID _ t get egid(void);

  int setuid(uid _ t uid);

  int setgid(GID _ t GID);

  我们可以查看系统手册页,获得更多关于组id和有效用户ID的详细信息,虽然我们会发现我们根本不需要操作这些功能。

linux不产生临时文件的命令,linux设置临时环境变量命令