You are not logged in.

#1 2009-04-17 18:48:20

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Simple bash scripting help needed..

I want to learn som simple bash scripting in order to automate various tasks.. Im totally noob, so bear with me smile

First of all I would like to set configs without using nano.. is there a simple command for this? For example if i want change my hostname in /etc/rc.conf.. how can i print the current vallue and how can i change it`?

i was thinking something like this to get the current value:
# cat /etc/rc.conf | grep HOSTNAME=
which returns HOSTNAME="myhostname"

how can i change this value with one or more commands whitout touching the rest of the file?

Offline

#2 2009-04-17 19:01:05

madeye
Member
From: Denmark
Registered: 2006-07-19
Posts: 331
Website

Re: Simple bash scripting help needed..

I believe what you need is "sed". It should (to my knowledge) be able to change text inside files.

Here is a link that may help you on your way
http://www.gentoo.org/doc/en/articles/l-sed1.xml

Happy coding


MadEye | Registered Linux user #167944 since 2000-02-28 | Homepage

Offline

#3 2009-04-17 19:03:35

evr
Arch Linux f@h Team Member
Registered: 2009-01-23
Posts: 554

Re: Simple bash scripting help needed..

i think the sed command would probably be what you are looking for.  I would suggest looking at some tutorials to get used to the syntax which can be alittle confusing.

edit: oops, guess i'm a little too late smile

Last edited by evr (2009-04-17 19:04:08)

Offline

#4 2009-04-17 19:10:26

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

To extract the hostname sed would make a tough time with the optional quotes (I came up with something like sed -n '/HOSTNAME/s/.*="\?\([^"]*\)"\?$/\1/p'). What you can do, because rc.conf is bash source'able is

eval $(grep HOSTNAME /etc/rc.conf)
read -p "The current hostname in rc.conf is $HOSTNAME, enter new name [$HOSTNAME]> " newhost
[ -z "$newhost" ] && exit
sed -i "/HOSTNAME/s/$HOSTNAME/$newhost/" /etc/rc.conf

Offline

#5 2009-04-17 19:15:20

abesto
Member
From: Hungary
Registered: 2009-03-05
Posts: 49
Website

Re: Simple bash scripting help needed..

I was going to post a simple solution, but Procyon beat me to it (and my script wouldn't have been half this elegant). Endre, aren't you Hungarian by chance?

Last edited by abesto (2009-04-17 19:15:43)


Linux user #476135 || Dotfiles hosted by GitHub

Offline

#6 2009-04-17 19:20:48

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

exelent! smile

thanks for the help! ill be back after experimenting a bit with sed and the code..

abesto: no im not hungarian.. full blooded norwegian wink

Offline

#7 2009-04-17 19:27:20

abesto
Member
From: Hungary
Registered: 2009-03-05
Posts: 49
Website

Re: Simple bash scripting help needed..

Well, welcome to the forums anyway smile
Also, once you think the thread is 'finished', please mark it [SOLVED] by editing the opening post and setting the subject there.


Linux user #476135 || Dotfiles hosted by GitHub

Offline

#8 2009-04-20 20:16:29

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

thanks abesto smile been here a while, but inactive for quite some time now, so forgot my username and password.. lol

Procyon's script worked just fine, just what i was thinking.. altough i cant figure out how to get the variable name singeled out..
example:

eval $(grep HOSTNAME /etc/rc.conf)
equals...:
HOSTNAME="whatever"

but if i want to use variables instead of HOSTNAME and /etc/rc.conf
example:

eval $(grep $conf $file)
and say this equals...:
TIMEZONE="Europe/Oslo"

so how do i extract the variable name "TIMEZONE" to use later? how do i get $TIMEZONE in the last example..
this is to avoid bloating the script with many simmilar lines of code..
example:
echo "$TIMEZONE"

hope this makes sense to you.. :-P

Offline

#9 2009-04-20 20:30:48

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

You need variable indirection: ${!var}

So:
$ conf=TIMEZONE
$ file=/etc/rc.conf
$ eval $(grep ^$conf $file)
$ echo ${!conf}
Europe/Oslo

I added a ^ because there is also a timezone string in the comments

Offline

#10 2009-04-20 20:41:10

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: Simple bash scripting help needed..

BTW, that method of variable indirection ( ${!var} ) works great in bash, but I don't think it's very portable.  You can also use eval to do the same:

$ conf=TIMEZONE
$ file=test.txt
$ cat > test.txt
TIMEZONE="Eastern"
$ eval $(grep ^$conf $file)
$ echo ${!conf}
Eastern
$ eval echo \$$conf
Eastern

Offline

#11 2009-04-20 21:08:44

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

the ${!conf} worked fine! thanks again Procyon..

please explain "portable", im totally noob.. is this important?

could'nt get the "\$$conf" to work.. i dont think the eval works in this specific context.. currently in the title of a 'dialog' box..

Offline

#12 2009-04-21 19:29:01

abesto
Member
From: Hungary
Registered: 2009-03-05
Posts: 49
Website

Re: Simple bash scripting help needed..

"portable" here means that it won't work in some other shell interpreters. Unless you plan on distributing the script or running it from another shell, this isn't really a problem. I'm not sure which shells do/don't support ${!var} but that's the general idea.


Linux user #476135 || Dotfiles hosted by GitHub

Offline

#13 2009-04-21 20:01:19

kumyco
Member
From: somewhere
Registered: 2008-06-23
Posts: 153
Website

Re: Simple bash scripting help needed..

export HOSTNAME= eval $(grep '^[ ]*HOSTNAME=' /etc/rc.conf)

$HOSTNAME contains your variable
export HOSTNAME to clear any previous definition
ignored white-space at the start of the line, the line must start with HOSTNAME= because you might have another copy commented out
only requires grep and cut so should be pretty portable I'd assume

EDIT: Better?

Last edited by kumyco (2009-04-21 20:14:48)

Offline

#14 2009-04-21 20:08:37

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

@kumyco: Only the last of the dual delimiters works and you miss the case of no quotes at all.

Offline

#15 2009-04-22 20:24:52

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

thanks for all the help.. another question for you guys..

i need a way to check if some_text is in the list_of_text

example

CHOICE="lisa"
NAMES="homer marge lisa bart maggie"

if [ $CHOICE is_anywhere_in_the_list $NAMES ]; then
  echo "this is how you do it"
elif [ the same but with other variables ];then
elif [ the same but with other variables ];then
elif [ the same but with other variables ];then
fi


so a loop or something to do this.. been reading on tldp, but cant figure it out :-P

Last edited by endre84 (2009-04-22 20:39:21)

Offline

#16 2009-04-22 20:45:42

abesto
Member
From: Hungary
Registered: 2009-03-05
Posts: 49
Website

Re: Simple bash scripting help needed..

A slightly naive solution:

CHOICE="lisa"
NAMES="homer marge lisa bart maggie"

if [ "`echo \" $NAMES \" | grep \" $CHOICE \"`" ]; then
  echo "this is how you do it"
