7
> strace w 2>&1 | grep urandom
read(4, "/usr/bin/grep\0urandom\0", 2047) = 22
> 

Why does "w" need urandom? How to avoid this?

UPDATE:

> strace w 2>&1 | awk '/urandom/'
read(4, "awk\0/urandom/\0", 2047)       = 14
> 

so it is the filtering that has something to do with urandom?

> strace who 2>&1 | grep urandom
> 

Then why isn't "who" affected?

  • 1
    It's not w which needs urandom. It's becase Piped commands run concurrently: unix.stackexchange.com/questions/37508/… – Arkadiusz Drabczyk Apr 24 '17 at 18:02
  • @ArkadiuszDrabczyk Makes sense. There is no urandom access in w source code. – Rui F Ribeiro Apr 24 '17 at 18:04
  • 2
    You're seeing the second command in the pipeline, your grep and your awk. It's not w opening the /dev/urandom device file. It's similar to ps -aux | grep grep – Kusalananda Apr 24 '17 at 18:04
  • 1
    @RuiFRibeiro: correct, I also checked it to make sure. I think this question could be now marked as a duplicate. – Arkadiusz Drabczyk Apr 24 '17 at 18:05
  • 1
    You can ask the question about unicorns: strace w 2>&1 | grep unicorns ;-) – Digital Trauma Apr 24 '17 at 21:29
8

As explained in other answers and comments the reason for what you observe is the way Bash handles pipes. In order to filter what you really want in similar situations you can try to enclose the first letter of the grep argument in [] like this:

$ strace w 2>&1 | grep random
read(4, "grep\0random\0", 2047)         = 12
$ strace w 2>&1 | grep '[r]andom'
$ strace w 2>&1 | grep '[c]lose'
close(3)                                = 0
close(3)                                = 0
close(3)                                = 0
close(3)                                = 0
close(3)                                = 0
close(3)                                = 0
(...)

EDIT:

As correctly noted by R. in the comment below in fact strace does not see the other side of the pipe. Similarly to ps aux | grep grep which also shows grep grep in its output w is is walking through /proc directory and finds grep process there.

  • 2
    Happy to see someone else doing this (although I usually bracket the last letter instead) with ps/strace etc. Easiest way to keep it from finding its own command line. – Monty Harder Apr 24 '17 at 21:29
  • This trick seems to be becoming widely known. I've heard that it is listed in some FAQs, and it's mentioned many times here on Stack Exchange. – Scott Apr 25 '17 at 0:51
  • 1
    This answer, and the comments on the question itself saying roughly the same thing, are simply wrong. The other answer (by ilkkachu) is right. strace does not (and cannot, in any easy way) trace the other commands in the shell pipeline. Rather, w is looking up the current commands being executed on your terminal (and other terminals), and runs across the grep as part of its work. – R.. Apr 25 '17 at 2:14
  • Correct, thx, I updated my answer. – Arkadiusz Drabczyk Apr 25 '17 at 6:36
15

From the manpage w(1):

w displays information about the users currently on the machine, and their processes

To display the users' processes, it goes through all processes running on the machine. Let's try this:

$ strace -o w.trace w | grep whatever

Inside the trace we find lines like these (on a Linux system):

open("/proc/8286/cmdline", O_RDONLY)    = 4
read(4, "grep\0whatever\0", 2047)       = 14

Which shows w explicitly going through /proc and looking at the command lines of all processes (and other things, not shown). It finds the grep that runs parallel to it and that's what strace sees it do. The pipe has nothing to do with it, other than starting both processes at the same time. In a way, it is similar to ps | grep seeing the grep itself.

who and most other commands don't need the information about the processes, and don't go looking, so you don't see the same when tracing them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.