Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to perform this:

locate pg_type.h | cat

But this command simply does nothing different than locate pg_type.h

What should I change ? I want to perform cat pg_type.h wherever pg_type.h may be.

share|improve this question
1  
You are running locate(1), and sending its output to the input of cat(1), which dutifully copies its input to its output. Nothing to see here, move along. –  vonbrand Feb 26 '13 at 1:02
add comment

2 Answers

up vote 5 down vote accepted
locate -e0 '*/pg_type.h' | xargs -r0 cat

locate pg_type.h would find all the files with pg_type.h in their path (so for instance if there was a rpg_type.horn directory, you'd end up displaying all the files in there).

Without -0 the output of locate can't be post-processed because the files are separated by newline characters while newline is a perfectly valid character in a file name.

cat without arguments writes to stdout what it reads from stdin, so locate | cat would be the same as locate, cat would just pass the output of locate along. What you need is to pass the list of files as arguments to cat.

That's what xargs is typically for: convert a stream of data into a list of arguments. -r is to not call cat if there's no input. Without -0 (which like -r is not standard but found on many implementations, at least those where xargs is useful to anything), xargs would just look for words in its input to convert into arguments, where words are blank separated and where backslash, single and double quotes can be used to escape those separators, so typically not the format locate uses to display file names.

That's why we use the -0 option for both locate and xargs which uses the NUL character (which is the only character not allowed in a file path) to separate file names.

Also note that locate is not a standard command and there exist a great number of different implementations with different versions thereof and different options and behaviours. The code above applies at least to relatively recent versions of the GNU locate and mlocate implementations which are the most common on Linux based operating systems at least.

share|improve this answer
    
+1, and answer for all the good details. It happen that I think locate is much faster than find, and I still have hesitations with find that I should learn however, that's sure... –  Stephane Rolland Feb 25 '13 at 23:32
add comment

Your command passes the output of locate to cat on standard-in. That's not what you want. What you want is to pass the output of locate to cat as an argument.

I believe the way to do that is with xargs:

locate pg_type.h | xargs cat
share|improve this answer
2  
You can also do this with backticks or $(), eg cat $(locate pg_type.h). –  TAFKA 'goldilocks' Feb 25 '13 at 23:20
1  
That assumes none of the paths returned by locate contain any space, tab, newline, blackslash, single or double quote characters. And for $() (@goldilocks), no spc, tab, newline or globbing (*, ?, [) characters. –  Stephane Chazelas Feb 25 '13 at 23:29
    
@StephaneChazelas : Yep. But who would put silly things like that in a path? ;) ;) –  TAFKA 'goldilocks' Feb 25 '13 at 23:38
2  
@goldilocks, Windows/Mac users or anybody that may want to exploit the bug that you're introducing. For instance, if you run that line as root and the output ends up in somewhere world-readable, then somebody may want to create a file called /tmp/ /etc/shadow /pg_type.h to be able to have a look at the content of the /etc/shadow file. Remember some bugs end up being security vulnerabilities, some of which end up exploited. Lets try and have as few bugs as possible in the first place. And that starts with teaching good practice here (or at least mention the limitations/risks). –  Stephane Chazelas Feb 25 '13 at 23:46
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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