5

I have a script that does some housekeeping that works perfectly well when invoked from an interactive shell, but did nothing when invoked by cron. To troubleshoot this I started a shell with a 'blank' environment with the command:

env -i /bin/bash --noprofile --norc

Using this blank env I've dug into my script and found that the following grep will not match any files:

grep -il "^ws_status\s*=\s*[\"']remove[\"']$"

However, when run from an interactive shell the command will return the filenames of the matching files.

As a note, the expression is matching lines like: WS_STATUS = "remove"

Through trial-and-error I discovered that adding -P to the options [Perl regex] the command started working normally in the 'blank' shell. However, I have no idea why my login shell appears to be defaulted to grep -P.

  • There is only one grep binary, /bin/grep
  • There are no aliases defined for grep=pgrep or grep="grep -P"
  • There is no env variable GREP_OPTIONS defined.

What's the deal here?

Note: OS is RHEL v5.10, Bash is v3.2.25, grep is v2.5.1

Sammitch
  • 2,111
  • 1
  • 21
  • 35
  • so in your interactive shell, `which grep` returns `grep -P`? Did you do a recursive grep for "grep -P" in `/etc/profile*`? – Petter H Oct 24 '13 at 18:23
  • @PetterH `which grep` returns `/bin/grep`, and `grep -ri grep /etc/profile*` only prints out a few uses of it in the scripts. – Sammitch Oct 24 '13 at 18:49
  • Rather than `which grep` can you try `type grep`. – Mark Wagner Oct 24 '13 at 19:29
  • @MarkWagner `grep is hashed (/bin/grep)` – Sammitch Oct 24 '13 at 20:18
  • `which` is useless. What does `type -a grep` output? (note the `-a` option) Part of the reason for the difference in behavior is that an interactive shell often has a different `PATH` than the environment of `cron`. – Dennis Williamson Oct 24 '13 at 21:12
  • @DennisWilliamson `grep is /bin/grep`. In both interactive and 'blank' shells. – Sammitch Oct 24 '13 at 23:09
  • OK, so what is it in `cron` (because `cron` isn't "blank"). – Dennis Williamson Oct 25 '13 at 00:43
  • @DennisWilliamson for the purpose of this question we can assume that the cron env and the 'blank' env are equivalent because: A) I was able to replicate the problem in the blank env. B) The solution in the blank env works in the cron env. – Sammitch Oct 25 '13 at 16:11
  • Sorry, I must have missed where the solution was posted. If you mean "adding -P" is the solution, then I disagree because the question is "what's the deal". By the way, `pgrep` is not at all the same as `grep -P`. `pgrep` searches for processes in the process list. – Dennis Williamson Oct 25 '13 at 18:41
  • @DennisWilliamson crap, faulty assumption with grep/egrep/fgrep. Fixed the question title. – Sammitch Oct 25 '13 at 18:58
  • `\s` (and everything else in your pattern) is not `-P` specific in GNU `grep`. Try something that is: `echo 'cookbook' | grep --color 'o.*?'` Without the -P it shouldn't match anything, but with it all the o's should be matched. Try it in your interactive environment and your "blank" environment with and without the `-P`. (you missed a reference to `pgrep` when editing your question.) – Dennis Williamson Oct 25 '13 at 23:16
  • @DennisWilliamson That works the same in both environments, so I guess it's not `-P`, but now I have even less of a clue what's happening. I also just did an `echo echo "^ws_status\s*=\s*[\"']remove[\"']$"` in both envs to see if it might have something to do with the escaping, but that's the same as well. – Sammitch Oct 26 '13 at 00:09
  • Are you 100% sure you are using the same shell in each environment? Sometimes cron runs sh while normal users run bash. Other times there might be a #! in a script you are running. bash handles hash paths differently from sh & the ksh family can be different again (different set of built-ins) – Ken Nov 08 '13 at 16:25
  • @Ken all of my scripts begin with #!/bin/bash – Sammitch Nov 08 '13 at 16:53
  • 1
    I don't have enough rep to comment, but does it help if you use `\grep` with a backslash, instead of `grep`? I know you already said that it wasn't aliased, but in the off chance that it is, this should use an unaliased grep. – sinisterstuf Jun 16 '14 at 10:46
  • Is something setting the ````GREP_OPTIONS```` environment variable? – James Youngman Apr 24 '16 at 13:48
  • @JamesYoungman whatever the problem was I must have solved it way back when. It doesn't look like I've set anything in the environment. Re-reading the question I'm not even sure what the problem was, and the script has been running for the last couple years with `grep -ilP "^ws_status\s*=\s*[\"']remove[\"']"`. – Sammitch Apr 25 '16 at 19:51

1 Answers1

2

Are any of these variables et?

GREP_OPTIONS, LC_ALL, LC_COLLATE, LANG, LC_CTYPE, LC_MESSAGES or POSIXLY_CORRECT

Any of them could affect grep's behavior.

One thing you might try is "set -x" to see the individual commands that get run. You might also move the commands into a shell script and call that from cron. That way you can more easily add commands like set, env, and set -x more easily.

#!/bin/bash
echo SET
set
echo ENV
env
set -x
grep -il "^ws_status\s*=\s*[\"']remove[\"']$"
exit
TomOnTime
  • 7,945
  • 6
  • 32
  • 52