Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a strange issue. My grep has colored output, and if I do something like this:

grep -lr '80' /etc/apache2/sites-available/|xargs ls

I got:

ls: cannot access /etc/apache2/sites-available/default: No such file or directory

But if I add --colour=none to grep, everything is OK.

Where am I wrong?

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

It could be a broken alias. Take a look at your /home/USERNAME/.bashrc (/root/.bashrc) If you see a

alias grep="grep -ARG1 -ARG2"

remove it or customize it as you like.

share|improve this answer
    
I don't think that's the OP's problem, but either way it's easier and more accurate to just type alias. It outputs all aliases in effect. –  ssmy Feb 12 '13 at 15:47
    
There's a good chance that an alias such as alias grep="grep --color always" is involved. –  chepner Feb 12 '13 at 19:13
    
Yes, in this bashrc I have --always, that's the problem here. –  Sloan Feb 13 '13 at 23:47
    
Well, if it was the solution to your problem, i'm glad i could help. And please confirm my answer as the solution by checking the check on the left of this post. –  derty Feb 14 '13 at 8:29
add comment

Where am I wrong?

Here's the problem: You're parsing the output of a command that spits out file names. You should never do that. And if you do, you need to make sure the output is well-formed and file names are properly delimited.*

Usually piping file names to xargs "just works" and it's a "good enough" solution, but it will not work if the command is inserting color control characters into its stdout. The output is meant to be readable for humans, on a terminal, and not by other commands.

The real question is: Why are you doing | xargs ls when grep already prints the file names?

* For example, find … -print0 | xargs -0 is a construct that delimits files with the only character that isn't allowed in file names, so you'll be safe there. However, in most of these cases find … -exec will work just as well.

share|improve this answer
    
Thank you, got it. ls after xargs is a an example, real command is ...|xargs sed -i 's/8080/80/g' –  Sloan Feb 13 '13 at 23:43
    
I see! If you need to replace every occurrence of 80 with 8080, why not run perl -pi -e 's/8080/80/g' /etc/apache2/sites-available/*? –  slhck Feb 14 '13 at 7:47
    
My skills in perl is not good, so far :) –  Sloan Feb 18 '13 at 18:00
add comment

There are typically[0] 3 arguments that can be used with the --color option to grep: "auto", "always", and "none". It seems like your grep may be aliased to use --color always, in which case the ANSI escape codes used to colorize the output are interfering with ls's ability to show them. When you use --color=none, you tell grep not to use these, fixing your problem. The auto option is a good compromise: it says to use color when the output is a terminal, but not to if the output is a file or pipeline, or generally something else where the ANSI codes will not work as intended.

That said, slhck is right and you probably don't need to be piping the output of grep to anything in this case, but it's good to understand the color-related issues for the future.

[0] I say typically, because my man page says you can use "never", "always", and "auto". Perhaps "none" and "never" are synonyms.

share|improve this answer
    
Thank you, using --auto is a very good idea for me. –  Sloan Feb 13 '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.