Bash command to output to file using ProcessBuilder not working - java

So, I pretty much have the below code to write some text to a file using ProcessBuilder:
val requestStringBody = "{\"transfers\": [{\"amount\": 100, \"name\": \"Steve Rogers\", \"taxId\": \"330.731.970-10\",\"bankCode\": \"001\",\"branchCode\": \"1234\",\"accountNumber\": \"123456-0\"}]}"
ProcessBuilder("cmd", "/c", ".\\git-bash.lnk", "-c", "echo -n \"$requestStringBody\" >> message.txt")
.directory(File(My Path))
.start()
.waitFor()
I had to use the git-bash.lnk due to some windows issues.
I've tried the same command using a different variable as the requestBodyString and it works fine, which leads me to believe that that string has an issue with it, but I just cant figured out what.
EDIT: Solved it using File(fileName).writeText(fileContent).

Your actual problem probably comes from the fact that the string you are embedding in your command line contains double quotes and that messes up quoting (also quoting on Windows command line is a mess).
That being said, this looks like a very convoluted way to write text to a file... as #VGR wrote, you would be better off just using regular APIs to write to files in Java.
For instance using Kotlin 1.5's Path.writeText:
val requestStringBody = "{\"transfers\": [{\"amount\": 100, \"name\": \"Steve Rogers\", \"taxId\": \"330.731.970-10\",\"bankCode\": \"001\",\"branchCode\": \"1234\",\"accountNumber\": \"123456-0\"}]}"
Path("message.txt").writeText(requestStringBody)
Or with older versions:
File("message.txt").writeText(requestStringBody)

Related

how to use windows default voice using java? [duplicate]

Is there a way to use the MS Speech utility from command line? I can do it on a mac, but can't find any reference to it on Windows XP.
My 2 cents on the topic, command line one-liners:
on Win using PowerShell.exe
PowerShell -Command "Add-Type –AssemblyName System.Speech; (New-Object System.Speech.Synthesis.SpeechSynthesizer).Speak('hello');"
on Win using mshta.exe
mshta vbscript:Execute("CreateObject(""SAPI.SpVoice"").Speak(""Hello"")(window.close)")
on OSX using say
say "hello"
Ubuntu Desktop (>=2015) using native spd-say
spd-say "hello"
on any other Linux
refer to How to text-to-speech output using command-line?
commandline function using google TTS (wget to mp3->mplayer)
command using google with mplayer directly:
/usr/bin/mplayer -ao alsa -really-quiet -noconsolecontrols "http://translate.google.com/translate_tts?ie=UTF-8&client=tw-ob&q=Hello%20World&tl=en";
on Raspberry Pi, Win, OSX (or any remote) using Node-Red
npm i node-red-contrib-sysmessage
There's a nice open source program that does what you're asking for on Windows called Peter's Text to Speech available here: http://jampal.sourceforge.net/ptts.html
It contains a binary called ptts.exe that will speak text from standard input, so you can run it like this:
echo hello there | ptts.exe
Alternatively, you could use the following three line VBS script to get similar basic TTS:
'say.vbs
set s = CreateObject("SAPI.SpVoice")
s.Speak Wscript.Arguments(0), 3
s.WaitUntilDone(1000)
And you could invoke that from the command line like this:
cscript say.vbs "hello there"
If you go the script route, you'll probably want to find some more extensive code examples with a variable timeout and error handling.
Hope it helps.
There's also Balabolka: http://www.cross-plus-a.com/bconsole.htm
It has a command line tool balcon.exe. You can use it like this:
List voices:
balcon.exe -l
Speak file:
balcon.exe -n "IVONA 2 Jennifer" -f file.txt
Speak from the command-line:
balcon.exe -n "IVONA 2 Jennifer" -t "hello there"
More command line options are available. I tried it on Ubuntu with SAPI5 installed in Wine. It works just fine.
If you can't find a command you can always wrap the System.Speech.Synthesis.SpeechSynthesizer from .Net 3.0 (Don't forget to reference "System.Speech")
using System.Speech.Synthesis;
namespace Talk
{
class Program
{
static void Main(string[] args)
{
using (var ss = new SpeechSynthesizer())
foreach (var toSay in args)
ss.Speak(toSay);
}
}
}
There is a powershell way also:
Create a file called speak.ps1
param([string]$inputText)
Add-Type –AssemblyName System.Speech
$synth = New-Object System.Speech.Synthesis.SpeechSynthesizer
$synth.Speak($inputText);
Then you can call it
.\speak.ps1 "I'm sorry Dave, I'm afraid I can't do that"
rem The user decides what to convert here
:input
cls
echo Type in what you want the computer to say and then press the enter key.
echo.
set /p text=
rem Making the temp file
:num
set num=%random%
if exist temp%num%.vbs goto num
echo ' > "temp%num%.vbs"
echo set speech = Wscript.CreateObject("SAPI.spVoice") >> "temp%num%.vbs"
echo speech.speak "%text%" >> "temp%num%.vbs"
start temp%num%.vbs
pause
del temp%num%.vbs
goto input
pause
Your best approach is to write a small command line utility that will do it for you. It would not be a lot of work - just read text in and then use the ms tts library.
Another alternative is to use Cepstral. It comes with a nice command line utility and sounds light years better than the ms tts.

