2015-05-29 10:13:12 u013074465 阅读数 1296

文章参考UNP,例子也来源于该书。


  Unix域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所使用的API就是在不同主机上执行客户/服务器通信所用的API(套接字API)。

    Unix域套接字仅仅复制数据,并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不要产生顺序号,无需发送确认报文。Unix域套接字提供流和数据报两种接口。Unix域数据报服务是可靠的,既不会丢失消息也不会传递出错。它是套接字和管道之间的混合物


使用Unix域套接字的理由

(1)Unix域套接字往往比通信两端位于同一主机的TCP套接字快一倍(TCPv3)。Unix域套接字仅仅复制数据,并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不要产生顺序号,无需发送确认报文。

(2)可用于在同一台主机的不同进程之间传递描述符。

(3)Unix域套接字较新的实现把客户的凭证(用户ID和组ID)提供给服务器,从而提供了额外的安全检查措施。


为了创建一对非命名的、相互连接的UNIX域套接字,用户可以使用面向网络的域套接字接口,也可以使用socketpair函数

使用面向网络的域套接字接口

还是字符串回射服务器

字节流客户/服务器程序

//服务器端
/* 从客户端读入数据,并将数据回射到客户端。 */  
void str_echo(int sockfd) {  
   ssize_t n;  
   char buf[1024];  
again:  
   while (( n = read(sockfd, buf, 1024)) > 0)  
      write(sockfd, buf, n);  
   if (n < 0 && errno == EINTR)  
      goto again;  
   else if (n < 0) {  
      err_exit("str_echo: read error.");     
   }  
} 

int main(int argc, char **argv)
{
	int					listenfd, connfd;
	pid_t				childpid;
	socklen_t			clilen;
	//<sys/un.h>中定义的unix域套接字地址结构
	struct sockaddr_un	cliaddr, servaddr;
	void				sig_chld(int);

	//用以创建一个Unix域字节流套接字
	listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);

	//先unlink路径名,以防早先某次运行本程序导致该路径名已经存在
	//在调用bind前初始化套接字地址结构。unlink出错没关系
	unlink(UNIXSTR_PATH);
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_LOCAL;
	strcpy(servaddr.sun_path, UNIXSTR_PATH);

	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

	Listen(listenfd, LISTENQ);

	Signal(SIGCHLD, sig_chld);

	for ( ; ; ) {
		clilen = sizeof(cliaddr);
		if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
			if (errno == EINTR)
				continue;		/* back to for() */
			else
				err_sys("accept error");
		}

		if ( (childpid = Fork()) == 0) {	/* child process */
			Close(listenfd);	/* close listening socket */
			str_echo(connfd);	/* process request */
			exit(0);
		}
		Close(connfd);			/* parent closes connected socket */
	}
}
//客户端
void str_cli(FILE *fp, int sockfd) {  
   char sendline[1024], recvline[1024];  
   while (fgets(sendline, 1024, fp) != NULL) {  
      write(sockfd, sendline, strlen(sendline));  
      if (read(sockfd, recvline, 1024) == 0) {  
         err_exit("str_cli: server terminated prematurely");  
      }  
      fputs(recvline, stdout);  
   }  
}  

int main(int argc, char **argv)
{
	int					sockfd;
	struct sockaddr_un	servaddr;

	sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_LOCAL;
	strcpy(servaddr.sun_path, UNIXSTR_PATH);

	Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));

	str_cli(stdin, sockfd);		/* do it all */

	exit(0);
}

数据报客户/服务器程序

//服务器端
//该函数时一个简单的循环,使用recvfrom读入下一个到达服务器端口的数据报,再使用sendto发送给发送者  
void dg_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)  
{  
  int n;  
  socklen_t len;  
  char mesg[MAXLINE];  
  for ( ; ; ) {  
    len = clilen;  
    n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);  
    Sendto(sockfd, mesg, n, 0, pcliaddr, len);  
  }  
}  

int main(int argc, char **argv)
{
	int					sockfd;
	struct sockaddr_un	servaddr, cliaddr;

	sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

	unlink(UNIXDG_PATH);
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_LOCAL;
	strcpy(servaddr.sun_path, UNIXDG_PATH);

	Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));

	dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
}

//客户端
//使用fgets从标准输入读入一行文本,使用sendto将文本发送到服务器,  
//使用recvfrom读回服务器的回射,使用fputs把回射内容显示在标准输出。   
void dg_cli(FILE *fp, int sockfd, const struct sockaddr *pservaddr,  
        socklen_t servlen) {  
  int n;  
  char sendline[MAXLINE], recvline[MAXLINE + 1];  
  while (Fgets(sendline, MAXLINE, fp) != NULL) {  
    Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr,servlen);  
      
    n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);  
      
    recvline[n] = 0;  
    Fputs(recvline, stdout);  
  }  
}  

