I am attempting to do a comparison before I append conditions to a profile.d file

A grep -F 'TMOUT' /etc/profile.d/sh.local shows me exactly what I expect however the test is always showing true. In all of these examples I've already appended the information I want to sh.local but I don't want to do it again if it is present.

[ ! `grep -Fq 'TMOUT' /etc/profile.d/sh.local` ] && echo $?
[ ! `grep -Fq 'NOT_PRESENT' /etc/profile.d/sh.local` ] && echo $?

Although this is for an .ebextension command the tests are failing before I even try to deploy, I imagine the final result should look like this but I'm obviously wrong about something. I've tried using $(grep) vs `grep`. Also ==1 vs !

    test: "[ $(grep -Fxq 'TMOUT' /etc/profile.d/sh.local) ==1 ]"
    command: |
      printf '\nTMOUT=300\nreadonly TMOUT\nexport TMOUT\n' | sudo tee -a /etc/profile.d/sh.local >/dev/null

And for the record this is Amazon Linux 2 and the following commands spit out the following

grep -F 'TMOUT' /etc/profile.d/sh.local
readonly TMOUT
export TMOUT

grep -F 'NOT_PRESENT' /etc/profile.d/sh.local
  • 1
    Just do grep -Fq ... || echo stuff_to_add – Stephen Harris Feb 22 at 21:38
  • Note that bash is a very whitespace-sensitive language: ==1 is NOT the same as == 1 – glenn jackman Feb 22 at 22:22


[ ! `grep -Fq 'TMOUT' /etc/profile.d/sh.local` ] && echo $?
[ ! `grep -Fq 'NOT_PRESENT' /etc/profile.d/sh.local` ] && echo $?

the backticks around the grep command constitute a command substitution, returning the command's standard output. Since you used -q, standard output is always empty so regardless of what string you grep for, your [ ! ... ] tests both become

[ ! ]

This is the "one argument form" of the test construct, and tests the non-emptiness of the one-character string ! - which is always true.

To test the exit status of the grep commands you may use:

grep -Fq 'TMOUT' /etc/profile.d/sh.local && echo $?

See also


[ $(grep -Fxq 'TMOUT' /etc/profile.d/sh.local) ==1 ]


[ ==1 ]

which tests the non-emptiness of string ==1; you probably intended to write == 1 which would at least have errored out with message [: ==: unary operator expected - see

  • Since this is [ not [[, then the absence of quotes is important. The output of the command substitution is empty, so the test becomes [ ! ] -- now that [ only receives one argument, the test becomes: is "!" non-empty? A one-character string is always non-empty, so the test is always true. – glenn jackman Feb 22 at 22:21
  • @glennjackman oops thanks ... will update – steeldriver Feb 22 at 22:23

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.