项目中要用 Java 去 get 到下载的 URL ,然后交给 linux 去 wget 。那么带着()
之类的符号是不可以的。
在 Python 中可以这么做
from urllib import quote from urllib import quote #URL 是瞎给的 cli_url ="http://down1.chinaunix.net/distfiles/lrzsz-(0)1220.tar.gz" url_0 = cli_url.split('://')[0] url_1 = cli_url.split('://')[1] new_url = url_0+'://'+quote(url_1) cli_url = new_url #http://down1.chinaunix.net/distfiles/lrzsz-%280%2912.20.tar.gz print cli_url
但是在 Java 中似乎并不是这么好做的,
public static void main(String[] args) throws URISyntaxException, MalformedURLException, UnsupportedEncodingException { String _url = "http://down1.chinaunix.net/distfiles/lrzsz-(0)12.20.tar.gz"; String url=URLEncoder.encode(_url, "UTF-8"); System.out.println(url); //http%3A%2F%2Fdown1.chinaunix.net%2Fdistfiles%2Flrzsz-%280%2912.20.tar.gz //先不管 http://还没有分割。蛋疼的是这里的 url 连 /都被编码了 }
想在 Java 中得到从http://down1.chinaunix.net/distfiles/lrzsz-(0)12.20.tar.gz
变成http://down1.chinaunix.net/distfiles/lrzsz-%280%2912.20.tar.gz
的效果。 url 是不规则的,用正则应该不行..求各位大神指教。
![]() | 1 langmoe 2017-03-09 15:26:03 +08:00 加个单引号不就好了吗 |
![]() | 3 Duolingo 2017-03-09 15:29:12 +08:00 via iPhone java 的那个地址也能直接访问的吧…… |
![]() | 6 Adia OP @codingadog 的确可以。但是 wget 的时候会恢复成()....所以还是 wget 不下来 |
![]() | 7 xiaoai 2017-03-09 15:41:47 +08:00 java.net.URLEncoder.encode(url) python urllib.parse 中也有对应的方法_(:з∠)_ |
![]() | 9 cute 2017-03-09 18:15:31 +08:00 wget "$(echo 'aHR0cDovL2Rvd24xLmNoaW5hdW5peC5uZXQvZGlzdGZpbGVzL2xyenN6LSgwKTEyLjIwLnRhci5nego='|base64 -D)" |
![]() | 10 eimsteim 2017-03-09 21:24:46 +08:00 这个需求好奇怪, Java 直接下载不就行了吗?为什么一定要交给 Linux 去 wget? |
![]() | 11 SoloCompany 2017-03-09 22:05:29 +08:00 你这思路真是奇葩 还是拿 python 来说是吧 正常的程序 subprocess.call(["curl", "http://baidu.com/&123"]) 2b 的程序 os.system("curl " + "http://" + quote("baidu.com/&123")) |
![]() | 12 Infernalzero 2017-03-09 23:10:02 +08:00 用 URL 和 URI 类,或者 apache 何 spring 都有封装好的类似 URIBuilder 这样的类 至于“()”,其实不是必须转义的,所以 URI 的 toASCIIString 不会把()转成%28%29 原因:( ) 不是保留字符 Thus, only alphanumerics, the special characters "$-_.+!*'(),", and reserved characters used for their reserved purposes may be used unencoded within a URL. http://www.ietf.org/rfc/rfc1738.txt |
![]() | 13 misaka19000 2017-03-10 01:13:11 +08:00 先给 URL 进行编码,之后再加协议不就行了 |
![]() | 14 ren2881971 2017-03-10 09:30:12 +08:00 需要这么复杂么。。 随便找个符号 替换下( ? |
![]() | 15 Adia OP @eimsteim 一个分布式系统,核心是 Java , agent 那边是用 python 写的,然后调用下去所以变成 shell 了 @SoloCompany 所以说解决问题最好的方法是否定问题是吗? |
![]() | 16 Adia OP @ren2881971 哪个符号? |
![]() | 17 SoloCompany 2017-03-10 10:04:27 +08:00 @Adia #15 shell argument 的问题为什么要用 url escape 方式来解决,典型的 AB 问题 |
![]() | 18 Adia OP @SoloCompany 那么你认为该如何解决? |
![]() | 19 SoloCompany 2017-03-10 11:01:42 +08:00 ![]() @Adia 光从这个问题描述来看,即使要 escape 也是用 shell 的 escape 规则, php 的话有个 escapeshellarg 方法,没有的话自己写一个也很简单,前面已经有人告诉你用单引号了,那么剩下的就是参数里面带单引号的怎么解决,那就是把单引号替换成 '\'' 为什么这样替换可以你自己做一下实验就知道了 |
![]() | 20 SoloCompany 2017-03-10 11:05:16 +08:00 多扯一句 php 就是个 2b 语言,所以宁愿发明个 escapeshellarg 也没有 exec($cmd, $arg …) ? |
![]() |
![]() | 22 SoloCompany 2017-03-10 14:28:35 +08:00 @picasso250 #21 我不清楚 python 或者 c 是怎么实现的,但我清楚 java 是怎么实现的,请参考 https://github.com/frohoff/jdk8u-jdk/blob/jdk8u60-b10/src/solaris/classes/java/lang/ProcessImpl.java#L83 79~83 行的内容很清楚的显示 unixprocess 调用的 argBlock 的结构是怎么样的,每一个 arg 都是一个 \0 终结的 CString ,请问和 shell escape 有任何关系吗? |
![]() | 23 cloudzhou 2017-03-10 15:53:08 +08:00 @Adia 如果怎么样,能使用 wget 或者 curl ,那就走标准的 http 协议啊,这样调用 shell ,一个是效率低下,不安全,并且平台相关。 |
![]() | 24 picasso250 2017-03-13 20:35:12 +08:00 @SoloCompany #22 真不幸,你至少应该找到 java 的 UNIXProcess 类,如果你有点 sense ,应该对着 forkAndExec 方法陷入沉思。 显然,你应该想到 popen 之类的系统调用。这就是 PHP 的 wrap 。或许 PHP 不会把东西变得更好,但 PHP 也不会把东西变得更糟。而且 escapeshellarg 显然让事情比原来( c 语言时)变得更好了。 如果你现在还不清楚这和 shell escape 有什么关系,我建议你……不要参与程序员话题的讨论了。 |
![]() | 25 SoloCompany 2017-03-13 21:04:46 +08:00 @picasso250 恭喜你找到了编程的真谛,已 block 不谢 |