0

when the below code is execute if is detected on my pc but when i execute the same command on office pc if is not getting detected what could be possible reason for this ambiguous behavior

$p is one line of text file , xyzxyz if ( abc ) i am using while read to pass line to grep

grep -qw -e 'if(' -e 'if' <<< $p
if [ $? -ne 0 ]; then

do something

fi

closed as unclear what you're asking by αғsнιη, G-Man, Stephen Rauch, Satō Katsura, Anthony Geoghegan Sep 21 '17 at 9:09

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • What OS does your home and office PC run? – Hunter.S.Thompson Sep 20 '17 at 18:58
  • my home pc has linux mint and on office pc , i am using VMplayer running RHEL 6 – user143252 Sep 20 '17 at 18:59
  • if $p is a file, use < (only one <) rather than (three <<< ) – Archemar Sep 20 '17 at 19:00
  • its one line of text file , just like export p='xyzxyz if ( abc )' – user143252 Sep 20 '17 at 19:03
  • 1
    And also, what is the output of grep -ow -e 'if(' -e 'if' <<< $p on both systems? (note the -o). It should be just if I think. – Kusalananda Sep 20 '17 at 19:39
4

Older versions of bash had that bug/misfeature in that in

 cat <<< $var

The content of $var would undergo word splitting (but not globbing) and the resulting words joined with spaces before being put in a temporary file set as input to the cat command.

That was fixed in bash-4.4 to align with the other shells supporting that <<< zsh operator.

For older versions, that's another case where you need to quote your variables.

So if $IFS contained i or f, that could explain the discrepancy:

$ a='if' bash4.1 -c 'IFS=f; cat <<< $a'
i
$ a='if' bash4.4 -c 'IFS=f; cat <<< $a'
if

In any case, note that the -e 'if(' is redundant since if a text contains if( as a word, it also contains a if word.

Also note that bash has regexp matching built-in, so you can always do

re='\<if\>'
if [[ $p =~ $re ]]; then
  printf '"%s" contains a "if" word\n' "$p"
fi

(at least on systems like Linux Mint and RHEL where EREs have those \<, \>, but if your grep supports -w, it's likely EREs will have \< and \> as well).

(above is one of those very rare cases where $p doesn't need to be quoted (though quoting won't harm), and $re must not be quoted (otherwise its content is not taken as a regular expression, but as a fixed string))

With standard sh syntax, you can also do:

case +$p+ in
  (*[^[:alnum:]_]if[^[:alnum:]_]*)
    printf '"%s" contains a "if" word\n' "$p"
esac

To get the same effect.

Not the answer you're looking for? Browse other questions tagged or ask your own question.