Reputation: 28659
How can I pass an awk
variable to a bash
command run within awk
?
I'm using awk to calculate a running sum of threads for each of a certain process, but then I want to use each pid to access the /proc/$pid
filesystem.
The line marked broken below is incorrect, because $pid
is non-existent.
How can I export the awk variable pid
to the shell command I get awk
to run?
(Line breaks added for readability)
$ ps -ALf | grep $PROC | grep -v grep | \ # get each pid
awk '{threads[$2]+=1} END \ # count num threads per pid
{ \
for (pid in threads) \
"cat /proc/$pid/cwd"|getline cwd; \ # get 'cwd' (**broken**)
print cwd ": " threads[pid] \ # display 'cwd' and num threads
}'
Upvotes: 3
Views: 2286
Reputation: 141770
You can do the whole lot in awk without any grep
s link this:
% ps -ALf | awk -v proc="${PROC}" '
$0 ~ proc && !/awk/ {
threads[$2] += 1
}
END {
for (pid in threads) {
"readlink /proc/" pid "/cwd" | getline dir
printf "%d: %d %s\n", pid, threads[pid], dir
dir=""
}
}'
A few things worth noting:
-v proc="${PROC}"
assigns the environment variable ${PROC}
to an awk
variable, proc
"readlink /proc/" pid "/cwd"
concatenates the three strings. There's no need for any concatenation operator in awk
.dir=""
resets the dir
variable, in case the symlink is not readable the next time around the loop.Upvotes: 2
Reputation: 47089
You cannot cat /proc/$pid/cwd
it is a symlink to a directory. One way to resolve symlinks is with readlink
from coreutils.
Here is a working example using bits from TrueY and Barmer:
ps -C $PROC |
awk '{ t[$1] } END { for(p in t) { "readlink -f /proc/" p "/cwd" | getline c; print c } }'
A couple of things to notice:
t[$1]
).Upvotes: 4
Reputation: 780663
awk doesn't do variable interpolation inside strings, you just concatenate the variable with the strings (just like you do in the print
statement).
awk '{threads[$2]+=1} END # count num threads per pid
{
for (pid in threads)
("cat /proc/" pid "/cwd")|getline cwd; # get 'cwd' (**broken**)
print cwd ": " threads[pid] # display 'cwd' and num threads
}'
You also don't need all those backslashes. Newlines inside a quoted string don't need to be escaped (and some of them weren't even before newlines, there were comments after them).
Upvotes: 2