在我的主目录中有一个名为“GNUstep”的目录。由于我不使用 GNUstep,我想删除此目录,但每次我这样做时都会创建它:
$ tree GNUstep
GNUstep
└── Defaults
1 directory, 0 files
$ rm -rf GNUstep
$ tree GNUstep # executed after a few seconds
GNUstep
└── Defaults
1 directory, 0 files
我已经删除了所有相关软件包,所以apt search gnustep | grep installed
现在什么都不显示。我也这么做了,apt autoremove
但没有任何效果。我使用 Lubuntu 16.04。
每次删除目录时,如何确定哪个进程会创建该目录,以及如何阻止它这样做?
这不是以下内容的重复:
- 这个 GNUstep 文件夹是什么?– 除了“直接删除它”(我就是这么做的)之外,它没有包含有关如何永久删除该目录的任何信息。
- 如何卸载 GNUStep?– 我已经这样做了,但问题并没有解决。
这建议:
作为一种解决方法,您可以更改 /etc/GNUstep/GNUstep.conf 文件中 GNUSTEP_USER_DEFAULTS_DIR 的值。
不幸的是,我的机器上没有这样的文件,甚至不/etc/GNUstep
存在。
答案1
总结:在这种情况下,软件包被仍在运行的程序实例卸载,该程序实例继续重新创建目录。检查
ps x
揭露这是什么程序。
这里有两个主要考虑因素:
- 您是否删除了所有想要删除的内容?
- 即使它已被卸载并且文件已被删除,它是否仍在运行?(可能会发生。)
1. 查找已删除的内容和仍保留的内容,并删除软件包。
跟踪您为删除软件包所采取的操作(例如您运行了哪些命令)以及删除了哪些软件包很有用。但即使没有,您也可以查看日志文件/var/log/apt/term.log
、/var/log/apt/history.log
和/var/log/dpkg.log
。特别是对于最近的软件包删除,很容易看到删除了什么。如果您通过在终端中运行命令来执行删除,那么它们也应该在您的 shell 历史记录中,您可以在 Bash 中使用命令history
(运行help history
以了解详细信息)进行检查,但这只会显示您运行的命令,而不是它们的效果。
要搜索包含特定单词的已安装软件包(例如)gnustep
,我建议使用:
apt list --installed '*gnustep*'
(当单词不是 时gnustep
,用gnustep
替换。)
请注意,尽管apt
的list
行动支持*
作为通配符角色,remove
和purge
行动则不然。相反,他们把它当作元字符在一个正则表达式(就像grep
),有时人们会删除更多包比他们打算和必须修复他们的系统。通常最好只传递要删除的特定软件包的名称。但是,例如,如果您需要删除所有软件包名字开头使用libgnustep
,然后你可以运行:
sudo apt remove ^libgnustep
(删除conf文件, 你可以purge
代替使用remove
。
2. 卸载的程序和库即使被删除也可能继续运行。
除非移除脚本卸载软件包时运行的命令会终止软件包所提供的程序正在运行的实例,这种情况很少见,除非软件包提供了后台服务或终止正在使用的其他程序库它提供了您已卸载的软件包所提供的软件,这是闻所未闻的即使文件被恢复后仍可能运行。
一个文件可能有一个或多个硬链接,即文件名。(硬链接不应与符号链接。) 什么时候全部已被移除,文件实际上已被删除:其索引节点条目被删除,并且允许重新使用存储文件数据的磁盘上的存储位置。除了如果文件当前处于打开状态。则文件将保留,直到被关闭,当使用它的程序故意关闭文件或退出时,就会发生这种情况。同样,如果您删除的文件是一个程序,程序将继续运行并且文件将保存在磁盘上,直到它退出。
因此,当您卸载提供程序的软件包但该程序正在运行时,删除该程序不会自动退出该程序,也不一定会影响其运行(尽管如果它稍后打开它认为存在的其他文件,则可能会影响其运行)。并且,当您卸载提供库的软件包但某个程序仍在使用该库时,该库会暂时继续存在于磁盘上,并且使用它的程序将继续运行。
重新启动足以删除文件,因为正在运行的进程在重新启动后无法继续存在。注销并重新登录实际上可能不够,尽管这通常就足够了。但是,如果您不能重新启动,或者不想重新启动,那么您可以尝试找出正在运行的程序并退出。在许多情况下,包括您遇到的情况,这是最好的方法,因为它更快,而且几乎和重新启动一样简单。但是,如果您找不到进程或不想麻烦,重新启动可以解决问题。
作为一个GNUstep程序运行时,它可能会读取和写入~/GNUstep
,如果发现不存在,它可能会重新创建它。虽然你可以尝试grep
对于您正在运行的进程列表中与 GNUstep 相关的特定文本(见下文),我建议采取更通用的方法:
检查 的输出
ps x
。您还可以使用a
标志ps ax
-- -- 显示所有用户的进程,但我建议首先省略它,因为该进程可能确实属于您,因此列出所有内容可能只会给您带来更大的麻烦。由于完整的命令行有时很有用,我建议运行ps x --columns=100000
。或者只运行ps | cat
,因为ps
当其输出不是终端时不会截断。这是几种情况之一“猫的无用用途”毕竟不是那么没用。(您实际上不太可能得到长度为十万个字符的行 - 这只是选择一个很大的数字以确保行不会被截断。再增加一个数量级就
ps
可以fix bigness error
了,这就是我选择 100000 的原因。)查看
pstree
。这将默认显示所有进程,并以直观的方式显示它们的父子关系。如果最终发现该进程属于另一个用户,或者它属于您,但您在查看 的输出时恰好错过了它,这将非常有用ps
。
当你运行该ps
命令时(读者:这个答案是在问题根据评论解决后写的),你成立仍在运行的程序是:
/usr/lib/GNUstep/Applications/GSSpeechServer.app/GSSpeechServer
我上面描述的方法并不是 GNUstep 特有的——除非你正在运行的 GNUstep 应用程序可能是以你而不是其他用户(如 root)的身份运行,但这是一种常见情况,并不是 GNUstep 特有的。然而,典型的路径名GNUstep 程序包含一个.app
目录,因为它们通常作为.app
容器提供。即使文件被删除,ps
仍然显示调用它的名称,经常是一个绝对路径。
因此,正在寻找 GNUstep 程序的用户,特别是当他们正在运行很多其他程序并且不想检查 的输出时ps x
,可以尝试通过运行以下命令来找到它:
ps x | grep '[.]app/'
(.
在正则表达式中匹配任意字符。匹配方法文字点是[.]
,虽然还有其他方法,但我选择了这种方法,因为它会导致grep
命令行不包含.app
,因此不得虚假列入在您的结果中。