0

I have a strange behavior in my terminal.

The following command prints nothing to my terminal:

comment=$(
    cat /usr/share/applications/brasero.desktop | 
    grep '^Comment=' |
    grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'
)
echo $comment

Exactly the same command, same syntax works perfectly inside a bash script.

Usually, i see people complaining about the opposite behavior.

I know that above operation could be done by hundreds of ways, but i can not understand why above command is not operating in my terminal.

On the other hand these commands work ok in both terminal and script:

comment=$(
    cat /usr/share/applications/brasero.desktop |
    grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'
)
echo $comment

grep -Po '(?<=Exec=)[ --0-9A-Za-z/:space:]*' > /usr/share/applications/brasero.desktop

I use GNU bash, version 4.4.0(1)-release (x86_64-pc-linux-gnu), under Debian 8 Sid, with grep (GNU grep) 2.26. I have tried in both xfce and mate terminal but same behavior.

Thanks

  • Why are there #: in front of each line? – Jeff Schaller Nov 4 '16 at 0:29
  • Just to indicate that i run those commands as root. Better to remove it. – George Vasiliou Nov 4 '16 at 0:34
5

When you have problems like this, you should start removing things from your test until you get something that works.

For example, if your starting point is:

comment=$(cat /usr/share/applications/brasero.desktop |grep '^Comment=' |grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*');echo $comment

First strip off the variable stuff:

cat /usr/share/applications/brasero.desktop |grep '^Comment=' |grep -Po '(?<=^Comment=)[ --0-9A-Za-z/.]*'

Then strip off the second grep:

cat /usr/share/applications/brasero.desktop |grep '^Comment='

Then the other grep:

cat /usr/share/applications/brasero.desktop

Eventually you'll find a point where it starts working. In your particular case, it'll start working with this:

cat /usr/share/applications/brasero.desktop |grep '^Comment='

So it's that second grep which is a problem. Add the other stuff back and see if it still works:

comment=$(cat /usr/share/applications/brasero.desktop |grep '^Comment=');echo $comment

Indeed it does. So what's the problem? Well, notice how on this last one, the output was in color? The output has ANSI color escape codes in it. This is preventing the second grep from matching.

The fix is to either change your grep alias to be --color=auto, or do unalias grep, or manually add --color=never to the commands.


There's also another approach that can be taken to this. Since you know that it works from within a script, the only explanation is that it's environmental.

So you can start with a clean environment, bash --noprofile --norc, and start bringing in your profile piece by piece until it breaks.

There is a catch to this technique though. Even with --noprofile --norc, there are a few differences between CLI and a script, such as history expansion, and job control. You can turn these off as well though: set +H and set -m.

  • Great answer. For some reason i had an alias grep='grep --color=always' in my .bashrc. When this grep alias changed to color=auto (or when unalias grep) everything works as expected in CLI. Really thank you. – George Vasiliou Nov 4 '16 at 20:21

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.