LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-16-2008, 08:40 AM   #1
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Rep: Reputation: 16
OI! Stuck good.


So my perl foo is weak, but my shell scripting is strong, however I've run into a situation I've never encountered before and now I'm stuck.

So I have a script called "add_host" (Bash)

I need to pass various argument to it for processing.

./add_host <Hostname> <Environment> <Description> <os=linux/aix>

Example: ./add_host eccws531 DEV "Perl Shared 1" linux

So:
eccws531 = $1
DEV = $2


linux SHOULD = $4 and "Perl Shared 1" SHOULD = $3, but the string is broken up as seperate arguments. I can't use shift, because this quoted string will vary in word length. Can I use getopts? I'm not very familiar with it so how would I use it to accomplish this?

I'm stumped.
 
Old 01-16-2008, 09:22 AM   #2
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
it should not be broken, if you have quoted your 3rd argument
Code:
# more test.sh
#!/bin/sh
echo $3
# ./test.sh 1 2 "three with space" 4
three with space
there's one such situation i can think of where it can break, that is
Code:
# more test.sh
#!/bin/sh
for args in $@
do
        echo $args
done
# ./test.sh 1 2 "three with space" 4
1
2
three
with
space
4
therefore we put double quotes
Code:
# more test.sh
#!/bin/sh
for args in "$@"
do
        echo $args
done
# ./test.sh 1 2 "three with space" 4
1
2
three with space
4
 
Old 01-16-2008, 09:44 AM   #3
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
You're right. I missed a part of my issue.

I have a file that has over 800 hosts in it and when I run the ./add_host from the command line and supply the arguments by hand it parses correctly like you demonstrated.

However when I try to feed the list into the script in a for loop

for i in `cat docu.list`;do ./add_host $i;done

The docu.list entries look like:

eccws531 DEV "Perl Shared 1" linux (And so on)

It takes each word as a separate argument? Should I be doing this in a while loop instead?
 
Old 01-16-2008, 10:14 AM   #4
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by RaelOM View Post
Should I be doing this in a while loop instead?
You can do that. However, if you want to use for loop, just do double quotes
Code:
# more file
/home/path/file with spaces
/home/path/normalfile
# for item in `cat file`; do echo "$item"; done
/home/path/file
with
spaces
/home/path/normalfile
# for item in "`cat file`"; do echo "$item"; done
/home/path/file with spaces
/home/path/normalfile
 
Old 01-16-2008, 10:46 AM   #5
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by ghostdog74 View Post
You can do that. However, if you want to use for loop, just do double quotes
Code:
# more file
/home/path/file with spaces
/home/path/normalfile
# for item in `cat file`; do echo "$item"; done
/home/path/file
with
spaces
/home/path/normalfile
# for item in "`cat file`"; do echo "$item"; done
/home/path/file with spaces
/home/path/normalfile
I am failing...

eccws587:/tmp # more docu.list
eccas873 QA "WAS 6.1 SHARED FARM PHASE I" linux

eccws587:/tmp # more g2
#!/bin/bash
echo "Hostname: $1"
echo "Env: $2"
echo "Desc: $3"
echo "OS: $4"

eccws587:/tmp # for i in "`cat docu.list`"; do ./g2 "$i"; done
Hostname: eccas873 QA "WAS 6.1 SHARED FARM PHASE I" linux
Env:
Desc:
OS:
 
Old 01-16-2008, 11:01 AM   #6
h/w
Senior Member
 
Registered: Mar 2003
Location: New York, NY
Distribution: Debian Testing
Posts: 1,286

Rep: Reputation: 46
removed ...

Last edited by h/w; 01-16-2008 at 01:39 PM.
 
Old 01-16-2008, 11:05 AM   #7
h/w
Senior Member
 
Registered: Mar 2003
Location: New York, NY
Distribution: Debian Testing
Posts: 1,286

Rep: Reputation: 46
Nevermind. I just saw your earlier post stating that it works for one input, but not in a loop.
 
Old 01-16-2008, 11:06 AM   #8
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by h/w View Post
Code:
$ cat add_host 
#!/bin/sh
HOST=$1;
ENV=$2;
DESC=$3;
OS=$4;

echo 'HOSTNAME = ' $HOST;
echo 'ENV = ' $2;
echo 'DESC = ' $3;
echo 'OS = ' $4;

exit 0;
Code:
$ ./add_host eccws531 DEV "Perl Shared 1" linux
HOSTNAME =  eccws531
ENV =  DEV
DESC =  Perl Shared 1
OS =  linux
look above
 