Runtime.getRuntime().exec() issue

I'm trying to run another programm from Java code:
String[] command = {"gdal_polygonize.py", "/home/user/myoldfiles/proceeded.tiff", "-mask", "/home/user/myoldfiles/biomass_02.08.14.tif", "-f", "'ESRI Shapefile'", "/home/user/myoldfiles/proceeded.shp", "DN"};
Process p = Runtime.getRuntime().exec(command);
I have no file proceeded.shp created in /home/user/myoldfiles/
The command output obtained with BufferedReader looks like:
Creating output /home/user/myoldfiles/proceeded.shp of format 'ESRI Shapefile'.
When I run next command in terminal(Ubuntu)
gdal_polygonize.py '/home/user/myoldfiles/proceeded.tiff' -mask '/home/user/myoldfiles/biomass_02.08.14.tif' -f 'ESRI Shapefile' '/home/user/myoldfiles/proceeded.shp'
It prints
Creating output /home/user/myoldfiles/proceeded.shp of format ESRI Shapefile.
0...10...20...30...40...50...60...70...80...90...100 - done.
And successfully creates proceeded.shp file. What am I doing wrong in Java code?
Thanks everybody for the help! I found solution here. The problem was in single quotes in 'ESRI Shapefile', I just deleted them and all works fine now!

Different output -- when running mathtext in command line and when the command is executed from a java program using apache-commons-exec

I am trying to run mathtext from a java program using apache-commons-exec. The problem is I am getting different output when I run the same command from a java program and when I run it through shell.
so if run mathtext like this in the shell:
./mathtext test.png "\$\frac{{\left( {{p^2} - {q^2}} \right)}}{2}\$"
in a shell I get the perfect png
but when I run the same thing using apache-commons-exec
Map map = new HashMap();
map.put("target", new File(trgtFileName));
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
Executor exec = new DefaultExecutor();
exec.setWorkingDirectory(/*I set the working directory where the mathtext is*/);
CommandLine cl = new CommandLine("./mathtext");
cl.addArgument("${target}");
cl.addArgument(latex);
cl.setSubstitutionMap(map);
// Logger.log4j.info("command is:::"+cl.toString());
ExecuteWatchdog watchdog = new ExecuteWatchdog(5000);
exec.setWatchdog(watchdog);
exec.execute(cl,EnvironmentUtils.getProcEnvironment(),resultHandler);
resultHandler.waitFor();
I get the image, not the equation but the raw TeX string :(
Can somebody please help me in solving the issue? I want to get the exact output.
Thanks.
I figured out where the problem was:
$ is a special character for the unix shell and not for java. So even if in the command line the input needs to escape $ like:
"\$\frac{{\left( {{p^2} - {q^2}} \right)}}{2}\$"
inside the java program I dont need to escape the '$' or put " (double quotes) at the beginning and at the end.I had to put the command like:
$\frac{{\left( {{p^2} - {q^2}} \right)}}{2}$
Hope this helps somebody :)
--Shankhoneer