int main(int argc, char **argv)
{
	int					sockfd;
	struct sockaddr_un	cliaddr, servaddr;

	sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

	bzero(&cliaddr, sizeof(cliaddr));		/* bind an address for us */
	cliaddr.sun_family = AF_LOCAL;
	strcpy(cliaddr.sun_path, tmpnam(NULL));

	Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));

	bzero(&servaddr, sizeof(servaddr));	/* fill in server's address */
	servaddr.sun_family = AF_LOCAL;
	strcpy(servaddr.sun_path, UNIXDG_PATH);

	dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));

	exit(0);
}

使用socketpair函数

int socketpair(int d, int type, int protocol, int sockfd[2]); 
socketpair()函数建立一对匿名的已经连接的套接字,其特性由协议族d、类型type、协议protocol决定,建立的两个套接字描述符会放在sockfd[0]和sockfd[1]中。
第1个参数d,表示协议族,只能为AF_LOCAL或者AF_UNIX(两者含义一样,POSIX把Unix域协议重新命名为“本地IPC”,以消除它对Unix系统的依赖,把AF_UNIX变为AF_LOCAL);
第2个参数type,表示类型,只能为0。
第3个参数protocol,表示协议,可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STREAM建立的套接字对是管道流与一般的管道相区别的是,套接字对建立的通道是双向的,即每一端都可以进行读写。参数sockfd,用于保存建立的套接字对,新创建的两个套接字描述符作为sockfd[0]和sockfd[1]返回。

2014-12-16 18:47:59 chenhanzhun 阅读数 1699

概述

        Unix 域套接字是一种客户端和服务器在单主机上的 IPC 方法。Unix 域套接字不执行协议处理,不需要添加或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套接字的效率更高。Unix 域套接字提供字节流(类似于 TCP)和数据报(类似于 UDP)两种接口,UNIX域数据报服务是可靠的,既不会丢失消息也不会传递出错。UNIX域套接字是套接字和管道之间的混合物。


Unix 域套接字编程


地址结构:

struct sockaddr_un{
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* pathname */
};

存放在 sun_path 数组中的路径名必须以空字符结尾。下面是把一个路径名绑定到 Unix 域套接字上实现的程序:

/* 创建一个Unix域套接字,并bind一个路径名 */
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>

extern void err_sys(const char *, ...);
extern void err_quit(const char *, ...);
int main(int argc, char **argv)
{
    int sockfd, size;
    socklen_t len;
    struct sockaddr_un addr1, addr2;

    if(argc != 2)
        err_quit("usage: %s <pathname>", argv[0]);

    bzero(&addr1, sizeof(addr1));
    addr1.sun_family = AF_UNIX;

    strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1);

    /* 创建一个Unix域套接字 */
    if( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    /* 若路径名在文件系统已存在,则bind会出错;所以先调用unlink删除要绑定的路径名,防止bind出错 */
    unlink(argv[1]);

    /* 将路径名bind绑定到该套接字上 */
    size = offsetof(struct sockaddr_un, sun_path) + strlen(addr1.sun_path);
    if(bind(sockfd, (struct sockaddr *)&addr1, size) < 0)
        err_sys("bind error");

    /* 显示已绑定的路径名 */
    len = sizeof(addr2);
    getsockname(sockfd, (struct sockaddr *)&addr2, &len);
    printf("bound name = %s, returned len = %d\n", addr2.sun_path, len);

    exit(0);
}

$ ./main /tmp/sock
bound name = /tmp/sock, returned len = 12

/*当该路径名存在,且不使用unlink函数时,会出现以下提示*/
$ ./main /tmp/sock
bind error: Address already in use


为了创建一对非命名的,相互连接的 UNXI 域套接字,用户可以使用socketopair函数。其实现如下:

#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sockfd[2]);
/* 返回值:若成功则返回0,出错则返回-1 */
/* 说明
* 参数 domain 必须是 AF_LOCAL 或 AF_UNIX,protocol 必须为 0,type 可以是 SOCK_STREAM 或 SOCK_DGRAM,新创建的两个套接字描述符作为sockfd[0]和sockfd[1]返回;

Unix 域套接字函数

与因特网域套接字相比,Unix 域套接字有以下的区别:

  1. 由 bind 创建的路径名默认访问权限应为 0777,并按当前 umask 值进行修改;
  2. 路径名必须是一个绝对路径名,避免使用相对路径名。因为它的解析依赖于调用者的当前工作目录,若服务器绑定的是一个相对路径名,则客户端和服务器必须在相同的目录才能正常工作;
  3. 在 connect 调用中指定的路径名必须是一个当前绑定在某个已打开的 Unix 域套接字上的路径名,而且套接字类型必须一致;
  4. 调用 connect 连接一个 Unix 域套接字涉及的权限测试等价于调用 open 以只写方式访问相应的路径名;
  5. Unix 域字节流套接字类似于 TCP 套接字:它们都为进程提供一个无记录边界的字节流接口;
  6. 在 Unix 域字节流套接字中,若 connect 调用时发现监听套接字的队列已满,则立即返回 ECONNREFUSED 错误。而 TCP 套接字遇到这种情况,TCP 监听套接字忽略这些到达的 SYN 连接请求,TCP 客户端则会重发数次 SYN 报文段;
  7. Unix 域数据报套接字类似于 UDP 套接字:它们都提供一个保留记录边界的不可靠数据报;
  8. 为一个未绑定路径名的 Unix 套接字发送数据时,不会自动给该套接字绑定一个路径名。而 UDP 套接字在给一个未绑定的 UDP 套接字发送数据时,会自动为其绑定一个临时端口;

Unix 域字节流编程

服务器程序:

#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <signal.h>
#include <errno.h>

#define QLEN 1024
typedef void Sigfunc(int);

extern void err_sys(const char *, ...);
extern void err_quit(const char *, ...);
extern void str_echo(int);
static Sigfunc *MySignal(int signo, Sigfunc *func);
static Sigfunc *M_signal(int signo, Sigfunc *func);
static void sig_chld(int);

int main(int argc, char **argv)
{
    int sockfd, conndfd, size;
    socklen_t len;
    pid_t childpid;
    struct sockaddr_un cliaddr, servaddr;

    if(argc != 2)
        err_quit("usage: %s <pathname>", argv[0]);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_UNIX;

    strcpy(servaddr.sun_path, argv[1]);

    /* 创建一个Unix域套接字 */
    if( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    /* 若路径名在文件系统已存在,则bind会出错;所以先调用unlink删除要绑定的路径名,防止bind出错 */
    unlink(argv[1]);

    /* 将路径名bind绑定到该套接字上 */
    size = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path);
    if(bind(sockfd, (struct sockaddr *)&servaddr, size) < 0)
        err_sys("bind error");

    /* 监听套接字 */
    if(listen(sockfd, QLEN) < 0)
    {
        close(sockfd);
        err_sys("listen error");
    }

    /* 信号处理 */
    MySignal(SIGCHLD, sig_chld);

    for( ; ;)
    {
        len = sizeof(cliaddr);
        if( (conndfd = accept(sockfd, (struct sockaddr *)&cliaddr, &len)) < 0)
        {
            if(errno == EINTR)
                continue;
            else
                err_sys("accept error");
        }
    }

    if( (childpid = fork()) == 0)
    {
        close(sockfd);
        str_echo(conndfd);
        exit(0);
    }
    close(conndfd);
}

