Linux 删除文件

本文将会讲述如何在Linux系统下删除文件的方法,以及如何在命令行下删除某个文件中特定的内容行, 或者删除特定日期创建的文件或者目录。
目录如下:

Linux 删除文件命令

在CentOS,Redhat,或者Ubuntu等类Unix系统下,我们主要用来删除文件或文件夹目录的方法是通过执行rm 命令或者 unlink命令。 下面我们来看删除文件命令rm的用法介绍:
rm 命令是Unix或者Linux系统下的主要用来文件系统中删除文件的命令。 当然,在大多数的系统里, 当我们想删除一个文件的时候,需要当前用对对该文件或者目录有写或者可执行的权限。
rm 命令格式:

rm {文件名}
rm [参数] {文件名}
unlink {文件名}
rm –f –r  {文件名}

 
rm 命令参数:
-f, –force 强制删除文件, 不做任何删除操作的提示
-I, –interactive  进行交互式的删除操作
-r, -R, –recursive 将对指定目录中的所有目录或子目录进行递归性的删除
-v, –verbose 显示删除操作的详细信息
–help 显示命令的使用帮助信息
通常情况下,我们会将-r 和-f来同时使用,这样就可以删除所有指定的文件或者目录,并且没有任何的操作提示信息输出。

Linux 删除单个文件夹或目录

让我们来看一个使用rm命令删除指定文件或者目录的例子, 假如你想删除当前目录下的一个文件名为fio.txt 的文件, 执行下面的命令:

# rm fio.txt

Linux 删除多个文件

如果想通过rm命令同时删除多个文件,可以将多个文件的文件名作为rm命令的参数, 执行下面的命令来删除当前目录下的fio1.txt, fio2.txt, fio3.txt 文件:

# rm fio1.txt  fio2.txt fio3.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt  fio2.txt  fio3.txt
root@devops:~/osetc# rm fio1.txt fio2.txt fio3.txt
root@devops:~/osetc# ls
root@devops:~/osetc#

Linux 递归删除特定目录下的所有文件

如果要删除的目录里还包含了多层的子目录或者子目录依旧还有目录,那么如果想删除目录里的所有子目录和文件,这个时候我们需要使用rm命令的-rf参数,比如,如果你想删除当前目录下的fio目录,执行下面的命令:

# rm –rf fio

命令输出如下:

root@devops:~/osetc# ls fio
fio1.txt  fio2.txt  fio3.txt  subfio
root@devops:~/osetc# rm -rf fio
root@devops:~/osetc# ls fio
ls: 无法访问'fio': 没有那个文件或目录
root@devops:~/osetc#

Linux 删除文件并做删除前交互确认

如果你想在删除每个文件的时候,让系统都做出确认删除提示,那么这样可以让你不会错误的删除文件,比如要删除当前目录下的fio1.txt, 执行下面的命令:

# rm –I fio1.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt
root@devops:~/osetc# rm -i fio1.txt
rm:是否删除普通文件 'fio1.txt'? y
root@devops:~/osetc# ls
root@devops:~/osetc#

Linux 显示删除文件时的信息

如果你想看到linux系统在删除你指定的文件或目录的时候,显示详细的处理信息,那么可以使用rm命令的-v选项,执行命令如下:

$ rm –v fio1.txt

命令输出如下:

root@devops:~/osetc# ls
fio1.txt
root@devops:~/osetc# rm -v fio1.txt
已删除'fio1.txt'
root@devops:~/osetc# ls
root@devops:~/osetc#

Linux系统下删除空目录文件

如果想删除特定目录下的,那么可以使用linux下的另一个命令rmdir, 执行下面命令:

# rmdir fio
# rmdir fio1

Linux下删除文件里的文件列表中的文件

如果某个文件里包含了很多需要删除的特定的文件路径, 那么我们可以使用rm命令并结合下xargs 命令来进行文件删除操作。
例如要删除当前目录下的fio.txt 文件中的列出的所有文件, 那么可以执行下面的命令:

