How to run “echo” command through Java? - java

I want to change a value inside of a file named scaling_max_freq located in /sys/devices/system/cpu/cpu0/cpufreq/ on an Android device.
On an another post I've read that I'm able to do this through an echo command like:
echo 255 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
Where "255" is the value I want to put in the file.
How can I succeed it through java?

You can do system call, Runtime.exec(). Or if you want to do it in pure Java you can reproduce the behavior of the command line. "echo" is just writing on the standard output, and the '>' operator is redirecting the standard output to a file (but do not append).
So in Java..
FileWriter writer = new FileWriter(file);
writer.write("255");

Related

Is there a way to simply copy console output into new text file?

I had a very simple request, I have a full code that sorts through an input file and outputs the merged strings properly into the console. My question is can I take this already perfect output from my CONSOLE and simply output it into a seperate .txt fle as well?
I've tried doing a simple
PrintStream printStream = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(printStream);
it does create my output.txt file, but it's always empty?
Option 1: Output via Terminal
Since your script already outputs perfectly to the terminal, you can redirect that output to a file via >
$ ./my-script > output.txt
You can also use the tee command if you still want to see the output in your terminal.
$ ./my-script | tee output.txt
Option 2: Generate file via code
I'm not too familiar with Java / PrintStream but from https://www.tutorialspoint.com/java/io/printstream_print_string.htm, you should see content in your file by:
PrintStream printStream = new PrintStream(new FileOutputStream("output.txt"));
printStream.print("foo");
printStream.flush();

How to enter UTF-8 characters inside a jar file using Scanner(System.in)

I have a java project in which i want to take input from the user.
I wrote the code in eclipse and it was running without any problems at all.
However, when I export my classes into an executable-jar file using eclipse and try to run it in the windows cmd, the Scanner(System.in) can't read charachters in UTF-8 (greek characters) or something else that i haven't thought about.
This is the part of the code where i run into the problem :
String yesORno = inp.stringScanner(); // basically a nextLine()
while (!(yesORno.equals("ΝΑΙ") || yesORno.equals("ΟΧΙ"))) { // ΝΑΙ and OXI are greek characters not latin
System.out.println("Παρακαλώ πληκτρολογίστε 'ΝΑΙ' ή 'ΟΧΙ'"); // please type ΝΑΙ or ΟΧΙ in greek
yesORno = inp.stringScanner(); // take input again
}
inp is an object of an other class which i use to take inputs, in this case with the method stringScanner()
public String stringScanner() {
Scanner in = new Scanner(System.in);
return in.nextLine();
}
So when i run the code in eclipse and enter some sample characters for testing i get :
And that's what i want to happen every time.
But when i run the jar file i get :
As you can see the jar file for some reason doesn't recognise greek NAI and yesORno.equals("ΝΑΙ") doesn't return true to stop the while loop.
The same happens with OXI
I have tried running the jar file by using a .bat file like :
start java -Dfile.encoding=UTF-8 -jar Myfile.jar
but no solution.
I've done a lot of reserch to resolve this problem but I have found nothing.
I would appreciate your help
The JVM argument -Dfile.encoding tells the JVM what is the default encoding for (text) files it may encounter. This includes stdin, stdout and stderr – mapped to System.in, System.out and System.err. But the argument will not change anything in the operating system.
Most probably, your Windows CMD is using the Windows-1253 encoding, not UTF-8. When you tell the JVM with the -Dfile.encoding argument that it would be UTF-8, that would be an outright lie …
Try start java -Dfile.encoding=Windows-1253 -jar Myfile.jar or start java -Dfile.encoding=ISO-8859-7 -jar Myfile.jar.
If you setup your system with Windows-1253, the second option may cause other problems, as ISO-8859-7 and Windows-1253 are not fully compatible. But for your test it should do the job.
According to the documentation, the way you use the scanner will always depend on the operating system's encoding settings.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Scanner.html#%3Cinit%3E(java.io.InputStream)
Look at the alternative constructors - you can define the encoding there directly. Your code could look like
Scanner in = new Scanner(System.in, "UTF-8");

Writing to the OutputStream of Java Process/ProcessBuilder as pipe