void sig_chld(int signo)
{
    pid_t pid;
    int stat;
    while( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
        printf("child %d terminated\n", pid);
    return;
}
static Sigfunc *MySignal(int signo, Sigfunc *func)
{
    Sigfunc *sigfunc;
    if( (sigfunc = M_signal(signo, func)) == SIG_ERR)
        err_sys("signal error");
    return (sigfunc);
}

static Sigfunc *M_signal(int signo, Sigfunc *func)
{
    struct sigaction act, oact;

    /* 设置信号处理函数 */
    act.sa_handler = func;
    /* 初始化信号集 */
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if(signo == SIGALRM)
    {/* 若是SIGALRM信号,则系统不会自动重启 */
#ifdef SA_INTERRUPT
        act.sa_flags |= SA_INTERRUPT;
#endif
    }
    else
    {/* 其余信号设置为系统会自动重启 */
#ifdef SA_RESTART
        act.sa_flags |= SA_RESTART;
#endif
    }
    /* 调用 sigaction 函数 */
    if(sigaction(signo, &act, &oact) < 0)
        return(SIG_ERR);
    return(oact.sa_handler);
}

客户端程序:

#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>


extern void err_sys(const char *, ...);
extern void err_quit(const char *, ...);
extern void str_cli(FILE *, int);

int
main(int argc, char **argv)
{
	int					sockfd;
	struct sockaddr_un	servaddr;

    if(argc != 2)
        err_quit("usage: %s <pathname>", argv[0]);
	if( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_UNIX;
	strcpy(servaddr.sun_path, argv[1]);

    int err;
	err = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
	if( err < 0)
        err_sys("connect error");

	str_cli(stdin, sockfd);		/* do it all */

	exit(0);
}



参考资料:

《Unix 网络编程》

2018-12-31 14:33:47 u011583025 阅读数 366

SVN有9种钩子

在当前仓库下面的hook目录,都会存在相应hook文件的模板,即那些以.tmpl为后缀的文件。在Unix/Linux下,删除tmpl的后缀才能起作用,而windows则需要将.tmpl改成.bat。 修改之后立即起效,无需重新启动svn服务。

工作中,最常用的是pre-commit和post-commit两种钩子,对应以下两种应用:

1、使用Pre-commit强制程序员提交的时候一定要写Log

2、使用Post-commit监控SVN,程序员提交代码后触发相应的检查脚本

实践

1、Pre-commit

#!/bin/sh
REPOS="$1"
TXN="$2"

LOGMSG=`svnlook log -t "$TXN" "$REPOS"|wc -c`
if [ $LOGMSG -lt 10 ]; then
    echo $LOGMSG 1>&2
    echo -e "\nLog message is too short" 1>&2
    exit 1
fi
# All checks passed, so allow the commit.
exit 0

SVN触发pre-commit的时候会传两个参数,第一个是代码库路径,第二个是事务名。使用svn look命令带上这两个参数就可以获取此次提交的svn log,从而进行长度的判断。返回0则表示允许提交,返回1则不允许提交。

不建议在Pre-commit脚本里做太复杂的检查,一旦脚本本身报错,会卡住程序员提交代码。所以大部分的检查都建议放在Post-commit来触发检查。

2、Post-commit

SVN触发post-commit的时会传3个参数,第一个是代码库路径,第二个是版本号,第三个是事务名。使用svn look命令带上这几个参数也可以获取你想要检查的信息,从而传入到自定义的检查脚本。

参考文章:

1、https://www.cnblogs.com/harrymore/p/8574134.html

2、https://blog.csdn.net/liumiaocn/article/details/81942161

 

2016-04-13 17:08:10 hejun_haitao 阅读数 372

UNIX域套接字用于在同一台计算机上运行的进程之间的通信。这点比用因特网域套接字效率更高。因为UNIX域套接字仅仅复制数据,并不执行协议处理,不要添加或删除网络报头,无需计算校验和, 不要产生顺序号,无需发送确认报文。 UNIX域套接字提供流和数据包两种接口。UNIX域数据报服务是可靠的,既不会丢失报文,也不会传递出错。UNIX域套接字就像是套接字和管道的混合。可以使用它们面向网络的域套接字接口或使用socketpair函数创建一对无命名的、相互连接的UNIX域套接字。

#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sockfd[2]);
                            返回值: 若成功,返回0; 若出错,返回-1

一对相互连接的UNIX域套接字可以起到全双工通道的作用:两端对读写都开放。
这里写图片描述

消息队列是XSI IPC三种方式之一(其他两个:信号量、共享存储)。每个内核中的IPC结构都用一个非负整数的标识符加以引用。例如, 要向一个消息队列发送消息或者从一个消息队列取消息,只需要知道其队列标识符。与文件描述符不同,IPC标识符不是小的整数。 当一个IPC结构被创建时,与这种结构相关的标识符连续加1,直至达到一个整型数的最大正值,然后又回转到0。

标识符是IPC对象的内部名。为使多个合作进程能够在同一IPC对象上汇聚,提供了一个外部命名方案。 每个IPC对象都与一个键相关联,将这个键作为该对象的外部名。当创建一个新IPC结构时,都应该指定一个键,这个键的数据类型是基本系统数据类型key_t.

但是,消息队列不能关联到文件描述符,这就限制了它不能和poll或select函数一起使用。然而,套接字是和文件描述符相关联的,消息到达时,可以用套接字来通知。对每一个消息队列使用一个线程。每个线程都会在msgrcv调用中阻塞。当消息到达时,线程会把它写入一个UNIX域套接字的一端。当poll指示套接字可以读数据时,应用程序会使用这个套接字的另一端接收消息。

// 17-3.c
//使用UNIX域套接字轮询 XSI消息队列

#include "apue.h"
#include "myerror.h"
#include <pthread.h>
#include <sys/msg.h>
#include <sys/socket.h>
#include <sys/poll.h>

#define NQ      3       /* number of queues */
#define MAXMSZ  512     /* maximum message size */
#define KEY     0x123   /* key for first message queue */

struct threadinfo{
    int qid;
    int fd;
};

struct mymesg{
    long    mtype;
    char    mtext[MAXMSZ];
};

void *helper(void *arg)
{
    int             n;
    struct mymesg   m;
    struct threadinfo   *tip = arg;

    for (;;)
    {
        memset(&m, 0, sizeof(m));

        if ((n = msgrcv(tip->qid, &m, MAXMSZ, 0, MSG_NOERROR)) < 0)
            err_sys("msgrcv error");
        if (write(tip->fd, m.mtext, n) < 0)
            err_sys("write error");
    }
}

int main()
{
    int                 i, n, err;
    int                 fd[2];
    int                 qid[NQ];
    struct pollfd       pfd[NQ];
    struct threadinfo   ti[NQ];
    pthread_t           tid[NQ];
    char                buf[MAXMSZ];

    for (i = 0; i < NQ; i++)
    {
        if ((qid[i] = msgget((KEY+i), IPC_CREAT | 0666)) < 0)
            err_sys("msgget error");

        printf("queue ID %d is %d\n", i, qid[i]);

        if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd) < 0)
            err_sys("socketpair error"); // 使用的是数据包套接字而不是流套接字,这样做可以保持消息边界,以保证从套接字里一次只读取一条消息

        pfd[i].fd = fd[0];
        pfd[i].events = POLLIN;
        ti[i].qid = qid[i];
        ti[i].fd = fd[1];

        if ((err = pthread_create(&tid[i], NULL, helper, &ti[i])) != 0)
            err_exit(err, "pthread_create error");
    }

    for (;;)
    {
        if (poll(pfd, NQ, -1) < 0)
            err_sys("poll error");

        printf("\n");

        for (i = 0; i < NQ; i++)
        {
            if (pfd[i].revents & POLLIN)
            {
                if ((n = read(pfd[i].fd, buf, sizeof(buf))) < 0)
                    err_sys("read error");
                buf[n] = 0;
                printf("queue id %d, message %s\n", qid[i], buf);
            }
        }
    }

    exit(0);
}