how to run cygwin script from java

I'm trying to run a bash script from a Java program I'm writing in windows. I've been trying to use the Runtime object to get a process to work, and my program compiles and runs without exceptions, but my simple test script, which just makes a directory, is not being executed.
Here's what I've got so far:
String cmmd[] = new String[3];
cmmd[0] = "C:\\cygwin\\bin\\bash.exe";
cmmd[1] = "cd C:/Users/pro-services/Desktop/projects/github/cygwin";
cmmd[2] = "bash TEST.sh";
Runtime rt= Runtime.getRuntime();
Process proc = rt.exec(cmmd);
This is basically a mix of different things I've found in forums around the net, but I guess I just don't really understand what is happening with the Process class (and I only have a basic idea about the Runtime class).
I also found this, and plugged my own stuff in where I thought it should go:
Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe",
"-c", "c:\\cygwin\\bin\\run.exe -p /bin bash C:\\Users\\pro-services\\Desktop\\projects\\github\\cygwin\\TEST.sh"},
new String[]{"PATH=/cygdrive/c/cygwin/bin"});
Here I'm not sure what the "-c" and "-p" strings represent, but I just went with it. At first it looked like I could just plug in the sequential commands that I want the Runtime/Process object to execute, in essence creating a "script" to run my script. But it now seems that there's more to it...
I'm just shooting in the dark at this point, and I have tried to understand the documentation but I'm lost. Any help would be appreciated. Thanks )))
Untested, but I would think:
cmmd[0] = "C:/cygwin/bin/bash.exe";
cmmd[1] = "-c";
cmmd[2] = "cd /cygdrive/c/Users/pro-services/Desktop/projects/github/cygwin && bash TEST.sh";

Adding parameters to Runtime.getRuntime()?

void restartWeb() {
try {
String[] command = new String[] {"webRestarter.exe" , ">>","webLog.log"};
Runtime.getRuntime().exec(command);
} catch (java.io.IOException err) {
webServer.logError(err.getMessage());
}
}
Why doesn't this work? How could I fix it so it does work like I want it to?
-- Executes webRestarter.exe with parameters >>webLog.log
So it'd spit out something like this:
webRestarter.exe>>webLog.log
You simply can't use pipes in a exec call. Pipes are a functionality of the shell and not of the operating system. So we have to call the shell executable and pass the command. Try this instead:
String[] command = new String[] {"cmd.exe", "/c", "start webRestarter.exe", ">>","webLog.log"};
Parameters are passed directly to the webRestarter.exe command. You can't use parameters to redirect standard output to a file, as this is usually done by your command line interpreter.
However, the exec() method returns a Process object, which you could use to retrieve standard output and write it to a file.
Sources:
http://download.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exec%28java.lang.String%29
http://download.oracle.com/javase/6/docs/api/java/lang/Process.html
If I'm not mistaken, pipes, redirects etc are a function of a shell. In this context, these are just arguments. You could handle this as simply as using cmd.exe with a /c switch as part of your command, I believe it'll handle this correctly, or handle the standard input/output yourself (though that's notoriously fraught with problems, I prefer something like commons-exec).
Just thought I'd mention two things that might be handy for working with Processes.
ProcessBuilder
is a good way to obtain a Process (in
code intended to run in a 1.5+ JRE).
It is recommended to carefully
read and implement all the
recommendations of When
Runtime.exec() won't.

Categories

Resources