fi

The extra spaces inside the escaped quotes are to ensure that only a whole word is "matched".

You can also replace the elif's with a loop through a list of "the other variables". Then you'd use the loop variable instead of $CHOICE above.


Linux user #476135 || Dotfiles hosted by GitHub

Offline

#17 2009-04-22 20:48:34

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

CHOICE="lisa"
NAMES="homer marge lisa bart maggie"
if [[ $NAMES =~ $CHOICE ]]; then echo match; fi

Offline

#18 2009-04-23 09:37:17

klixon
Member
From: Nederland
Registered: 2007-01-17
Posts: 525

Re: Simple bash scripting help needed..

abesto wrote:

A slightly naive solution:

CHOICE="lisa"
NAMES="homer marge lisa bart maggie"

if [ "`echo \" $NAMES \" | grep \" $CHOICE \"`" ]; then
  echo "this is how you do it"
fi

The extra spaces inside the escaped quotes are to ensure that only a whole word is "matched".

You can also replace the elif's with a loop through a list of "the other variables". Then you'd use the loop variable instead of $CHOICE above.

grep can check on word-bounderies with \< and \>, or with the -w switch. The -q switch suppresses any messages and exits with exit-code 0 when the first match is found:

if echo "${NAMES}" | grep -qw "${CHOICE}"; then

Nice and readable, should work, but i haven't tested it

EDIT:

Procyon wrote:

CHOICE="lisa"
NAMES="homer marge lisa bart maggie"
if [[ $NAMES =~ $CHOICE ]]; then echo match; fi

This one also matches elisa, ie. no check on word bounderies. You should be carefull with that wink

Last edited by klixon (2009-04-23 09:40:22)


Stand back, intruder, or i'll blast you out of space! I am Klixon and I don't want any dealings with you human lifeforms. I'm a cyborg!

Offline

#19 2009-04-23 10:21:12

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Simple bash scripting help needed..

I was wondering how to fix that, but \<$CHOICE\> or \b$CHOICE\b doesn't seem to work with =~

Offline

#20 2009-04-23 15:17:39

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

if echo "${NAMES}" | grep -qw "${CHOICE}"; then