在main函数中创建了一些消息队列和UNIX域套接字,并为每个消息队列开启了一个线程。然后它在一个无线循环中用poll来论询选择一个套接字端点。当某个套接字可读时,程序从套接字中读取数据并把消息打印到标准输出上。

//17-4.c
//给XSI消息队列发送消息
//程序需要两个参数: 消息队列关联的键值以及一个包含消息主体的字符串。
#include "apue.h"
#include "myerror.h"
#include <sys/msg.h>

#define MAXMSZ 512

struct mymesg{
    long mtype;
    char mtext[MAXMSZ];
};

int main(int argc, char *argv[])
{
    key_t key;
    long qid;
    size_t nbytes;
    struct mymesg m;

    if (argc != 3)
    {
        fprintf(stderr, "usage: sendmsg KEY message\n");
        exit(1);
    }

    key = strtol(argv[1], NULL, 0);
    if ((qid = msgget(key,0)) < 0)
        err_sys("can't open queue key %s", argv[1]);

    memset(&m, 0, sizeof(m));
    strncpy(m.mtext, argv[2], MAXMSZ-1);
    nbytes = strlen(m.mtext);
    m.mtype = 1;

    if (msgsnd(qid, &m, nbytes, 0) < 0)
        err_sys("can't send message");

    exit(0);

}

测试结果:
这里写图片描述

2015-05-07 15:46:20 smok56888 阅读数 2437

业务需要产生大量琐碎文件,最终服务器的inode被占100%

用rm直接删除文件,等啊等中间跑了两次厕所也没有执行完,能不能有快一点的方法啊!

google一把发现一篇好文,原地址点这里,转过来备忘




场景:删除/tmp下的所有文件


方法一:直接使用rm

rm -f /tmp/*

方法二:使用find 和 rm

find /tmp/ -type f  -exec rm {} \;


方法三: 使用find

find /tmp/ -type f -delete


方法四:使用rsync

rsync是linux下文件同步和数据传输的命令。通过构造一个空文件夹并且和目标文件夹进行同步,就可以把目标文件夹的内容给删除了

mkdir blanktest
rsync --delete-before -d blanktest/  /tmp/


附原文的一个速度比较


UNIX

阅读数 32

没有更多推荐了,返回首页