Old 01-16-2008, 11:06 AM   #9
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by h/w View Post
Nevermind. I just saw your earlier post stating that it works for one input, but not in a loop.



Yea, thanks for trying to help though.
 
Old 01-16-2008, 01:38 PM   #10
h/w
Senior Member
 
Registered: Mar 2003
Location: New York, NY
Distribution: Debian Testing
Posts: 1,286

Rep: Reputation: 46
Here's a simple awk script to get the different fields...

Code:
$ cat hosts.txt 
eccws531 DEV "Perl Shared 1" linux
eccws531 DEV "Perl Shared 2" linux
eccws531 DEV "Perl Shared 3" linux
eccws531 DEV "Perl Shared 4" linux
eccws531 DEV "Perl Shared 5" linux
eccws531 DEV "Perl Shared 6" linux
eccws531 DEV "Perl Shared 7" linux
eccws531 DEV "Perl Shared 8" linux
eccws531 DEV "Perl Shared 9" linux
eccws531 DEV "Perl Shared 10" linux
eccws531 DEV "Perl Shared 11" linux
eccws531 DEV "Perl Shared 12" linux
eccws531 DEV "Perl Shared 13" linux
eccws531 DEV "Perl Shared 14" linux
eccws531 DEV "Perl Shared 15" linux
eccws531 DEV "Perl Shared 16" linux
Code:
$ awk '{host=$1; env=$2; os=$NF; if(match($0,"\".*\"")){desc=substr($0,RSTART,RLENGTH);}else{desc=""};printf("HOSTNAME=%s\nENV=%s\nDESC=%s\nOS=%s\n\n",host,env,desc,os);}' < hosts.txt
 
Old 01-16-2008, 03:39 PM   #11
Alien_Hominid
Senior Member
 
Registered: Oct 2005
Location: Lithuania
Distribution: Hybrid
Posts: 2,247

Rep: Reputation: 53
Wouldn't perl

@list = ("arguments");
exec foo @list;

work?
 
Old 01-16-2008, 05:05 PM   #12
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
Set the IFS at the top of the script to a newline only. Normally it breaks args on space OR tab OR newline. Note that you have to use a literal newline char eg

#start
IFS=<hit rtn key here>
#end

not
IFS=\n
with or without single/double quotes

alternately you can use

Code:
# How to read file line by line:
while read line
do
  echo "$line"
done <data-file
 
1 members found this post helpful.
Old 01-23-2008, 11:10 AM   #13
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by chrism01 View Post
Set the IFS at the top of the script to a newline only. Normally it breaks args on space OR tab OR newline. Note that you have to use a literal newline char eg

#start
IFS=<hit rtn key here>
#end

not
IFS=\n
with or without single/double quotes

alternately you can use

Code:
# How to read file line by line:
while read line
do
  echo "$line"
done <data-file

Still not working as I expect.....

eccws587:/tmp # while read line
> do
> echo "$line"
> done <docu.list
eccas873 QA "WAS 6.1 SHARED FARM PHASE I" linux
eccws587:/tmp # while read line; do bash -x add_host `echo "$line"`; done <docu.list
+ IFS=
+ PHPLOC=/proj/netops/cacti/php/bin/php
+ CLILOC=/proj/netops/cacti/cacti-0.8.6j/hosting/cli
+ HOSTNAME=eccas873
+ ENV="WAS
+ DESC=QA
+ OS=6.1
+ '[' 9 -ne 4 ']'
+ echo 'Usage: add_host <server name> <env> <desc> <os=linux/aix>'
Usage: add_host <server name> <env> <desc> <os=linux/aix>
+ exit 127
 
Old 01-23-2008, 11:21 AM   #14
RaelOM
Member
 
Registered: Dec 2004
Posts: 110

Original Poster
Rep: Reputation: 16
Here is my script I'm trying to write that will add hosts to cacti from the command line:

Code:
#!/bin/bash

###########################
#
# Author: Rael Mussell
# Date: 1/11/2008 (My Birthday!)
# Purpose: This script is used to add a server to cacti/create the graps/add to proper tree
#
# Usage: add_host -host=<hostname> -env=<DEV/QA/PROD> -desc=<PROJECT> --os=<linux/aix>
#            OR
#            add_host -- this will prompt input
#
############################

IFS=


PHPLOC="/proj/netops/cacti/php/bin/php"
CLILOC="/proj/netops/cacti/cacti-0.8.6j/hosting/cli"

HOSTNAME=$1
ENV=$3
DESC=$2
OS=$4

# Add peak offset ability.

