데비안 9의 xdg-open은 브라우저를 열 수 없습니다

데비안 9의 xdg-open은 브라우저를 열 수 없습니다

나는 (Fluxbox와 xfce를 사용하여) lxdm을 시도하기로 결정했고 많은 프로그램에서 URL 핸들러가 이 오류 메시지와 함께 실패한다는 것을 발견했습니다. 에러 메시지

보시다시피 이것은 이상합니다. 사용자 디렉토리를 URL 앞에 추가합니다. 여기의 예는 텔레그램에서 가져온 것이지만, 명령줄에서 실행될 때뿐만 아니라 불일치에서도 xdg-open https://www.google.com비슷한 오류가 발생합니다. xdg-settings get default-web-browser출력 firefox.desktop은 xfce 및 lxdm의 링크로 사용될 수 있습니다. 더 많은 정보; bash -x를 실행했는데...

$ bash -x /usr/bin/xdg-open http://www.google.com
+ check_common_commands http://www.google.com
+ '[' 1 -gt 0 ']'
+ parm=http://www.google.com
+ shift
+ case "$parm" in
+ '[' 0 -gt 0 ']'
+ '[' -z '' ']'
+ unset XDG_UTILS_DEBUG_LEVEL
+ '[' 0 -lt 1 ']'
+ xdg_redirect_output=' > /dev/null 2> /dev/null'
+ '[' xhttp://www.google.com '!=' x ']'
+ url=
+ '[' 1 -gt 0 ']'
+ parm=http://www.google.com
+ shift
+ case "$parm" in
+ '[' -n '' ']'
+ url=http://www.google.com
+ '[' 0 -gt 0 ']'
+ '[' -z http://www.google.com ']'
+ detectDE
+ unset GREP_OPTIONS
+ '[' -n LXDE ']'
+ case "${XDG_CURRENT_DESKTOP}" in
+ DE=lxde
+ '[' xlxde = x ']'
+ '[' xlxde = x ']'
+ '[' xlxde = x ']'
+ '[' xlxde = xgnome ']'
+ '[' -f /run/user/1000/flatpak-info ']'
+ '[' xlxde = x ']'
+ DEBUG 2 'Selected DE lxde'
+ '[' -z '' ']'
+ return 0
+ case "${BROWSER}" in
+ case "$DE" in
+ open_lxde http://www.google.com
+ pcmanfm --help -a is_file_url_or_path http://www.google.com
++ file_url_to_path http://www.google.com
++ local file=http://www.google.com
++ echo http://www.google.com
++ grep -q '^file:///'
++ echo http://www.google.com
+ local file=http://www.google.com
+ echo http://www.google.com
+ grep -q '^/'
++ pwd
+ file=/home/nesmerrill/.local/share/applications/http://www.google.com
+ pcmanfm /home/nesmerrill/.local/share/applications/http://www.google.com
+ '[' 0 -eq 0 ']'
+ exit_success
+ '[' 0 -gt 0 ']'
+ exit 0

그런데 중요한 부분은 pcmanfm --help -a is_file_url_or_path http://www.google.com명령어를 이렇게 사용하면 아무 일도 안 일어날 것 같다는 점인 것 같은데요?

$ pcmanfm --help -a is_file_url_or_path http://www.google.com
Usage:
  pcmanfm [OPTION…] [FILE1, FILE2,...]  

Help Options:
  -h, --help                   Show help options
  --help-all                   Show all help options
  --help-gtk                   Show GTK+ Options

Application Options:
  -p, --profile=PROFILE        Name of configuration profile
  -d, --daemon-mode            Run PCManFM as a daemon
  --no-desktop                 No function. Just to be compatible with nautilus
  --desktop                    Launch desktop manager
  --desktop-off                Turn off desktop manager if it's running
  --desktop-pref               Open desktop preference dialog
  --one-screen                 Use --desktop option only for one screen
  -w, --set-wallpaper=FILE     Set desktop wallpaper from image FILE
  --wallpaper-mode=MODE        Set mode of desktop wallpaper. MODE=(color|stretch|fit|crop|center|tile|screen)
  --show-pref=N                Open Preferences dialog on the page N
  -n, --new-win                Open new window
  -f, --find-files             Open a Find Files window
  --role=ROLE                  Window role for usage by window manager
  --display=DISPLAY            X display to use

