Collect Linux Command Output

Collect Linux command output

Use Process.getInputStream() to get an InputStream that represents the stdout of the newly created process.

Note that starting/running external processes from Java can be very tricky and has quite a few pitfalls.

They are described in this excellent article, which also describes ways around them.

Get first line of a shell command's output

Yes, that is one way to get the first line of output from a command.

If the command outputs anything to standard error that you would like to capture in the same manner, you need to redirect the standard error of the command to the standard output stream:

utility 2>&1 | head -n 1

There are many other ways to capture the first line too, including sed 1q (quit after first line), sed -n 1p (only print first line, but read everything), awk 'FNR == 1' (only print first line, but again, read everything) etc.

Get system command output in C program

Ok, I was confused in my other answer. In any case, the philosophy in this answer is the same. You can use directly the popen function.

Then you have something like this:

int numOfCPU;
FILE *fp = popen("grep -c ^processor /proc/cpuinfo", "r");

fscanf(fp, "%d", &numOfCPU);
pclose(fp);

I hope it will be useful.

How can I loop over the output of a shell command?

Never for loop over the results of a shell command if you want to process it line by line unless you are changing the value of the internal field separator $IFS to \n. This is because the lines will get subject of word splitting which leads to the actual results you are seeing. Meaning if you for example have a file like this:

foo bar
hello world

The following for loop

for i in $(cat file); do
echo "$i"
done

gives you:

foo
bar
hello
world

Even if you use IFS='\n' the lines might still get subject of Filename expansion


I recommend to use while + read instead because read reads line by line.

Furthermore I would use pgrep if you are searching for pids belonging to a certain binary. However, since python might appear as different binaries, like python2.7 or python3.4 I suggest to pass -f to pgrep which makes it search the whole command line rather than just searching for binaries called python. But this will also find processes which have been started like cat foo.py. You have been warned! At the end you can refine the regex passed to pgrep like you wish.

Example:

pgrep -f python | while read -r pid ; do
echo "$pid"
done

or if you also want the process name:

pgrep -af python | while read -r line ; do
echo "$line"
done

If you want the process name and the pid in separate variables:

pgrep -af python | while read -r pid cmd ; do
echo "pid: $pid, cmd: $cmd"
done

You see, read offers a flexible and stable way to process the output of a command line-by-line.


Btw, if you prefer your ps .. | grep command line over pgrep use the following loop:

ps -ewo pid,etime,cmd | grep python | grep -v grep | grep -v sh \
| while read -r pid etime cmd ; do
echo "$pid $cmd $etime"
done

Note how I changed the order of etime and cmd. Thus to be able to read cmd, which can contain whitespace, into a single variable. This works because read will break down the line into variables, as many times as you specified variables. The remaining part of the line - possibly including whitespace - will get assigned to the last variable which has been specified in the command line.

How do I set a variable to the output of a command in Bash?

In addition to backticks `command`, command substitution can be done with $(command) or "$(command)", which I find easier to read, and allows for nesting.

OUTPUT=$(ls -1)
echo "${OUTPUT}"

MULTILINE=$(ls \
-1)
echo "${MULTILINE}"

Quoting (") does matter to preserve multi-line variable values; it is optional on the right-hand side of an assignment, as word splitting is not performed, so OUTPUT=$(ls -1) would work fine.

How do I execute a command and get the output of the command within C++ using POSIX?


#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>

std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}

Pre-C++11 version:

#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>

std::string exec(const char* cmd) {
char buffer[128];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!");
try {
while (fgets(buffer, sizeof buffer, pipe) != NULL) {
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}

Replace popen and pclose with _popen and _pclose for Windows.

How to get output of a bash command in a variable

You have to include the output of the special standard error output stream:

cmd_output=$(rm "$file" 2>&1)

There are three default streams on every program (that are numbered file descriptors):

0. Standard input (where the program normally reads from)
1. Standard output (where the program normally writes to)
2. Standard error (where the program normally writes error messages)

So to capture the error messages, we must redirect standard error output (stderr) into normal standard output (stdout) which will then be captured by the $(...) expression.

The syntax for redirection is through the > "operator". Immediately before it you tell which file descriptor to redirect (the default is 1, which is stdout). And you can specify it to redirect to a file. If you write an ampersand (&) after it, you force it to redirect into another file descriptor. Therefore, in this example, we redirect file descriptor 2 (stderr) into file descriptor 1 (stdout).

Also, you can also redirect input with < "operator", but in this case the default file descriptor is 0 (stdin).

Another observation is that it is probably good practice to place your $file variable between double quotes, in case it has white space characters.

Hope this helps a little =)

How to store the result of an executed shell command in a variable in python?

Use the subprocess module instead:

import subprocess
output = subprocess.check_output("cat syscall_list.txt | grep f89e7000 | awk '{print $2}'", shell=True)

Edit: this is new in Python 2.7. In earlier versions this should work (with the command rewritten as shown below):

import subprocess
output = subprocess.Popen(['awk', '/f89e7000/ {print $2}', 'syscall_list.txt'], stdout=subprocess.PIPE).communicate()[0]

As a side note, you can rewrite

cat syscall_list.txt | grep f89e7000

To

grep f89e7000 syscall_list.txt

And you can even replace the entire statement with a single awk script:

awk '/f89e7000/ {print $2}' syscall_list.txt

Leading to:

import subprocess
output = subprocess.check_output(['awk', '/f89e7000/ {print $2}', 'syscall_list.txt'])


Related Topics



Leave a reply



Submit