debian 9 上的 xdg-open 無法打開瀏覽器
我決定嘗試 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
行的方法是:
- 測試是否
pcmanfm
可執行(通過讓它報告它自己的幫助,並丟棄任何 STDOUT 或 STDERR)- 並且,執行腳本函式
is_file_url_or_path()
,然後查看"$1"
參數是否可以接受pcmanfm
(根據上面提到的程式碼註釋)如果這兩個條件都成立,那麼腳本會流入一個短塊:
- 呼叫腳本函式
file_url_to_path()
以剝離任何前導“file://”部分(作為本地 varfile
)- 如果結果不是絕對路徑(即不以“/”開頭),則將 CWD 添加到
file
- 執行
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 想要的。這樣,問題就解決了……但是要付出什麼代價???
這個不太正確的修復有兩個問題:
- 當實際給定路徑或文件計劃 URL 時,會執行錯誤的程式碼路徑(
else .. fi
部分)。這是因為預期的程序鏈實際上只是一個程序,它(幾乎)總是生成一個 shell 重定向錯誤,該錯誤被視為if .. ;
“假”的條件。這還不錯,因為該else .. fi
塊只是將工作推遲到另一個名為的腳本函式open_generic()
,該函式旨在處理路徑和文件 URL(但不是pcmanfm
用來完成工作,而是我沒有分析的其他一些複雜的程式碼路徑,但是我認為做得很公平)。可是等等!恐怖… _- 回顧一下
pcmanfm --help ...
shell 嘗試的擴展腳本行。注意 STDERR 的重定向。考慮一下如果使用合法路徑(如“/home/user/precious”)完成此操作會發生什麼。OMG嘗試探測是否pcmanfm
可用,然後測試參數是否是文件,只是***覆蓋文件!!!***再見了珍貴…