답변1

@ user310685는 가까웠지만 확실히 틀렸습니다. 수정 사항은 다음 과 같은 경우 에만 "작동 xdg-open" 합니다.아니요"기본" 파일 경로(예: 선행 "file://" URI 체계 및 이중 슬래시 없음) 또는 파일 체계 URI(예: 선행 "file://" 포함)가 제공됩니다. 두 가지 유형의 인수 모두 xdg-open뒤에 와야 pcmanfm하지만 그렇지 않습니다.

실제 오류는 STDERR 리디렉션의 오류가 아닙니다. 대신, 스크립터는 test"and" 연산자를 쉘의 프로세스 목록 "and" 커넥터와 혼동합니다. (잘못된) 사용은 "-a"이고 올바른 사용은 "&&"입니다.

참고로 원본 스크립트 줄, 해당 줄에 대한 수정 사항 및 @user310685의 "공포의 공포" 제안을 복사했습니다.

#ORIG#   if pcmanfm --help >/dev/null 2>&1 -a is_file_url_or_path "$1"; then
#FIXED#  if pcmanfm --help >/dev/null 2>&1 && is_file_url_or_path "$1"; then
#HORROR# if pcmanfm --help >/dev/null 2>$1 -a is_file_url_or_path "$1"; then

그 의도는 if ..; then위의 스크립트 줄에 나와 있습니다.

# pcmanfm only knows how to handle file:// urls and filepaths, it seems.

이 의견을 고려하면 문제가 있는 라인을 이해하는 방법은 if .. then다음과 같습니다.

  1. 실행 가능한지 테스트합니다 pcmanfm(자체 도움말을 보고하고 STDOUT 또는 STDERR을 삭제하여).
  2. 그리고 스크립트 기능을 실행하여 매개변수가 허용되는지 is_file_url_or_path()확인합니다 (위에 언급된 코드 주석을 기반으로 함)."$1"pcmanfm

두 조건이 모두 true이면 스크립트는 짧은 블록으로 흐릅니다.

  1. 선행 "file://" 부분을 제거하는 스크립트 함수를 호출합니다 file_url_to_path()(로컬 var로 file).
  2. 결과가 절대 경로가 아닌 경우(예: "/"로 시작하지 않음) 다음 값에 CWD를 추가하세요.file
  3. 구현하다pcmanfm "$file"

원본 스크립트가 실패하는 이유:

위에서 언급했듯이 스크립트는 "프로세스 목록"에 "-a"를 (잘못) 사용합니다.그리고실제로 일어나는 일은 쉘이 명령을 실행한다는 것입니다(STDOUT 및 STDERR 리디렉션이 명령에서 "제거"되어 명령 단어 시퀀스의 첫 번째 단어 뒤 어디에나 나타날 수 있도록 허용한 후).

pcmanfm --help -a is_file_url_or_path "$1"

이것언제나성공( pcmanfmPATH에서 실행 가능하지 않은 경우). 모드에서 실행하면 명령줄( )의 모든 추가 항목이 -a ..무시됩니다. 따라서 "파일 또는 파일 URL로 처리" 코드 블록은 다음과 같습니다.pcmanfm--help언제나처형되다. URL(구성표 부분 포함)이 제공되면 file_url_to_path()스크립트 기능은 단순히 선행 "file://"을 제거하고 후행 "#..." 조각을 자르고 매개변수를 URI 디코딩(예: "%XX")합니다. ASCII). 참고: 인수가 "file:///"로 시작하지 않으면 아무 작업도 수행되지 않습니다.

예를 들어 OP의 URL은 'https://www.google.comfile_url_to_path()" 는 "file:///"로 시작하지 않기 때문에 변경되지 않습니다 .하지만숨은 코드는 이 매개변수가 분명히 "/"로 시작하지 않기 때문에 "상대 경로"로 처리합니다. 따라서 설명된 대로 CWD를 추가한 다음 pcmanfm표시할 기존 경로로 해당 값을 찾지 못하는 것이 거의 확실합니다. 대신 OP의 질문에 표시된 대로 오류 팝업이 표시됩니다.

