i need to fetch the nth line of a txt file using shell script.
my text file is like
abc
xyz
i need to fetch the 2nd line and store it in a variable
i've tried all combinations using commands like :
sed
awk
head
tail
cat
... etc
problem is, when the script is called from the terminal, all these commands work fine.
but when i call the same shell script, from my java file, these commands do not work.
I expect, it has something to do with the non-interactive shell.
Please help
PS : using read command i'm able to store the first line in a variable.
read -r i<edit.txt
here , "i" is the variable and edit.txt is my txt file.
but i cant figure out, how to get the second line.
thanks in advance
edit :
ALso the script exits, when i use these "non-working" commands, And none of the remaining commands is executed.
already tried commands :
i=`awk 'N==2' edit.txt`
i=$(tail -n 1 edit.txt)
i=$(cat edit.txt | awk 'N==2')
i=$(grep "x" edit.txt)
java code:
try
{
ProcessBuilder pb = new ProcessBuilder("./myScript.sh",someParam);
pb.environment().put("PATH", "OtherPath");
Process p = pb.start();
InputStreamReader isr = new InputStreamReader(p.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line ;
while((line = br.readLine()) != null)
System.out.println(line);
int exitVal = p.waitFor();
}catch(Exception e)
{ e.printStackTrace(); }
}
myscript.sh
read -r i<edit.txt
echo "session is : "$i #this prints abc, as required.
resFile=$(echo `sed -n '2p' edit.txt`) #this ans other similar commands donot do anything.
echo "file path is : "$resFile
An efficient way to print nth line from a file (especially suited for large files):
sed '2q;d' file
This sed command quits just after printing 2nd line rather than reading file till the end.
To store this in a variable:
line=$(sed '2q;d' file)
OR using a variable for line #:
n=2
line=$(sed $n'q;d' file)
UPDATE:
Java Code:
try {
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "/full/path/of/myScript.sh" );
Process pr = pb.start();
InputStreamReader isr = new InputStreamReader(pr.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine()) != null)
System.out.println(line);
int exitVal = pr.waitFor();
System.out.println("exitVal: " + exitVal);
} catch(Exception e) { e.printStackTrace(); }
Shell script:
f=$(dirname $0)/edit.txt
read -r i < "$f"
echo "session is: $i"
echo -n "file path is: "
sed '2q;d' "$f"
Try this:
tail -n+X file.txt | head -1
where X is your line number:
tail -n+4 file.txt | head -1
for the 4th line.
Related
I have seen similiar questions on this site, but none of them seem to address/solve my problem, so I figured there is something specifically wrong with my program. I am trying to execute a very simple command, which is to take a string of a process name from a textfield input and concatenate it to a command to return and print the title of the window. This is my code:
String line;
Process p = null;
try
{
String command = "tasklist /v /fo list /fi \"imagename eq " + tf.getText().trim() + "*\"| find /i \"window title:\"\n";
p = Runtime.getRuntime().exec(command);
BufferedReader input =
new BufferedReader(new InputStreamReader(p.getInputStream()));
System.out.println(command);
while ((line = input.readLine()) != null)
{
line = line.trim();
System.out.println(line);
}
System.out.println("done");
}
catch (IOException ioException)
{
ioException.printStackTrace();
}
However, the line returned by the InputStream is always null, even though if I put the command used in .exec() into cmd (I printed it so I know they are the exact same), it works properly, albeit after a 5 seconds or so of delay. I tried it with 2 different process names and they both worked on cmd, but not in this java program. This is the output of the above code, in case that helps (the blank line is presumably from the \n at the end of the command string):
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
done
I tried adding p.waitFor() after calling .exec(), but that didn't seem to change anything. So what am I doing wrong here?
You have two problems with launching the command. Firstly you are ignoring error stream so don't see the actual problem.
Replace p = Runtime.getRuntime().exec(command); with ProcessBuilder to get access to error message:
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream();
p = pb.start();
This will tell you that tasklist is not a process. Normally using full pathname would fix this type of error, but as you are using pipe the whole command must sent to to CMD.EXE to interpret pipe components correctly. Run CMD.EXE then your piped command:
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", command);
pb.redirectErrorStream();
p = pb.start();
Prints:
tasklist /v /fo list /fi "imagename eq notepad*"| find /i "window title:"
Window Title: Notepad++
done
It's also easier to read STDOUT with simple transfer:
try(var stdout = p.getInputStream()) {
stdout.transferTo(System.out); // or where-ever
}
I'm looking a way to write running log of python which is executed by java app via script.
Let's say my script is:
import time
for x in range(120):
print("Running ", x)
time.sleep(1)
Here is my current solution:
Trigger script using java
String cmd = "python script.py";
var process = Runtime.getRuntime().exec(cmd, null, new File(sandboxPath));
Write log to new file:
String traceLogCmd = String.format("strace -p %s -s 9999 -e trace=write -o output.txt", process.pid());
Runtime.getRuntime().exec(traceLogCmd, null, new File(sandboxPath));
Now the problem is output.txt only has content whenever the python script is done executing so that I cannot tailf the output file.
Meanwhile if I execute python script.py and strace command dirrectly from terminal, the output is exactly what I expected.
Can someone correct me if I did something wrong or have a another way to get python log?
Thanks in advance.
Use ProcessBuilder instead of Runtime.exec(). More details: When Runtime.exec() won't
The following code will append to StringBuilder object output of the script sb.append(line);. It would not be difficult to write that content to a file.
Process p = new ProcessBuilder("sh", "-c", "python", "path-to-your-script").start();
String result = getCommandResult(p.getInputStream());
private static String getCommandResult(InputStream stream) throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStreamReader isr = new InputStreamReader(stream);
BufferedReader in = new BufferedReader(isr)) {
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
}
return sb.toString().trim();
}
I'm currently using ProcessBuilder to run some file like test.out.
Here is some of my code
ArrayList cmd = new ArrayList();
cmd.add("sudo");
cmd.add("./test.out");
String s = "";
try{
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.directory(new File("/myPath"));
pb.redircErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferReader br = new BufferReader(isr);
String line = "";
while((line = br.readLine()) !=null)
{
s+=line;
}
System.out.println(s);
}
I output the path which is correct("/myPath").
when I remove line
`cmd.add("sudo")`
the output will give me a String:
oneoflib:must be root. Did you forgot sudo?
But once I add
cmd.add("sudo");
there is nothing output.
Is there anyone whats wrong with it?
I can run sudo ./test.out from terminal which works fine.
I'm using eclipse BTW.
Thank you very much.
I guess that getting the error stream from the process could be beneficial here to help debug the problem.
This should help, consider the following bash script and let's call it yourExecutable. Let's also assume that it has all the proper permissions:
if [ "$EUID" -ne 0 ]
then echo "Please run as root"
exit
fi
echo "You are running as root"
When run without sudo it prints "Please run as root" other wise it prints "You are running as root"
The command, ie first argument in your list should be bash, if that is the shell you are using. The first argument should be -c so the commands will be read from the following string. The string should be echo <password> | sudo -S ./yourExecutable. This isn't exactly the best way to send the password to sudo, but I don't think that is the point here. The -S to sudo will prompt for the password which is written to stdout and piped over to sudo.
public static void main(String[] args) throws IOException {
Process process = new ProcessBuilder("bash", "-c", "echo <password> | sudo -S ./yourExecutable").start();
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String string;
while((string = errorReader.readLine()) != null){
System.out.println(string);
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((string = reader.readLine()) != null){
System.out.println(string);
}
}
Output on my machine looks like:
Password:
You are running as root
This question already has answers here:
Runtime's exec() method is not redirecting the output
(2 answers)
Closed 7 years ago.
i'm trying to run shell command in linux via java. most of the commands work, but when i run the following command i get an execption, although it works in the shell:
String command = "cat b.jpg f1.zip > pic2.jpg";
String s = null;
try {
Process p = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
i am getting the error in the console:
cat: >: No such file or directory
cat: pic2.jpg: No such file or directory
The problem is the redirection.
cat: >: No such file or directory
The way to interpret this error message:
the program cat is trying to tell you about a problem
the problem is that there is no file named >
Indeed, > is not a file. It's not intended as a file, at all. It's a shell operator to redirect output.
You need to use ProcessBuilder to redirect:
ProcessBuilder builder = new ProcessBuilder("cat", "b.jpg", "f1.zip");
builder.redirectOutput(new File("pic2.jpg"));
Process p = builder.start();
When you run a command it doesn't start a shell like bash unless you do this explicitly. This means you are running cat with four arguments b.jpg f1.zip > pic2.jpg The last two files names don't exist so you get an error.
What you are likely to have intended was the following.
String command = "sh -c 'cat b.jpg f1.zip > pic2.jpg'";
This will run sh which in sees > as a special character which redirects the output.
Because you need to start a shell (e.g. /bin/bash) which will execute your shell command, replace:
String command = "cat b.jpg f1.zip > pic2.jpg";
with
String command = "bash -c 'cat b.jpg f1.zip > pic2.jpg'";
On ubuntu server, I can press up arrow to show the last command line which I used, and we can modify it by history -r , for example
$>history
... some command here
...
$> history -r hello.file
$>cat hello.file
aa
$>history
... some command here
...
aa
Of course, when I press up arrow at this time, the command line will give me "aa",
So that, I want some program to help me to do that
my Java sample code is
Runtime r = Runtime.getRuntime();
Process p = r.exec("/bin/bash history -r hello.file");
p.waitFor();
BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = b.readLine()) != null) {
System.out.println(line);
}
b.close();
but it not work, and java didn't print any exception.
I also test by a simple bash file
my bash file:
#!/bin/bash
history -r hello.file
and my test follow is
$>history
... some command here
...
$>sh my_bash_file.sh
$>history
... some command here
...
it still not working...
How can I update the "history" by a program?
Is it impossible?