Perl脚本在终端中运行,但在从Java程序调用时不运行 [英] Perl script runs in terminal but doesn't run when invoked from Java program
问题描述
我正在运行一个用另一个字符串替换字符串的Perl脚本:
I was running a Perl script that replaces a string with another:
perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt
当我从终端运行此命令时它很好地将给定文件中出现的所有 str1
替换为 str2
。当我从java运行它时它会访问该文件,但不会发生替换:
When I run this command from terminal it well replaces all the occurrences of str1
in the given file to str2
. When I run this from java it does access the file but no replacement occurs:
Runtime.getRuntime().exec("perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt");
- 我确定它访问该文件(该文件似乎是在gedit中编辑(需要重新加载))。
- 我尝试了Java
ProcessBuilder
类,但结果相同。 - 当我使用
Runtime.exec()
或ProcessBuilder
时使用其他命令(如gedit newFile.txt
)它们运行良好。 - 具有讽刺意味的是,我从java打印了上面的perl命令,并在终端中获取了粘贴,并且替换操作是完成!
- 使用这些命令没有异常或错误。 (我用try和catch来确保这一点)。
- 我还使用
/ usr / bin / perl
而不是中的per> 以确保执行perl cmd。 - I'm sure it accesses the file (the file seems to be edited in gedit(reload required)).
- I tried Java
ProcessBuilder
class but the same result happens. - When I use
Runtime.exec()
orProcessBuilder
with other commands (likegedit newFile.txt
) they work well. - Ironically, I printed the above perl command from java and take the paste in terminal and the replace operation is done!
- No exceptions or errors by using those commands. (I used try and catch to ensure this).
- I also used
/usr/bin/perl
instead ofperl
in the cmd to ensure the perl cmd is executed.
那你觉得怎么样?问题是?
So what do you think the problem is?
编辑:
我通过从java中的命令中删除引号来解决这个问题。感谢@ikegami的帮助。
所以工作版本是:
I solved this problem by just removing the quotes from the command in java. Thanks to @ikegami for help. So the working version is:
perl -pi.back -e s/str1/str2/g; path/to/file1.txt
而不是
perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt
推荐答案
exec
使用 StringTokenizer
解析命令,显然只是在空格上拆分。
exec
uses StringTokenizer
to parse the command, which apparently just splits on whitespace.
以下面的shell命令为例(类似但不同于你的命令):
Take for example the following shell command (similar but different than yours):
perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt
对于它, StringTokenizer
生成以下命令和参数:
For it, StringTokenizer
produces the following command and arguments:
-
perl
(命令) -
-pi.back
-
-e
-
's / a / b / g;
-
s / c / d / g;'
-
path / to / file1 .txt
perl
(command)-pi.back
-e
's/a/b/g;
s/c/d/g;'
path/to/file1.txt
这是完全错误的。命令和参数应为
That's completely wrong. The command and arguments should be
-
perl
(命令) -
-pi.back
-
-e
-
s / a / b / g; s / c / d / g;
(注意缺少报价。) -
path / to / file1.txt
perl
(command)-pi.back
-e
s/a/b/g; s/c/d/g;
(Note the lack of quotes.)path/to/file1.txt
您可以将上述内容传递给 exec(String [] cmdarray)
。或者,如果您没有解析命令的选项,您实际上可以通过将以下内容传递给 exec(String [] cmdarray)
来调用shell来为您解析它。 :
You could pass those above to exec(String[] cmdarray)
. Or if you don't have the option of parsing the command, you could actually invoke a shell to parse it for you by passing the following to exec(String[] cmdarray)
:
-
sh
(命令) -
-c
-
perl -pi.back -e's / a / b / g; s / c / d / g;'path / to / file1.txt
sh
(command)-c
perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt
这篇关于Perl脚本在终端中运行,但在从Java程序调用时不运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!