수리하다:

#FIXED#아주 간단합니다. 위 줄에 표시된 대로 프로세스 체인에 올바른 AND 연산자 구문인 "&&"를 사용하세요 .

@user310685의 제안에 대한 무서운 점은 다음과 같습니다.

@ user310685의 제안으로 문제가 해결되었습니다. 무슨 일이 일어나는지는 쉘이 충실하게 변수 확장을 수행한 다음 다음과 같은 작업을 시도한다는 것입니다.

pcmanfm --help >/dev/null 2>https://www.google.com -a is_file_url_or_path https://www.google.com

CWD에 "https:"(올바른 위치에)라는 폴더가 있지 않는 한 이는 거의 확실하게 쉘 리디렉션 오류를 생성합니다.할 수 있다). 리디렉션 오류는 STDERR에 메시지를 보내고 쉘은 계속됩니다. 이 오류는 if .. else .. fi블록 내에서 발생하므로 쉘이 else .. fi@user310685가 원했던 부분을 차지합니다. 이런 식으로 문제가 해결됩니다..

하지만 어떤 대가를 치르게 될까요?

그다지 정확하지 않은 이 수정에는 두 가지 문제가 있습니다.

  1. 실제로 경로나 파일 스키마 URL을 입력하면 잘못된 코드 경로( else .. fi일부)가 실행됩니다. 이는 예상되는 프로세스 체인이 실제로 (거의) 항상 if .. ;"거짓" 조건으로 처리되는 셸 리디렉션 오류를 생성하는 하나의 프로세스이기 때문입니다. 이것은 아니다수오좋지 않습니다. 해당 블록은 경로 및 파일 URL을 처리하도록 설계된 else .. fi이라는 다른 스크립트 함수로 작업을 연기하기 때문입니다(그러나 작업을 수행하는 데 사용되지 않고 대신 분석하지 않은 다른 복잡한 코드 경로를 사용함). , 그러나 나는 그것이 공정한 직업이라고 생각합니다).open_generic()pcmanfm하지만 기다려! 이것두려움...
  2. pcmanfm --help ...쉘이 시도하는 확장된 스크립트 라인을 다시 살펴보십시오 . STDERR의 리디렉션에 유의하세요. "/home/user/precious"와 같은 합법적인 경로를 사용하여 이 작업을 수행했다면 어떤 일이 일어날지 생각해 보세요.어머나사용 가능한지 감지 pcmanfm한 다음 매개변수가 파일인지 테스트해 보세요.파일 덮어쓰기! ! !안녕, 소중한...

답변2

Debian 10 (buster)이는 에도 해당 LXDE됩니다 xdg-utils 1.1.3-1. 스크립트에 오타가 있습니다 xdg-open. 수정 방법은 다음과 같습니다.

    --- /usr/bin/xdg-open   2018-05-20 00:18:48.000000000 +0200
+++ /home/klaumi/bin/xdg-open   2018-09-13 15:15:51.630704599 +0200
@@ -928,7 +928,7 @@
 {

     # pcmanfm only knows how to handle file:// urls and filepaths, it seems.
-    if pcmanfm --help >/dev/null 2>&1 -a is_file_url_or_path "$1"; then
+    if pcmanfm --help >/dev/null 2>$1 -a is_file_url_or_path "$1"; then
         local file="$(file_url_to_path "$1")"

         # handle relative paths

( &in 은 2>&1로 대체되어야 합니다 $.)

답변3

Debian 10(buster), LXDE, xdg-utils 1.1.3-1에서 작동하는 것으로 확인되었습니다. 버그 같은데? 편집이 필요 없는 옵션 /usr/bin/xdg-open:

  • xdg-open에 다른 데스크탑 환경의 핸들러를 사용하도록 요청할 수 있습니다(참조:1): XDG_CURRENT_DESKTOP=gnome xdg-open https://www.google.com

답변4

Seiji Adachi의 수정(그는 임시 수정이라고 함)이 나에게 잘 작동합니다.https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=906766

관련 정보