我刚刚在我的 Ubuntu 14.10 计算机上编写了一个 C++ 程序。由于它是一个客户端/服务器程序,我打开了三个终端仿真器:一个用于编写代码和编译,一个用于客户端测试,最后一个用于服务器测试。过了一会儿,我以为我的代码中有一个错误。我花了一个多小时来追踪它,结果发现退出目录并再次进入目录解决了整个问题。确切地说,这些是我执行的命令:
some_directory$ ./client
some_directory$ cd ..
$ cd some_directory
some_directory$ ./client
在没有更改任何内容(也没有重新编译)的情况下,两次运行的结果不同。我唯一能想到的就是某种可以存储旧版本文件的缓存,但我从未听说过这样的功能。有没有解释,如何解决(让它自动刷新,而不退出目录)?
答案1
我认为 bash 不会做任何花哨的事情(它确实会缓存没有路径指定的可执行文件的路径,但这不适用于此处,因为您正在指定路径)
听起来您所在的目录已被移动或挂载。在构建软件的情况下,目录移动的可能性更大。
目录移动案例
在终端 1 中重现目录移动行为的示例
cd /tmp
mkdir dir1
cd dir1
touch exampleFile
然后在 2 号航站楼:
cd /tmp
mv dir1 dir2
mkdir dir1
cd dir1
两个 shell 都显示位于名为“dir1”的目录中,但列表将显示不同的内容。如果终端 2 创建一个名为“exampleFile”的文件,则两个 shell 都会在“dir1”中显示“exampleFile”,但它们是不同的文件。这是因为终端 1 中的 shell 实际上现在位于 dir2 中,只是它不知道而已。终端 1 中的 shell 可以通过 cd 到达真正的“dir1”:
cd .
这看起来很奇怪但却重新解决了路径。
覆盖式外壳
当 shell(或任何程序)位于目录中,然后文件系统挂载在其上方时,就会发生这种情况。例如,在终端 1 中:
mkdir /tmp/dir1
cd /tmp/dir1
2 号航站楼:
mount /dev/whateverdev /tmp/dir1
cd /tmp/dir1
终端 1 可以看到该目录中原始文件系统的文件。终端 2 可以看到 /dev/whateverdev 中的文件。
如何避免
在过度安装的情况下,这主要只是知道您正在做什么或您的机器是如何配置的(例如,如果在插入 USB 驱动器时自动安装程序正在运行)。
对于目录移动的情况,这更多地取决于构建系统。如果有一条规则通过移动旧输出目录来备份它,然后为新构建创建一个新目录,那么您会经常遇到这种情况。请检查您的构建规则是否存在欺骗。
当然,这也可能是一次性的意外事故(类似于上面第一个例子中的情况)。在这种情况下,意识到这种情况的发生会对你有所帮助。
答案2
一般来说hash
和sync
hash
- 内置命令狂欢
为了加快执行命令时的操作bash shell存储它的小路在一个哈希表。每个shell
实例都有自己的hash table
。有关更多信息,请阅读以下摘录man bash
:
如果名称不是shell 函数也不是内置,且不包含斜线,狂欢搜索每个元素以查找
PATH
包含该名称的可执行文件的目录。
猛击使用哈希表记住可执行文件的完整路径名(见hash
下文Shell 内建命令以下)。PATH
仅当在哈希表中找不到该命令时,才会对目录进行完整搜索。
您可以用 替换列表中的条目(例如命令client
)hash client
;您可以使用 从列表中删除此条目hash -d client
;您可以使用 完全重置列表hash -r
。
Sync
- 将磁盘上的数据与内存同步
该sync
命令确保内存中的所有内容都写入磁盘。
为了加快操作速度,Linux 通常会将一些数据存储在内核文件系统缓冲区中,即已安排通过低级 I/O 系统调用写入的数据[1]。
另一方面“硬盘可能默认使用自己的易失性写入缓存来缓冲写入,这大大提高了性能,但同时也带来了写入丢失的可能性”[2]
sync
将内存中缓冲的任何数据写入磁盘。这可以包括(但不限于)修改的超级块、修改的 inode 以及延迟的读取和写入。这必须由内核实现;该sync
程序除了执行“sync”系统调用外什么也不做。 内核将数据保存在内存中以避免进行(相对较慢的)磁盘读写。 这提高了性能,但是......
[如果你有兴趣继续阅读这里或使用info coreutils sync
]。
针对您的问题
如果您的问题取决于上述某个方面,您可以尝试在一行中写入多个命令,然后使用向上箭头键快速调用它们,例如:
hash -d ./client; ./client
,sync ; ./client
,hash -d ./client ; sync ; ./client
(cd .. ; cd - ; ./client )
,您自己的解决方案。在这里,您以子壳继承你们一生中所做的一切壳(作为变量......)但这不会返回对当前壳。
如果不完全理解编译步骤和客户端与服务器之间的拨号操作所涉及的操作,可能很难找到原因(它甚至可能是符号链接,或者NFS 文件系统...)。在这种情况下,你必须通过反复试验来寻找起源。