if [ $# -ne 4 ]; then
         echo 1>&2 "Usage: $0 <server name> <env> <desc> <os=linux/aix>"
         exit 127
fi

if [ "$4" == "linux" ]; then
        $PHPLOC $CLILOC/add_device.php --description="$HOSTNAME - $DESC $ENV" --ip=$HOSTNAME.dearborn.ford.com --template=10 --avail=snmp --community=FUSELINUX
        # Add to Tree with Same DESC name
        HOSTID=`$PHPLOC $CLILOC/add_tree.php --list-hosts | tail -2 | head -1 | awk '{print $1}'`
        if [ `$PHPLOC $CLILOC/add_tree.php --list-nodes --tree-id=1 | grep $DESC | wc -l` -eq "0" ]; then
                $PHPLOC $CLILOC/add_tree.php --type=node --node-type=header --tree-id=1 --name=$DESC
                TREEID=`$PHPLOC $CLILOC/add_tree.php --list-nodes --tree-id=1 | grep $DESC | awk '{print $2}'`
        else
                TREEID=`$PHPLOC $CLILOC/add_tree.php --list-nodes --tree-id=1 | grep $DESC | awk '{print $2}'`
                $PHPLOC $CLILOC/add_tree.php --type=node --node-type=host --tree-id=1 --parent-node=$TREEID --host-id=$HOSTID --host-group-style=1
        fi

        # Create Graphs for host
        $PHPLOC $CLILOC/add_graphs.php --graph-type=ds --graph-template-id=79 --host-id=$HOSTID --snmp-query-id=11 --snmp-query-type-id=32 --snmp-field=ifDescr --snmp-value=eth0
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=87 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=53 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=59 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=55 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=56 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=57 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=58 --host-id=$HOSTID
        $PHPLOC $CLILOC/add_graphs.php --graph-type=cg --graph-template-id=88 --host-id=$HOSTID
elif [ "$4" == "aix" ]; then
        echo "This is disabeled until the AIX template is fixed"
        #$PHPLOC $CLILOC/add_device.php --description="$1 - $3 $2" --ip=$1.dearborn.ford.com --template=11 --avail=snmp --community=FUSELINUX
fi
The script works beautifully. Running it by hand I can add the desc name and it can be as long as I want so long as it's encapsulated by " ".

Trying to cart in a list though and the DESC name is treated as seperate arguments per word.

Last edited by RaelOM; 01-23-2008 at 11:25 AM.
 
Old 01-23-2008, 12:20 PM   #15
Big_Vern
LQ Newbie
 
Registered: Jan 2008
Posts: 9

Rep: Reputation: 1
Quote:
Originally Posted by RaelOM View Post
Still not working as I expect.....

eccws587:/tmp # while read line
> do
> echo "$line"
> done <docu.list
eccas873 QA "WAS 6.1 SHARED FARM PHASE I" linux
eccws587:/tmp # while read line; do bash -x add_host `echo "$line"`; done <docu.list
+ IFS=
+ PHPLOC=/proj/netops/cacti/php/bin/php
+ CLILOC=/proj/netops/cacti/cacti-0.8.6j/hosting/cli
+ HOSTNAME=eccas873
+ ENV="WAS
+ DESC=QA
+ OS=6.1
+ '[' 9 -ne 4 ']'
+ echo 'Usage: add_host <server name> <env> <desc> <os=linux/aix>'
Usage: add_host <server name> <env> <desc> <os=linux/aix>
+ exit 127
Perhaps something like this? (re-quoting if necessary)

Code:
Big_Vern:~$ cat text
abc def "ghi jkl" mno

Big_Vern:~$ cat scr

while read line
do
 echo $line
 eval set -a $line
 echo "No 1: $1"
 echo "No 2: $2"
 echo "No 3: $3"
 echo "No 4: $4"
done <text

Big_Vern:~$ ./scr
abc def "ghi jkl" mno
No 1: abc
No 2: def
No 3: ghi jkl
No 4: mno
 
1 members found this post helpful.
  


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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Ahat is a good desktop configuration for maximum compatibility and good performance? aerostarlegacy Linux - Hardware 0 12-12-2007 01:39 AM
What's a good printer that works good with linux? badmofo666 Linux - Hardware 7 02-23-2006 10:10 AM
LXer: Reviewer finds Ubuntu good, but not good enough LXer Syndicated Linux News 0 01-05-2006 06:01 AM
Recommend a good BitTorrent client, and a good CD ripper? audiorevolution Linux - Software 6 06-07-2005 06:36 AM
Good morning, Good evening, Good night. Cheeseboy LinuxQuestions.org Member Intro 2 11-04-2004 09:46 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:29 AM.

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