# xargs rm -v < fio.txt

命令输出如下:

root@devops:~/osetc# cat fio.txt
/root/osetc/fio1/file1.txt
/root/osetc/fio1/file2.txt
/root/osetc/fio1/file3.txt
root@devops:~/osetc# xargs rm -v <fio.txt
已删除'/root/osetc/fio1/file1.txt'
已删除'/root/osetc/fio1/file2.txt'
已删除'/root/osetc/fio1/file3.txt'

注意:当你使用rm命令来删除文件的时候,千万不要运行”rm –rf / “ 命令, 因为这个命令会将linux系统的根目录下的所有文件都删除掉,这样的话,就会导致你的系统挂掉。

Linux删除文件名中以连字符或者减号开头的文件名

如果你想删除某个文件名中包含特殊字符的文件,无法直接使用rm 命令进行文件删除。 这个时候我们需要在rm命令后的加上双连字符,再跟文件名即可。 比如要删除-fio.txt文件,就可以执行下面的命令:

# rm -- -fio.txt

 Linux 通过文件的inode号删除文件

当我们在系统里看到文件名里包含乱码或者特殊字符的文件时候,如果简单的通过rm命令来删除文件的话,会失败的。 这个时候该怎么办? 我们可以通过文件唯一的inode号来进行删除操作。
我们需要结合find命令来根据文件的inode号来进行删除文件操作。
查看文件的inode
在linux系统里可以通过命令ll –i 来查看当前目录下的文件的详细信息,输出信息的第一列就是文件的inode号。 执行下面的命令:

#ll –I

命令输出如下:

root@devops:~/osetc# ll -i
总用量 16
131103 drwxr-xr-x 3 root root 4096 3月  14 22:56 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131106 -rw-r--r-- 1 root root   82 3月  14 22:56 fio.txt
131104 -rw-r--r-- 1 root root    5 3月  15 21:23 fio2.txt
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令的delete参数进行文件删除
从上面的输出中,我们可以看到fio.txt 文件的inode号为131106, 通过执行下面的find命令并结合其-inum 参数来删除文件,执行下面的命令:

#find ./* -inum 131106 –delete

命令输出如下:

root@devops:~/osetc# find ./ -inum 131106 -delete
root@devops:~/osetc# ll -i
总用量 12
131103 drwxr-xr-x 3 root root 4096 3月  15 21:17 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131104 -rw-r--r-- 1 root root    5 3月  15 21:23 fio2.txt
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令的exec参数并结合rm命令进行文件删除操作
我们也可以通过find命令的exec参数并结合rm删除命令来根据文件的inode号做文件的删除,执行下面的命令:

#find ./ -inum 131104 –exec rm –i {} \;

命令输出如下:

root@devops:~/osetc# find ./ -inum 131104
./fio2.txt
root@devops:~/osetc# find ./ -inum 131104 -exec rm -i {} \;
rm:是否删除普通文件 './fio2.txt'? y
root@devops:~/osetc# ll -i
总用量 24
131103 drwxr-xr-x 3 root root 4096 3月  15 21:29 ./
131073 drwx------ 6 root root 4096 3月  14 22:56 ../
262172 drwxr-xr-x 2 root root 4096 3月  14 22:57 fio1/
131105 -rw-r--r-- 1 root root    5 3月  15 21:23 fio3.txt
131106 -rw-r--r-- 1 root root    5 3月  15 21:23 fio4.txt
131108 -rw-r--r-- 1 root root    5 3月  15 21:24 fio5.txt

通过find命令并结合xargs来删除文件
当我们使用find命令查看到指定inode号的文件后,还可以结合xargs命令来进行文件的删除,执行命令如下:

# find ./ -inum 131105 |xargs rm -v

命令输出如下:

root@devops:~/osetc# find ./ -inum 131105
./fio3.txt
root@devops:~/osetc# find ./ -inum 131105 |xargs rm -v
已删除'./fio3.txt'

