왜 이런 일이 발생합니까?

왜 이런 일이 발생합니까?

여기에 문제가 있습니다. 저는 비교적 새로 설치한 Mint 19를 실행하고 있습니다. Dwarf Fortress에 대한 많은 소문을 듣고 한 번 설치한 후 서둘러 떠나야 했기 때문에 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.

그러면 프로그램이 즉시 종료됩니다. Dwarf Fortress를 제거하고 삭제하고 다시 설치해 보았지만 동일한 결과를 얻었습니다. 완벽하게 작동하며 한 번만 이 오류를 계속 쳐다봐도 알 수 없습니다.

이것은 사업이나 다른 어떤 것과도 관련이 없으며 기술적으로 저는 프로그램에 참여하는 사람도 아니지만 지금 프로그램이 왜 실패하는지, 어떤 방식으로 프로그램을 깨뜨렸는지 알고 싶습니다. 이것은 무시하기에는 너무 신비스럽습니다. 시간 내 주셔서 감사합니다.

답변1

간단히 말해서:$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!"

왜 이런 일이 발생합니까?

dwarf-fortressUbuntu에서 제공하는 패키지는 Python 래퍼를 사용합니다 /usr/games/dwarf-fortress. 이 래퍼는 data에 다른 디렉터리와 함께 설치되는 두 번째 수준 계층 구조를 만듭니다 $XDG_DATA_HOME/.local/share/dwarf-fortress/run/.unionfs-fuse.unionfs(8)

이를 통해 모드를 $XDG_DATA_HOME/.local/share/dwarf-fortress디렉토리에 넣을 수 있으므로 아무것도 변경할 필요가 없습니다 /usr/share/games/dwarf-fortress. 정말 좋습니다! 그러나 unionfs조심스럽게 취급하고 적절하게 청소해야 합니다. 게임을 종료하는 데 익숙해 지면 C-cPython 스크립트는 이를 수행할 수 없습니다.

그러므로 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-fusein 을 제거하세요 $XDG_DATA_HOME/dwarf-fortress/run/. 저는 XDG_DATA_HOME그런 설정을 하지 않았기 때문에 실수로 잘못된 디렉토리를 삭제하는 일이 없도록 $HOME를 사용하여 확인 해야 합니다!env

rm -r $HOME/.local/share/dwarf-fortress/run/.unionfs-fuse

그게 다야. df_linux버전 은 참고해주세요베이 12 게임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드워프 포트리스 종료 후 마운트 해제된 마운트가 있는 것으로 나타나며, mount | grep unionfs에서 활성화된 마운트가 확인됩니다 /tmp. 전체 $XDG_DATA_HOME/dwarf-fortress디렉토리를 삭제했는데 다시 작동했습니다. 합격하여 설치를 strace -ff -e trace=execve dwarf-fortress확인 하고 디렉토리를 찾을 수 있었습니다.unionfs.unionfs-fuse

관련 정보