项目中要用 Java 去 get 到下载的 URL ,然后交给 linux 去 wget 。那么带着()
之类的符号是不可以的。
在 Python 中可以这么做
from urllib import quote
from urllib import quote
#URL 是瞎给的
cli_url ="http://down1.chinaunix.net/distfiles/lrzsz-(0)12.20.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
codingadog 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 1
@Adia 光从这个问题描述来看,即使要 escape 也是用 shell 的 escape 规则, php 的话有个 escapeshellarg 方法,没有的话自己写一个也很简单,前面已经有人告诉你用单引号了,那么剩下的就是参数里面带单引号的怎么解决,那就是把单引号替换成 '\''
为什么这样替换可以你自己做一下实验就知道了 |
20
SoloCompany 2017-03-10 11:05:16 +08:00
多扯一句
php 就是个 2b 语言,所以宁愿发明个 escapeshellarg 也没有 exec($cmd, $arg …) ? |
21
picasso250 2017-03-10 14:08:06 +08:00
@SoloCompany 你以为 python 底层是怎么做的?
所以不是 宁愿发明,而是 我就 wrap 一下 c 的接口。剩下的你自己解决。 |
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 不谢
|