Linux 删除指定日期之前的文件

如果你想删除指定日期之前的所有的文件,这个时候我们需要通过linux下find命令并结合其-mtime参数进行文件的查找,在通过rm命令对查找到的文件进行删除。
执行下面的命令来查找root目录下十天之前创建或更改过的文件:

root@devops:~/osetc# find /root -mtime +10 -name "mysql-server*"
/root/mysql-server_5.7.20-1ubuntu16.04_amd64.deb-bundle.tar
/root/mysql-server_5.7.20-1ubuntu16.04_amd64.deb

下一步就可以使用rm命令对查找到的文件进行删除,执行下面的命令:

# find /root -mtime +10 -name "mysql-server*"  -exec rm -rf {} \;

当然也可以使用find命令的ctime参数。

Linux 通过rm()函数进行文件的删除

在linux系统里可以通过unlink和rmdir函数来进行文件的删除,但是rmdir函数只能删除空目录文件,所有我们需要新写一个函数来先删除目录文件下的所有文件,使其成为一个空目录,进而调用rmdir函数删除空目录。如果是普通文件的话,就可以通过unlink函数进行删除。 通过新函数rm来判断文件类型,目录文件通过rm_dir函数删除,普通文件通过unlink函数删除。
rm_dir函数如下:
//递归删除目录下的所有文件

int rm_dir(std::string dir_full_path)
{
DIR* dirp = opendir(dir_full_path.c_str());
if(!dirp)
{
return -1;
}
struct dirent *dir;
struct stat st;
while((dir = readdir(dirp)) != NULL)
{
if(strcmp(dir->d_name,".") == 0
|| strcmp(dir->d_name,"..") == 0)
{
continue;
}
std::string sub_path = dir_full_path + '/' + dir->d_name;
if(lstat(sub_path.c_str(),&st) == -1)
{
Log("rm_dir:lstat ",sub_path," error");
continue;
}
if(S_ISDIR(st.st_mode))
{
if(rm_dir(sub_path) == -1) // 如果是目录文件,递归删除
{
closedir(dirp);
return -1;
}
rmdir(sub_path.c_str());
}
else if(S_ISREG(st.st_mode))
{
unlink(sub_path.c_str());     // 如果是普通文件,则unlink
}
else
{
Log("rm_dir:st_mode ",sub_path," error");
continue;
}
}
if(rmdir(dir_full_path.c_str()) == -1)//delete dir itself.
{
closedir(dirp);
return -1;
}
closedir(dirp);
return 0;
}

Rm函数如下:

int rm(std::string file_name)
{
std::string file_path = file_name;
struct stat st;
if(lstat(file_path.c_str(),&st) == -1)
{
return -1;
}
if(S_ISREG(st.st_mode))
{
if(unlink(file_path.c_str()) == -1)
{
return -1;
}
}
else if(S_ISDIR(st.st_mode))
{
if(file_name == "." || file_name == "..")
{
return -1;
}
if(rm_dir(file_path) == -1)//删除目录下的所有文件.
{
return -1;
}
}
return 0;
}

Linux 删除文件后 空间没有释放

当Linux系统下的磁盘的使用空间达到100%后,我们肯定会对文件系统里的某些不用的文件或者比较大的日志文件进行清理,比如我们会删除apache服务的日志文件, 但是当我们通过rm命令删除掉日志文件后, 我们通过df命令查看当前磁盘的可用空间依旧没有变化,这是怎么回事呢? 为什么文件删除后,磁盘空间没有被释放?
磁盘空间没有被释放的原因如下
在Linux文件系统里,当我们通过rm命令将文件删除后,系统只会将文件的链接或者指针删除掉,但是数据并没有被从所占用的磁盘空间清除,而如果之前调用这个文件的进程依旧在运行的话,那么指针也不会被删除,因为该进行依然会写数据到该文件里,所以内核依然会认为该文件没有被删除。 所以当我们再次使用df命令查看磁盘空间的时候,空间使用率依旧没有变化。
磁盘空间没有被释放的解决方法:
其实解决办法很简单,那就是找到调用这个文件的进程,将该进程重新启动或者关闭,比如重新启动HTTP服务。当然还有万能的方法,那就是重启Linux系统。
对于不能重启系统或者进程的情况,我们可以通过对日志文件的写操作,对该文件进行重新覆盖,这样就会清空该文件所占用的存储空间。比如要清空HTTP的日志文件,我们可以执行下面的命令:

