題 Bash是否有可執行文件的緩存?


我剛剛在我的Ubuntu 14.10計算機上編寫了一個C ++程序。由於它是一個客戶端/服務器程序,我打開了三個終端仿真器:一個用於編寫代碼和編譯,一個用於客戶端測試,最後一個用於服務器測試。過了一會兒,我以為我的代碼中有一個錯誤。我失去了一個多小時跟踪它,結果發現退出目錄並再次輸入它解決了整個問題。確切地說,這些是我執行的命令:

some_directory$ ./client
some_directory$ cd ..
$ cd some_directory
some_directory$ ./client

沒有改變任何東西 - 沒有重新編譯 - 兩次運行給出了不同的結果。我唯一能想到的是某種緩存可以存儲舊版本的文件,但我從來沒有聽說過這樣的功能。是否有解釋,以及如何解決它(使其自動刷新,而不退出目錄)?


5
2018-01-31 03:36


起源




答案:


我不認為bash做任何花哨的事情(它確實緩存了沒有路徑指定的可執行文件的路徑,但這不適用於此,因為您指定了路徑)

聽起來像你所在的目錄被移動或掛載。在構建軟件的情況下,更有可能進行目錄移動。

目錄移動案例

在終端1中重新創建目錄移動行為的示例

cd /tmp
mkdir dir1
cd dir1
touch exampleFile

然後在終端2:

cd /tmp
mv dir1 dir2
mkdir dir1
cd dir1

兩個shell都顯示為名為“dir1”的目錄,但列表將顯示不同的內容。如果terminal2創建一個名為'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驅動器時自動掛載程序正在運行)。

在目錄移動的情況下,這取決於構建系統。如果存在通過移動舊輸出目錄來備份舊輸出目錄然後為新構建創建新目錄的規則,則會經常遇到這種情況。檢查您的構建規則是否有欺騙性。

當然,這也可能是一次性的無意外事故(類似於上面第一個例子中所示)。在這種情況下,意識到這可能會幫助你。


3
2018-01-31 04:28



非常感謝你。當我發布問題時,我無法重現問題,但事實證明你的答案是正確的 - 與此同時,我將執行一個冒險的shell命令,所以我備份了目錄,然後刪除了其中一個副本(不要不記得哪一個,對不起)。這就是你提到的第一個案例。 - akrasuski1


一般來說 hash 和 sync

hash  - 內置命令 慶典

在執行命令時加速操作 bash shell 存儲它的 路徑 在一個 哈希表。每 shell 實例有自己的 hash table。有關更多信息,請閱讀此摘錄 man bash

如果名稱既不是 shell函數 也不是 內置,並包含否   斜線, 慶典 搜索的每個元素 PATH 對於目錄   包含該名稱的可執行文件。
巴什 用一個 哈希表 記住可執行文件的完整路徑名(參見 hash 下 SHELL BUILTIN命令 下面)。 完整搜索目錄 PATH 僅當在哈希表中找不到該命令時才執行

您可以替換列表中的條目(例如命令 clienthash 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 ),你自己的解決方案。在這裡你執行一個客戶端 子shell 把你所做的一切都歸於你的遺產 貝殼 (作為變量......)但不會返回當前的變化 貝殼

如果沒有完全理解編譯步驟中涉及的操作以及客戶端和服務器之間的撥號操作,很難找到原因(它甚至可能是符號鏈接,或者是高延遲) NFS文件系統 ...)。在這種情況下,您必須通過試驗和錯誤搜索原點。


2
2018-01-31 10:54