Perl script runs in the terminal, but does not start when called from a Java program

I ran a Perl script that replaces the string with another:

perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt 

When I run this command from the terminal, it replaces all occurrences of str1 in this file with str2 . When I run this from java, it gets access to the file, but no replacement happens:

 Runtime.getRuntime().exec("perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt"); 
  • I'm sure it accesses the file (the file seems to be edited in gedit (requires a reboot)).
  • I tried Java ProcessBuilder but the same result.
  • When I use Runtime.exec() or ProcessBuilder with other commands (like gedit newFile.txt ), they work well.
  • Ironically, I typed the above perl command from java and took the paste in the terminal, and the replacement operation is complete!
  • No exceptions or errors when using these commands. (I used try and catch to ensure this).
  • I also used /usr/bin/perl instead of perl in cmd to enforce perl cmd.

So what do you think the problem is?

EDIT:

I solved this problem by simply removing quotes from the command in java. Thanks @ikegami for the help. Therefore, the working version:

 perl -pi.back -es/str1/str2/g; path/to/file1.txt 

instead

 perl -pi.back -e 's/str1/str2/g;' path/to/file1.txt 
+6
source share
1 answer

exec uses a StringTokenizer to parse a command, which apparently just breaks into spaces.

Take, for example, the following shell command (similar but different from yours):

 perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt 

To do this, StringTokenizer issues the following command and arguments:

  • perl (command)
  • -pi.back
  • -e
  • 's/a/b/g;
  • s/c/d/g;'
  • path/to/file1.txt

This is completely wrong. The command and arguments must be

  • perl (command)
  • -pi.back
  • -e
  • s/a/b/g; s/c/d/g; (Note the absence of quotation marks.)
  • path/to/file1.txt

You can pass these values ​​above exec(String[] cmdarray) . Or, if you don’t have the ability to parse the command, you can call the shell to parse it by passing the following to exec(String[] cmdarray) :

  • sh (command)
  • -c
  • perl -pi.back -e 's/a/b/g; s/c/d/g;' path/to/file1.txt
+5
source

All Articles