I have problems sending data from java to a (linux)-subprocess created by ProcessBuilder/Process.
A shell-only based basic example would look like as follows and works fine.
echo "hello world" | cat - >/tmp/receive.dat
Now, I want to substituted the echo "hello world" by a java program which should internally create a new process (the cat - >/tmp/receive.dat) and then send data to it.
I tried the following, but the file /tmp/receive.dat remains untouched:
String[] cmdArray = { "/bin/cat", "-", ">/tmp/receive.dat" };
ProcessBuilder builder = new ProcessBuilder (cmdArray);
builder.directory (new File ("/tmp"));
Process p = builder.start ();
OutputStream pos = p.getOutputStream ();
byte [] bytes = "hello world".getBytes ();
pos.write (bytes);
pos.close ();
p.waitFor ();
The same happens under Windows, of course with an adapted cmdArray:
cmd /c type con >c:\tmp\receive.dat
Printing directly to system.out from java is no alternative as many subprocesses should be called within the livecycle of the java program.
thx for any help!
Tombo
The issue here is that /bin/cat does not actually write to files, it merely writes to standard out. The output redirection >/tmp/receive.dat is actually performed by the shell, but you are bypassing the shell by invoking cat in this manner.
If what you are trying to achieve is merely an OutputStream that writes to a file, then doing that via standard java I/O (e.g., FileOutputStream and friends) is what you want. It is also cross-platform (i.e., Windows-friendly), unlike anything that depends on the shell.
Regarding the comment about not being able to merely write to standard out from java because of subprocesses - any subprocess you invoke can inherit standard out from their parent process (the java process - look at ProcessBuilder.Redirect.INHERIT). So even if you are invoking subprocesses from java, redirecting all the output to a file should still work in the same way as your initial example (where the java program replaces the echo command).
You probably want ProcessBuilder#redirectOutput(File), as the > functionality is not of cat, rather what is calling cat (in our sense, the process builder).

Java redirect System.out and appending

In Java, I have redirected System.out: System.setOut("someText.txt"); to write to a text file. I would like to run this program once an hour, and would like to append each set of print statements to the end of the file. For example suppose at hour 1, my program runs, prints "Hello\n" and then quits. Then at hour 2, my program runs, prints "hello again\n", and then quits.
If this happened I would like the contents of my text-file to be something like:
Hello
Hello again
Currently, I am just overwriting the text file.
How can I append to the end of the text file with this redirected printStream?
EDIT How can I also print to the console?
When you build the FileOutputStream use the following:
FileOutputStream(File file, boolean append)
Creates a file output stream to write to the file represented by the specified File object.
from the JAVADOC
Code example:
OutputStream outStream = new FileOutputStream("file1.txt",true);
Use
OutputStream printStream = new OutputStream(new FileOutputStream("someText.txt", true));
System.setOut(printStream);
the answers by #Frank and #Petr Mensik are correct. But just in case you wanted to try something different:
System.out.append("Hello World\n") should do the trick. Hence, instead of doing a System.out.print, you do a System.out.append
The simplest answer is not to do this using Java code, but to use tee; trying to reimplement tee in Java is just reinventing a square wheel. Just do this:
java -jar yourapp.jar | tee -a output.log
On Windows? Install MinGW and/or Cygwin. :-)

Redirection with Runtime.getRuntime().exec() doesn't work

I need to execute a command from a program. The command line is ok, I tried it in the terminal, but it doesn't work in the program.
I add a copy from my code:
File dir = new File("videos");
String[] children = dir.list();
if (children == null) {
// Either dir does not exist or is not a directory
System.out.print("No existe el directorio\n");
} else {
for (int i=0; i<children.length; i++) {
// Get filename of file or directory
String filename = children[i];
//Recojo el momento exacto
System.out.print("\n" +filename);
Process p = Runtime.getRuntime().exec("exiftool -a -u -g1 -j videos/"+filename+">metadata/"+filename+".json");
}
The program must get the name of all of the files in a folder (filename) and extract the metadata of theese videos, writting them on a .json files in the folder 'metadata'.
Where is the problem?
The problem is, the redirection character (>) is a shell-based construct, not an executable. So unless you're running this command through something like bash (which you're not), it's going to be interpreted as a literal character argument to your exiftool invocation.
If you want to get this to work, you have two options:
Get bash to do it - pass the whole command line as an argument to bash -c. This might need some heroic escaping, although in your case it looks OK.
Do the redirection yourself within Java. Invoke the command without the redirected output (i.e. everything up to the > sign), then read from the process' outputstream and write all the contents to the appropriate file.
The latter approach sounds like more work initially, but when you consider that you need to always read a Process' output anyway (see the javadocs, second paragraph), it's actually very little extra on top of that. You're simply sending this output to a file instead of throwing it away.
If you have Java 7, it's easier:
Process p = new ProcessBuilder()
.command("exiftool", "-a", "-u", "-g1", "-j",
new File("videos", filename).toString())
.redirectOutput(new File("metadata", filename + ".json"))
.start();
This falls under "solution 2", but the runtime library takes care of the boilerplate.

Categories

Resources