LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 08-28-2009, 04:55 PM   #1
mijohnst
Member
 
Registered: Nov 2003
Location: Huntsville, AL
Distribution: RHEL, Solaris, OSX, SuSE
Posts: 419

Rep: Reputation: 31
Bash Scripting explanation


Howdy all... I'm writing a simple script to change some security settings and I need someone to explain the -z option in a if statement. The way I understand it, if I have an empty variable then do something... for example:

Code:
for variable in '/bin/grep -i ^banner /tmp/sshd_config'; do
  if [ -z "$variable" ]; then
   sed -i '109i\banner /etc/motd' /tmp/sshd_config
  elif [ -n "$variable" ]; then
   sed -i '/^[Bb]anner/ d' /tmp/sshd_config
   sed -i '108i\Banner /etc/motd' /tmp/sshd_config
  fi
done
So the way I understand it, if grep comes up with nothing, then the string is empty...so in the empty "variable" add it at line 109. If there IS a line that begins with banner anywhere, then delete it and added it on line 108.

Am I misunderstanding something here because it will only run the option with -n. If I change the first option to -n then it run that option. Is the string not really empty? Thanks for the help!

Last edited by mijohnst; 08-28-2009 at 05:03 PM.
 
Old 08-28-2009, 06:14 PM   #2
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by mijohnst View Post
Is the string not really empty?
This script
Code:
#!/bin/bash
BLAH=$(grep -i ^banner blah.sh)
if [ -z "$BLAH" ] ; then
        echo "BLAH has a length of zero"
fi

if [ -n "$BLAH" ] ; then
        echo "BLAH has a non-zero length"
fi
produces this output
Code:
[user@machine:~]:./blah.sh
BLAH has a length of zero
On the other hand, this script
Code:
#!/bin/bash
for variable in $(grep -i ^banner bleh.sh) ; do
        if [ -z "$variable" ] ; then
                echo "variable has a length of zero"
        elif [ -n "$variable" ] ; then
                echo "variable has a non-zero length"
        else
                echo "variable failed all tests"
        fi
done
produces no output
Code:
[user@machine:~]:./bleh.sh
[user@machine:~]:
So, I am going to go with, "The string is not really empty."
 
Old 08-28-2009, 06:16 PM   #3
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Instead of this
Code:
for variable in '/bin/grep -i ^banner /tmp/sshd_config'; do
did you really want this
Code:
for variable in `/bin/grep -i ^banner /tmp/sshd_config`; do
The first one is definitely a non-empty string. The second one executes the command in a sub-shell (note the backticks instead of the single quotes).
 
Old 08-28-2009, 11:17 PM   #4
mijohnst
Member
 
Registered: Nov 2003
Location: Huntsville, AL
Distribution: RHEL, Solaris, OSX, SuSE
Posts: 419

Original Poster
Rep: Reputation: 31
Thanks David1357... your first example worked. I will have to call out a variable instead of using a for loop. For curiosities sake, is it possible to do what I wanted with the for loop? I tried changing the ticks like you recommended but that didn't help. Thanks again for your help! Believe or not, I'm learning...

Last edited by mijohnst; 08-28-2009 at 11:43 PM.
 
Old 08-29-2009, 12:02 AM   #5
i92guboj
Gentoo support team
 
Registered: May 2008
Location: Lucena, Córdoba (Spain)
Distribution: Gentoo
Posts: 4,083

Rep: Reputation: 405Reputation: 405Reputation: 405Reputation: 405Reputation: 405
Quote:
Originally Posted by David1357 View Post
This script
Code:
#!/bin/bash
BLAH=$(grep -i ^banner blah.sh)
if [ -z "$BLAH" ] ; then
        echo "BLAH has a length of zero"
fi

if [ -n "$BLAH" ] ; then
        echo "BLAH has a non-zero length"
fi
produces this output
Code:
[user@machine:~]:./blah.sh
BLAH has a length of zero
On the other hand, this script
Code:
#!/bin/bash
for variable in $(grep -i ^banner bleh.sh) ; do
        if [ -z "$variable" ] ; then
                echo "variable has a length of zero"
        elif [ -n "$variable" ] ; then
                echo "variable has a non-zero length"
        else
                echo "variable failed all tests"
        fi
done
produces no output
Code:
[user@machine:~]:./bleh.sh
[user@machine:~]:
So, I am going to go with, "The string is not really empty."
Nope. The problem with that script is that the contents of for is never run. "for" runs an interation for each element, since there are no elements, there's no looping at all.
 
Old 08-29-2009, 12:59 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
"test" is actually a separate command, the output of which can used by the if statement. 'test foo' and '[ foo ]' are equivalent commands.

test evaluates the expression given to it, and outputs a true-or-false exit value. "[ -z $variable ]" is really saying "the variable is a null string: T/F?", so if it's null the answer is "true", and false otherwise.

The if statement then reads that exit value to decide what to do next.

Another useful way you can test whether a variable is set or not is to use parameter substitution to define a default value.

Code:
if [ ${variable:-novalue}" = "novalue" ]; then
   echo "The variable is unset."
else
   echo "The variable is $variable."
If the variable is empty or unset here, then it will default to "novalue", and test will echo true. If the variable contains something, it will echo false, and if will branch to the alternate action.

This won't work correctly, however, if the variable actually contains the string "novalue" (it will test true), so there's also an operator that works the opposite way:

Code:
if [ "${variable:+setvalue}" = "setvalue" ]; then 
   echo "The variable is $variable."
else
   echo "No variable defined."
fi
In this case, if the variable contains something, then the substitute value will be output in place of it, and test will echo true. Otherwise the test reads false.

Last edited by David the H.; 08-29-2009 at 01:01 AM.
 
Old 08-29-2009, 01:06 AM   #7
mijohnst
Member
 
Registered: Nov 2003
Location: Huntsville, AL
Distribution: RHEL, Solaris, OSX, SuSE
Posts: 419

Original Poster
Rep: Reputation: 31
Thank you all very much for your help. It makes sense now and also explains why I haven't been able to find any "for" examples the way I tried to do it. Thanks again for taking the time! Once again this forum and it's users don't disappoint!

Last edited by mijohnst; 08-29-2009 at 01:09 AM.
 
Old 08-29-2009, 10:29 AM   #8
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by mijohnst View Post
For curiosities sake, is it possible to do what I wanted with the for loop?
Can you post your modified script here? I would like to see your changes before trying to answer this question.
 
Old 08-29-2009, 10:32 AM   #9
David1357
Senior Member
 
Registered: Aug 2007
Location: South Carolina, U.S.A.
Distribution: Ubuntu, Fedora Core, Red Hat, SUSE, Gentoo, DSL, coLinux, uClinux
Posts: 1,302
Blog Entries: 1

Rep: Reputation: 107Reputation: 107
Quote:
Originally Posted by i92guboj View Post
The problem with that script is that the contents of for is never run.
That was implicit in what I was saying. If the string in the original post was empty, the "for" loop would not even get executed. I was merely providing what you might call a proof.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Reading a bash variable in bash scripting problem freeindy Programming 3 11-27-2008 02:29 AM
new to bash scripting peok Programming 2 07-15-2006 02:46 AM
explanation on some bash syntax slzckboy Programming 2 10-02-2005 06:06 AM
Bash Scripting help jgtg32a Programming 5 09-06-2005 09:38 AM
bash scripting vadon Linux - Newbie 6 05-10-2005 04:07 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 04:27 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration