와인으로 MS 윈도우용 프로그램을 설치하면, ~/.local/share/applications/wine/Programs/
)에 자동으로 .desktop
파일이 만들어지고, 리눅스 데스크탑용 런처에서 바로 실행할 수 있는 상태가 된다.
예를 들어, mp3tag 을 설치한다면,
[Desktop Entry] Name=Mp3tag Exec=env WINEPREFIX="/home/user/.wine" wine C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start\\ Menu\\\\Programs\\\\Mp3tag\\\\Mp3tag.lnk Type=Application StartupNotify=true Path=/home/user/.wine/dosdevices/c:/Program Files (x86)/Mp3tag Icon=5632_MP3TAG.0 StartupWMClass=mp3tag.exe
이런 식으로 .desktop 파일이 만들어진다.
이렇게 그냥 단독 실행했을 때는 별 문제가 없다. 그러나, 돌핀등 파일 관리자에서 파일을 선택한 뒤 우클릭하여 그 파일을 Wine 용 프로그램으로 불러오고 싶다면? 아예 파일 불러오기가 안될 수도 있고(그냥 프로그램만 실행된다.), 된다하더라도 경로 문제로 인해 원하는 결과를 얻을 수가 없게 된다(프로그램이 시작되지만, 경로를 찾을 수 없다는 오류가 뜬다.).
이건 리눅스 경로와 Wine(MS 윈도우) 경로가 다르기 때문이다. 이를 위해 Wine 에선 winepath 를 제공해주는데, 이상하게도 최근 winepath 가 한글을 무시하기 시작했다.
winepath -w '/다운로드' Z:\?ㅼ슫濡쒕뱶
제대로된 결과는 Z:\다운로드
가 돼야 하지만, 저렇게 코드가 깨져버린다. 이유는 알 수가 없다. 버그 보고하기도 번거롭고 복잡하고..
버그 보고를 했다. 의외로 답이 빨리 달렸다. 헌데 이게 생각보다 복잡한 문제라고 하는데..
글쓴이가 한대로, tee 를 붙였더니 제대로 작동은 한다.
그런데, 이게 또 문제. 스크립트를 직접 터미널에서 실행시키면 winepath 가 제대로 작동한다. 물론 tee 를 붙였을 때.
하지만 돌핀에서 연동하여 실행했을 때는 winepath 결과가 제대로 나오질 않는다. 그냥 null 값이 나오는 듯 한데.. 시험해볼 방법이 여의치 않아서(그냥 내용을 파일로 출력해보는 정도밖에..), 더 이상 확인해볼 순 없었다.
문제가 과연 뭐였을까?
하여, 그냥 winepath -w
를 regex 로 구현하는 간단한 스크립트를 만들어 일종의 wrapper 로 사용해보기로 했다.
.desktop 파일
위치
MS 윈도우 프로그램을 Wine 으로 설치했을 때 생기는 원 위치(~/.local/share/applications/wine/Programs
)에서 .desktop 파일을 직접 수정해도 되지만, 이럴 경우 재설치/판올림시 초기화되는 문제가 있다.
따라서, 이 위치에 생성된 .desktop
파일은 확장자를 .org
등으로 바꿔주고, 수정된 .desktop
파일을 ~/.local/share/applications
에 복사해놓는 편이 정신건강에 이롭다.
수정
mp3tag 을 예로 들면, 이런 식으로 변경해야 한다.
Name=Mp3tag #Exec=env WINEPREFIX="/home/nemoarch/.wine" wine C:\\\\ProgramData\\\\Microsoft\\\\Windows\\\\Start\\ Menu\\\\Programs\\\\Mp3tag\\\\Mp3tag.lnk Exec=wine_mp3tag_4DP %f .... 나머지는 동일
Exec 항목을 저런 식으로 바꿨다. wine_mp3tag_4DP
가 wrapper 이고, 저건 실행경로(~/bin
등)에 있어야 한다.%f
는 파일 1개를 넘기는 인수다. 여러 개를 넘기려면 %F 를 써야 하는데, 그리 되면 복잡해지기도 하고, 특히나 mp3tag 은 주로 디렉토리 단위로 작업을 하기 때문에, %f 를 써서 현재 선택한 파일만을 넘기기로 했다. 예전에는 %d 로 선택한 파일의 디렉토리만 넘길 수도 있었는데, 그건 없어졌다(deprecated).
wrapper
# 사용자 홈디렉토리를 알아낸 후, .wine 폴더 경로 추가. WINE_HOME="$HOME/.wine" # Argument (%f) 가 넘어왔을 때만 winepath 로 변환 if [[ $# -gt 0 ]]; then music_dir=$(dirname "$1") wine_music_dir=$(winepath-perl.sh "$music_dir") # Wine 을 사용, MS 윈도우 프로그램 호출 env WINEPREFIX="$WINE_HOME" wine 'C:\Program Files (x86)\Mp3tag\Mp3tag.exe' /fp:"$wine_music_dir" else # Arg. 가 없으므로 /fp 를 사용하지 않음. env WINEPREFIX="$WINE_HOME" wine 'C:\Program Files (x86)\Mp3tag\Mp3tag.exe' fi exit 0
Argument 가 있을 때만, 즉 돌핀등에서 컨텍스트 메뉴로 실행하여 %f
가 같이 넘어왔을 때만 winepath
를 사용하기로 했다. 또, dirname
으로 경로만을 넘긴다. 선택한 파일 1개만 넘기고 싶다면 dirname 을 사용하지 않으면 된다.
복잡할 여지가 아예 없는, 단순한 스크립트.
winepath-perl.sh
wine 용으로 경로를 변환해주는 스크립트. 파일명에 perl 이 들어갔지만, perl 스크립트는 아니고 regex 에서 perl 을 사용했다.
file_names="$@" for f in "$@" do # pattern & subs pattern="/" subs="\\" export pattern subs to_wine_filename=$(echo "Z:$f" | perl -pe 's/$ENV{pattern}/$ENV{subs}/g') echo -E "$to_wine_filename" done
sed 로 하지 않고 perl 을 쓴 이유는 다른 글에 장황하게 기록돼 있다. 간단하게 말하자면, 구분자(delimiter, /) 때문이다. 경로명에 슬래시가 들어있는데, 이게 구분자와 헷갈리기 때문에, 보다 편하게 쓸 수 있는 방법을 찾았고, 그게 perl 이었다.
다만, 위 스크립트 상태로는 파일 1개(%f) 를 넘겼을 때만 제대로 작동할 듯. 스크립트만 보면 여러 개(%F)를 처리할 수 있듯은 보이지만, 그걸 Wine 용 프로그램에서 제대로 처리하려면 뭔가 더 방법이 필요하다.
덧붙이자면, %F 가 되어 파일명이 여러개 넘어오면, 위 작업도 여러번 반복되면서 파일명을 계속 넘기게 된다. winepath-perl.sh 를 실행한 쪽에선 그 파일명들을 받아서 처리하는 방식으로 처리해야한다.
현재는 %F 가 필요하진 않아서 그냥 이렇게만 해놨다. 즉, 아직 궁하지 않아 여기까지만 생각해 봤을 뿐이다.
또, 경로명이 길 경우(255 bytes 초과?) 오류가 발생한다. 이건 wine, 또는 MS 윈도우 자체 문제로 보인다. 이런 현상을 방지하기 위해 winepath 에는 –short 선택사항이 있는데.. 그것까지 구현하기엔 실력이 한참 모자라기에..
update-desktop-database
.desktop 파일을 수정하면, 자동으로 변경사항이 반영되는 듯도 하지만, 안 그럴 때도 있다.
이럴 땐, 다음 명령을 실행해줘야 한다.
update-desktop-database ~/.local/share/applications
주로 쓰는 mp3tag, foobar2000 등으로 시험해봤는데 원하는대로 잘 작동했다.