矮人要塞安裝的奇怪問題
事情就是這樣。我正在執行 Mint 19,安裝相對較新。聽了很多關於矮人要塞的炒作,安裝了一次;然後,需要匆忙離開,用 Control-C 關閉它。從那時起,每次我嘗試執行它時,我都會得到輸出:
/tmp/dwarf-fortresss7j3cousrun/df: 6: /tmp/dwarf-fortresss7j3cousrun/df: ./libs/Dwarf_Fortress: not found Traceback (most recent call last): File "/usr/games/dwarf-fortress", line 93, in <module> main() File "/usr/games/dwarf-fortress", line 90, in main run_df_in_unionfs_with_cleanup(user_run_dir, data_dirs, sys.argv) File "/usr/games/dwarf-fortress", line 60, in run_df_in_unionfs_with_cleanup run_df_in_unionfs(user_run_dir, data_dirs, args) File "/usr/games/dwarf-fortress", line 54, in run_df_in_unionfs run_df(tmp_dir, args) File "/usr/games/dwarf-fortress", line 46, in run_df subprocess.run(cmd).check_returncode() File "/usr/lib/python3.6/subprocess.py", line 369, in check_returncode self.stderr) subprocess.CalledProcessError: Command '['/tmp/dwarf-fortresss7j3cousrun/df', '/usr/games/dwarf-fortress']' returned non-zero exit status 127.
隨後立即終止程序。我試圖刪除,甚至清除並重新安裝矮人堡壘,只是為了得到相同的結果。它執行得非常好,恰好一次,儘管我一直盯著這個錯誤,但我無法理解它。
這不是業務關鍵或其他任何事情,從技術上講,我什至不是玩家;但我真的很想知道為什麼程序現在失敗了,以及我以什麼方式破壞了它。不加檢查就太神秘了。謝謝你的時間。
**TL;DR:**使用以下腳本清除您的
$XDG_DATA_HOME
/$HOME
遺留物並解除安裝先前的unionfs
:#!/bin/sh set -eu echo "Killing currently running Dwarf Fortress instances" killall -q -9 Dwarf_Fortress || true echo "Removing old Dwarf Fortress unionfs mounts and mount points" find /tmp/ -maxdepth 1 -name "dwarf-fortress*" \ -printf " Found %f\n" \ \( -exec fusermount -u {} \; -o -true \) \ -exec rmdir {} \; UNIONFSDIR="${XDG_DATA_HOME:-"${HOME:?}/.local/share/"}dwarf-fortress/run/.unionfs-fuse" if [ -d "$UNIONFSDIR" ]; then echo "Removing old .unionfs-fuse directory" rm -r -- "$UNIONFSDIR" fi echo "Done. Run dwarf-fortress and praise Armok!"
為什麼會這樣?
Ubuntu 提供的
dwarf-fortress
包使用 Python 包裝器/usr/games/dwarf-fortress
。該包裝器在 中創建了一個二級data
層次結構,該層次結構與其他一些目錄一起$XDG_DATA_HOME/.local/share/dwarf-fortress/run/.unionfs-fuse
安裝。unionfs(8)
這使您可以將您的 mods 放在您的
$XDG_DATA_HOME/.local/share/dwarf-fortress
目錄中,因此您不需要更改 的內容/usr/share/games/dwarf-fortress
,這很棒!但是,unionfs
必須小心處理並正確清理。C-c
當您習慣退出遊戲時,Python 腳本無法做到這一點。因此,
unionfs
它可能仍處於安裝狀態,但處於不良狀態。我如何解決它?
所以首先,確保遊戲完全關閉:
killall -s KILL Dwarf_Fortress
然後確保沒有剩餘的
unionfs
DF 安裝:mount | grep -a -e dwarf -e unionfs unionfs on /tmp/dwarf-fortresswvlaptrarun type fuse.unionfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000) unionfs on /tmp/dwarf-fortress4ylv2t19run type fuse.unionfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)
如您所見,我的系統上目前有兩個。由於兩者都壞了,讓我們擺脫它們
fusermount -u
:fusermount -u /tmp/dwarf-fortresswvlaptrarun fusermount -u /tmp/dwarf-fortress4ylv2t19run
最後,但最重要的是,刪除
.unionfs-fuse
in$XDG_DATA_HOME/dwarf-fortress/run/
。我沒有XDG_DATA_HOME
設置,所以我必須使用$HOME
. 檢查env
之前不小心刪除了錯誤的目錄!rm -r $HOME/.local/share/dwarf-fortress/run/.unionfs-fuse
就是這樣。請注意,Bay 12 Games
df_linux
的版本沒有遇到這個問題,因為它既不使用 Python 包裝器,也不使用 Unionfs。話雖如此,該問題已在 2019 年得到解決,並已發送至
bullseye
. 不幸的是,它沒有固定在 中0.44.12-1
,因此buster
可能仍會受到影響。你是怎麼想出這個解決方案的?
首先,我看了一下
file $(which dwarf-fortress)
,它告訴我這是一個 Python 腳本:$ file $(which dwarf-fortress) /usr/games/dwarf-fortress: Python script, ASCII text executable
然後我用任何編輯器檢查了腳本,發現
def get_user_run_dir(): old_run_dir = xdg.BaseDirectory.save_data_path('dwarf-fortress') new_run_dir = os.path.join(old_run_dir, 'run') ... def run_df_in_unionfs(user_run_dir, data_dirs, args): mnt_dirs = user_run_dir + "=rw:" + ':'.join(data_dirs) with tempfile.TemporaryDirectory(suffix='run', prefix='dwarf-fortress') as tmp_dir: cmd = ['unionfs', '-o', 'cow,relaxed_permissions', mnt_dirs, tmp_dir] subprocess.run(cmd).check_returncode() try: run_df(tmp_dir, args) finally: subprocess.run(['fusermount', '-u', tmp_dir]).check_returncode()
這表明至少有一些東西可以在 中找到
xdg.BaseDirectory
,這是$HOME/.local/share
(除非另有設置)。同時fusermount -u
顯示退出矮人要塞後有一個unmount pending,並mount | grep unionfs
確認了在/tmp
. 我擺脫了整個$XDG_DATA_HOME/dwarf-fortress
目錄,它又工作了。使用strace -ff -e trace=execve dwarf-fortress
,我能夠確認unionfs
安裝並找到.unionfs-fuse
目錄。