Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I need to be able to write whether the test for a grep is either TRUE or FALSE to a variable so I can use it later

For the following, if I run

defaults read com.apple.Finder | grep "AppleShowAllFiles"

on my system, it would return

AppleShowAllFiles = FALSE;

Cool. So now I want to pipe this response to a test of some kind. This is where I get stuck.

I think if I can pipe/assign this output to a specified variable, I would be able to run a test on it. Now, just say, I've assigned the value of this output to a variable, in this case I will use $ASAF as my variable, I can run it in a test like this

if [ $ASAF = "AppleShowAllFiles = TRUE;" ]; then
defaults write com.apple.Finder AppleShowAllFiles FALSE
killall Finder
else
defaults write com.apple.Finder AppleShowAllFiles True
killall Finder
fi

If there is some other way to do this, I would be more than open to options. I've not had to do something like this for a while, and I'm a bit stumped. I searcehd Google a bit, but it was all answers without explanations and using the return value of 0 or 1. I think the returned output being assigned to a variable would be more appropriate, as then I can use it over and over in the script as need be.

share|improve this question
add comment

3 Answers 3

up vote 1 down vote accepted

If you just want to save the return code (success/failure) of a command, use $?:

# grep -q to avoid sending output to `stdout` and to stop if it finds the target.
defaults read com.apple.Finder | grep -q "AppleShowAllFiles"
NOTFOUND=$?

# Note that we use an *arithmetic* test, not a string test, and that we have to
# invert the arithmetic value.

if ((!NOTFOUND)); then
  # not NOTFOUND is FOUND
  # ...
fi

Alternatively, you could save the output in a variable, if, as in your example, you need the actual string. If so, your solution is reasonable, but be aware that parsing the output of programs like defaults can be quite brittle, since minor format changes will make patterns suddenly fail to match. Try to make your patterns as general as possible:

# Here we use the `-m1` flag to stop matching as soon as the first line matches
ASAF_STRING=$(defaults read com.apple.Finder | grep -m1 "AppleShowAllFiles")

# Try to parse true or false out of the string. We do this in a subshell to
# avoid changing the shell option in the main shell.
ASAF=$(
  shopt -s nocasematch
  case $ASAF_STRING in 
    *true*) echo TRUE;;
    *false*) echo FALSE;;
    *) echo Could not parse AppleShowAllFiles >> /dev/stderr;;
  esac
)
share|improve this answer
add comment

I see two ways of doing this, depending on whether you actually need the variable more than once or not.

If you only need the variable once, you can just combine the grep into your if statement, i.e.

if defaults read com.apple.Finder | grep -q "AppleShowAllFiles" ; then ...

Or, if you need to use the variable more than once, you could do something like this

defaults read com.apple.Finder | grep -q "AppleShowAllFiles"

ASAF=$? ##$? is equal to the return value of the last command

if [ "$ASAF" -eq "0"]; then ...

share|improve this answer
    
Can you add a little more to you answer. I noticed you don't break the if/then statement onto many lines. You put a ; at the end of a line and continue, how do you end the line? Can you give me a simple grep test. Even if it is just jibberish? –  Danijel J Sep 28 '13 at 15:25
add comment

You don't need to use grep at all:

[[ $(defaults read com.apple.finder AppleShowAllFiles)  0 ]] && bool=true || bool=false
defaults write com.apple.finder AppleShowAllFiles -bool $bool
osascript -e 'quit app "Finder";

defaults read prints boolean values as 1 or 0.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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