3

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?

3 Answers 3

1

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.

4
  • 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, 2013 at 15:47
  • There's a good chance that an alias such as alias grep="grep --color always" is involved.
    – chepner
    Feb 12, 2013 at 19:13
  • Yes, in this bashrc I have --always, that's the problem here. Feb 13, 2013 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. Feb 14, 2013 at 8:29
3

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.

3
  • Thank you, got it. ls after xargs is a an example, real command is ...|xargs sed -i 's/8080/80/g' Feb 13, 2013 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, 2013 at 7:47
  • My skills in perl is not good, so far :) Feb 18, 2013 at 18:00
1

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.

0

You must log in to answer this question.

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