Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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
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. – loadaverage 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. – Harrys Kavan Feb 14 '13 at 8:29

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' – loadaverage 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 :) – loadaverage Feb 18 '13 at 18:00

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. – loadaverage Feb 13 '13 at 23:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .