Debian

debian 9 上的 xdg-open 無法打開瀏覽器

  • December 12, 2019

我決定嘗試 lxdm(使用的是fluxbox和xfce),並發現對於許多程序,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

@user310685 接近了 - 但絕對是錯誤的。只有在沒有給出“裸”文件路徑(即沒有前導“file://”URI 方案和雙斜杠)或文件方案 URI(即帶有前導“file://”)時xdg-open,該修復“才有效” . 這兩種類型的論點應該有defer to ,但他們不會。xdg-open``pcmanfm

實際錯誤不是 STDERR 重定向中的錯誤。相反,腳本編寫者混淆了test“and”運算符和 shell 的程序列表“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(根據上面提到的程式碼註釋)

如果這兩個條件都成立,那麼腳本會流入一個短塊:

  1. 呼叫腳本函式file_url_to_path()以剝離任何前導“file://”部分(作為本地 var file
  2. 如果結果不是絕對路徑(即不以“/”開頭),則將 CWD 添加到file
  3. 執行pcmanfm "$file"

為什麼原始腳本失敗:

如上所述,腳本(錯誤地)使用“-a”作為“程序列表運算符”。實際發生的是 shell 執行命令(在 STDOUT 和 STDERR 重定向被“拉出”命令之後,允許在第一個單詞之後的命令單詞序列中的任何位置):

pcmanfm --help -a is_file_url_or_path "$1"

總是成功的(除非pcmanfm在 PATH 上不可執行)。執行它的模式-a ..會忽略命令行 ( ) 上的所有額外內容。因此,“程序作為文件或文件 URL”程式碼塊總是被執行。當給定一個 URL(帶有方案部分)時,腳本函式僅刪除前導“file://”,截斷任何尾隨“#…”片段,並且還對參數進行 URI 解碼(即“%XX”轉換為 ASCII)。注意:除非參數以“file:///”開頭,否則什麼都不做。pcmanfm``--help``file_url_to_path()

例如,OP 的 URL“ https://www.google.com ”沒有改變,file_url_to_path()因為它不以“file:///”開頭。但是後來的程式碼認為這個參數是一個“相對路徑”,因為它顯然不是以“/”開頭的。因此,它按照描述在 CWD 之前添加,然後pcmanfm幾乎可以肯定不會找到該 munged 值作為現有的顯示路徑。相反,它會顯示一個錯誤彈出視窗,就像 OP 的問題一樣。

修復:

很簡單:對流程鏈 AND 運算符使用正確的語法:“&&” #FIXED#,如上一行所示。

@user310685 建議的可怕之處:

@user310685 的建議確實解決了一個問題。發生的情況是,shell 盡職盡責地進行變數擴展,然後嘗試執行以下操作:

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

這幾乎肯定會產生 shell 重定向錯誤(除非 CWD 有一個名為“https:”的文件夾(在正確的位置)——它可以)。該重定向錯誤向 STDERR 發送一條消息,然後 shell 繼續執行。由於此錯誤發生在一個if .. else .. fi塊內,因此 shell 會else .. fi參與其中,這正是 @user310685 想要的。這樣,問題就解決了……

但是要付出什麼代價???

這個不太正確的修復有兩個問題:

  1. 當實際給定路徑或文件計劃 URL 時,會執行錯誤的程式碼路徑(else .. fi部分)。這是因為預期的程序鏈實際上只是一個程序,它(幾乎)總是生成一個 shell 重定向錯誤,該錯誤被視為if .. ;“假”的條件。這還不錯,因為該else .. fi塊只是將工作推遲到另一個名為的腳本函式open_generic(),該函式旨在處理路徑和文件 URL(但不是pcmanfm用來完成工作,而是我沒有分析的其他一些複雜的程式碼路徑,但是我認為做得很公平)。可是等等!恐怖_
  2. 回顧一下pcmanfm --help ...shell 嘗試的擴展腳本行。注意 STDERR 的重定向。考慮一下如果使用合法路徑(如“/home/user/precious”)完成此操作會發生什麼。OMG嘗試探測是否pcmanfm可用,然後測試參數是否是文件,只是***覆蓋文件!!!***再見了珍貴…

引用自:https://unix.stackexchange.com/questions/450200