#echo “”> /tmp/access.log

Linux 删除文件恢复

通过上面的介绍,我们知道文件通过rm命令删除后,系统只是删除了执行该文件inode链接,但并没有删除文件的数据块。 我们可以通过proc文件系统来恢复删除的文件,因为每一个进程在proc文件系统里都会有一个目录和进程名字,里面会包含一个文件描述符子目录,该进程需要打开的所有文件链接都会在这个目录里。 所以当从文件系统里删除文件后,proc文件系统里依然还有一个inode的引用。
下面我们来演示将恢复删除后的/var/log/syslog 日志文件:
1# 删除日志文件/var/log/syslog, 执行下面的命令:

#rm /var/log/syslog

2# 通过lsof命令来查看进程的文件描述符和相关文件名信息,执行下面的命令:

# lsof | grep /var/log/syslog

命令输出如下:

root@devops:~/osetc# lsof | grep /var/log/syslog
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.
rsyslogd    972                syslog    5w      REG                8,1    24202    1311921 /var/log/syslog (deleted)

从上面的输出中可以看到进程的pid号为972
3# 进入proc文件系统查看进程号为972的文件描述信息,执行命令:

# ll /proc/972/fd/

命令输出如下:

root@devops:~/osetc# ll /proc/972/fd/
总用量 0
dr-x------ 2 root   root    0 3月  15 21:14 ./
dr-xr-xr-x 9 syslog syslog  0 3月  14 22:22 ../
lr-x------ 1 root   root   64 3月  15 21:14 0 -> /dev/null
l-wx------ 1 root   root   64 3月  15 21:14 1 -> /dev/null
l-wx------ 1 root   root   64 3月  15 21:14 2 -> /dev/null
lrwx------ 1 root   root   64 3月  15 21:14 3 -> socket:[13886]
lr-x------ 1 root   root   64 3月  15 21:14 4 -> /proc/kmsg
l-wx------ 1 root   root   64 3月  15 21:14  5 -> /var/log/syslog (deleted)
l-wx------ 1 root   root   64 3月  15 21:14 6 -> /var/log/auth.log
l-wx------ 1 root   root   64 3月  15 21:14 7 -> /var/log/kern.log

从输出里我们可以看到syslog文件的链接信息,可以通过head -5 命令来查看文件内容。

#head -5  /proc/972/fd/5

命令输出如下:

root@devops:~/osetc# head -5 /proc/972/fd/5
Mar 14 22:23:06 devops anacron[998]: Job `cron.daily' terminated
Mar 14 22:23:13 devops gnome-session[1826]: Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
Mar 14 22:27:15 devops anacron[998]: Job `cron.weekly' started
Mar 14 22:27:15 devops anacron[2837]: Updated timestamp for job `cron.weekly' to 2018-03-14
Mar 14 22:27:20 devops anacron[998]: Job `cron.weekly' terminated

4# 执行下面的命令,恢复syslog文件

#cat  /proc/972/fd/5 >/var/log/syslog

命令输出如下:

root@devops:~/osetc# cat /proc/972/fd/5 >/var/log/syslog
root@devops:~/osetc# ls /var/log/syslog
/var/log/syslog

我们可以看到被删除后的syslog文件已经被恢复了。
也可以参考本站的另一篇文章,实现linux系统下的回收站功能,进而更方便的实现删除文件的恢复。


99%的人还阅读了:

Leave a Reply