Worked like a charm, thanks klixon..

had to change it a littlebit though.. had to remove the {} around the last variable.. and remove the -q in grep to keep it from exit..

if echo "${NAMES}" | grep -w "$CHOICE"; then

Last edited by endre84 (2009-04-23 15:39:46)

Offline

#21 2009-04-23 20:27:08

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

i need more help guys.. a bit complicated this time.. not to good at explaining it :-P hope you understand....


NAMES="homer !marge lisa bart !maggie"
NUMBER="how do i get the number of whole words in $NAMES here?" (5 in this case)
COUNTER="1"

while [ $COUNTER is_less_than_or_equal_to $NUMBER ]
do
PERSON="how do i get the name number $COUNTER from $NAMES" (but without the ! if there is any..) ($COUNTER 2 would set $PERSON to "marge")
TRUE="did the name start with !   ?" (with value "yes" or "no") (  ! = no  )

output all this to a file in the following format: (including the \ )

"$COUNTER" "$PERSON" "$TRUE" \
"$COUNTER" "$PERSON" "$TRUE" \
"$COUNTER" "$PERSON" "$TRUE" \
"$COUNTER" "$PERSON" "$TRUE" \
"$COUNTER" "$PERSON" "$TRUE" \


COUNTER=$(( $COUNTER + 1 ))
done


basically i want a file like this

"1" "homer" "yes" \
"2" "marge" "no" \
"3" "lisa" "yes" \
"4" "bart" "yes" \
"5" "maggie" "no" \

then i want to insert this into the script as if it was in there already if possible.. ?? like in the eval $(grep HOSTNAME /etc/rc.conf)....

Last edited by endre84 (2009-04-23 20:30:52)

Offline

#22 2009-04-23 20:39:04

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

final edit:

> cat .bin/testing
#!/bin/bash

names='homer !marge lisa bart !maggie'

count=1
for name in $names; do
  if [ "$name" = "$(echo $name | tr -d '!')" ]; then
    echo "\"$count\" \"$name\" \"yes\" \\"
  else
    echo "\"$count\" \"$(echo $name | tr -d '!')\" \"no\" \\"
  fi
  count=$((count+1))
done

> .bin/testing
"1" "homer" "yes" \
"2" "marge" "no" \
"3" "lisa" "yes" \
"4" "bart" "yes" \
"5" "maggie" "no" \

could be cleaned up a bit

Last edited by brisbin33 (2009-04-23 21:12:28)

Offline

#23 2009-04-23 21:53:43

klixon
Member
From: Nederland
Registered: 2007-01-17
Posts: 525

Re: Simple bash scripting help needed..

You can simplify this a bit:

$name | tr -d '!'

like this:

${name#!}

Which means you can do this

if [ ${name} = ${name#!} ]; then

Last edited by klixon (2009-04-23 21:55:07)


Stand back, intruder, or i'll blast you out of space! I am Klixon and I don't want any dealings with you human lifeforms. I'm a cyborg!

Offline

#24 2009-04-24 16:01:07

endre84
Member
From: Norway
Registered: 2009-04-15
Posts: 18

Re: Simple bash scripting help needed..

brisbin33: just what i meant, unbelievable that you understood that.. lol

is it possible to insert text from a file directly into the script, so that it works as if it was written in the script and not in a seperate file? this is supposed to be a dialog menu with checkboxes...

so for example:

the script  should look like this:

dialog --title "The Simpsons" \
--checklist "The characters in The Simpsons" 25 50 17 \
"1" "homer" "yes" \
"2" "marge" "no" \
"3" "lisa" "yes" \
"4" "bart" "yes" \
"5" "maggie" "no" \


but i need to get the values in the list from a text file, so is there a way to do this?

dialog --title "The Simpsons" \
--checklist "The characters in The Simpsons" 25 50 17 \
THE_COMMAND_TO_INSERT_THE_LIST_FROM_THE_FILE


or is this not possible'`??

Last edited by endre84 (2009-04-24 16:21:30)

Offline

#25 2009-04-24 17:36:40

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Simple bash scripting help needed..

ok this one's gonna be more of a hint than an outright answer.

for name in $(cat $list); do

and if my guess at your overall goal is right, i think you'll run into another problem once you've solved that one... 

my recommendation?

echo "dialog..." >> $file
echo "--checklist..." >> $file
for name in...
   if...
      echo "... yes" >> $file
   else...
      echo "... no" >> $file
   fi
done

cat $file | zenity 

exit 0

i hope you can fill in what i've left out... wink

Offline

Board footer

Powered by FluxBB