[求助] zsh 使用 open 命令打开含中文 url 失败 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
leverestfish
V2EX    程序员

[求助] zsh 使用 open 命令打开含中文 url 失败

  •  
  •   leverestfish 2020-12-12 19:19:01 +08:00 1481 次点击
    这是一个创建于 1773 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前一直用一个 Alfred workflow 来实现选中文字快速百度查询,是通过一个 zsh 脚本的 open 命令来打开链接的,更新 Big Sur 之后这个 workflow 跪了,看了下是由于无法用 open 命令来打开含有中文字符的 URL 来,具体情况见下图。

    shell 小白在这问下有没有什么解决方案,比如如何把$url 变量进行 urlencode 等,或者是否有 open 的替代命令?

    另外也好奇为什么会出这个问题。

    图片

    # 打开英文 url 是 OK 的 url="abcd" open http://www.baidu.com/s\?wd\=$url # 有中文就报错了(识别为系统文件了) url="汉字" open http://www.baidu.com/s\?wd\=$url The file /Users/<my_username>/http:/www.baidu.com/s?wd=汉字 does not exist. 

    尝试了加引号等操作均没有办法(实在是 shell 小白了),并且已善用搜索,求大佬指点,谢谢!

    dorentus
        1
    dorentus  
       2020-12-12 19:40:30 +08:00   1
    URLEncode 一下。。。

    url="汉字"
    open http://www.baidu.com/s\?wd\=$(perl -MURI::Escape -le "print uri_escape('$url')")

    ----

    解释:

    下面这行 perl 命令会对 $url 进行 URLEncode (这是我在 macOS 下面能找到的不安装任何包就能用的最快的 URLEncode 了):

    perl -MURI::Escape -le "print uri_escape('$url')"

    而 Bash 的 $(命令) 会把命令输出的结果转化成字符串

    其实也相当于:

    url="汉字"
    url_encoded=$(perl -MURI::Escape -le "print uri_escape('$url')")
    open http://www.baidu.com/s\?wd\=$url_encoded
    Jirajine
        2
    Jirajine  
       2020-12-12 19:43:26 +08:00 via Android   1
    omz_urlencode () {
    emulate -L zsh
    zparseopts -D -E -a opts r m P
    local in_str=$1
    local url_str=""
    local spaces_as_plus
    if [[ -z $opts[(r)-P] ]]
    then
    spaces_as_plus=1
    fi
    local str="$in_str"
    local encoding=$langinfo[CODESET]
    local safe_encodings
    safe_encodings=(UTF-8 utf8 US-ASCII)
    if [[ -z ${safe_encodings[(r)$encoding]} ]]
    then
    str=$(echo -E "$str" | iconv -f $encoding -t UTF-8)
    if [[ $? != 0 ]]
    then
    echo "Error converting string from $encoding to UTF-8" >&2
    return 1
    fi
    fi
    local i byte ord LC_ALL=C
    export LC_ALL
    local reserved=';/?:@&=+$,'
    local mark='_.!~*''()-'
    local dont_escape="[A-Za-z0-9"
    if [[ -z $opts[(r)-r] ]]
    then
    dont_escape+=$reserved
    fi
    if [[ -z $opts[(r)-m] ]]
    then
    dont_escape+=$mark
    fi
    dont_escape+="]"
    local url_str=""
    for ((i = 1; i <= ${#str}; ++i )) do
    byte="$str[i]"
    if [[ "$byte" =~ "$dont_escape" ]]
    then
    url_str+="$byte"
    else
    if [[ "$byte" == " " && -n $spaces_as_plus ]]
    then
    url_str+="+"
    else
    ord=$(( [##16] #byte ))
    url_str+="%$ord"
    fi
    fi
    done
    echo -E "$url_str"
    }
    leverestfish
        3
    leverestfish  
    OP
       2020-12-12 20:05:49 +08:00
    @dorentus
    @Jirajine
    问题解决,感谢二位,学习了!这问题看起来确实有点蠢了,因为我搜 shell 进行 urlencode 发现都是文件操作,所以才来问了,再次感谢~
    aloxaf
        4
    aloxaf  
       2020-12-12 20:06:53 +08:00   1
    > 另外也好奇为什么会出这个问题。

    这和 zsh 和 shell 都没有半毛钱关系,显然是 open 命令升级后对 url 的判定规则改变了。大概写这个程序员没想过世界上竟然还有包含 non-ascii 字符的 url 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5380 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 09:15 PVG 17:15 LAX 02:15 JFK 05:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86