PDA

View Full Version : Bash Question - Noob



victorbrca
February 28th, 2008, 01:35 AM
Would anyone be able to enlighten me why the first one works and the second without "for" loop does not?


#!/bin/bash

function teste() {
for i in "$@" ; do
if [ -d "$i" ] ; then echo "Error: \"$1\" already exists" ; fi
done
}

teste $1



#!/bin/bash

function teste() {
if [ -d "$i" ] ; then echo "Error: \"$1\" already exists" ; fi
}

teste $1

Thanks!!


Vic.

Mr. C.
February 28th, 2008, 01:45 AM
function teste() {
if [ -d "$i" ] ; then echo "Error: \"$1\" already exists" ; fi
}

Think: What is "$i" here ?

MrC

k2t0f12d
February 28th, 2008, 01:57 AM
In

#!/bin/bash

function teste() {
if [ -d "$i" ] ; then echo "Error: \"$1\" already exists" ; fi
}

teste $1

$i is unassigned. Passing

teste $1
does not implicitly cause $i to become the value of $1

The for loop in the first example cycles through the arguments to teste, assigning them incrementally to $i for one iteration each.

victorbrca
February 28th, 2008, 02:00 AM
Think: What is "$i" here ?

MrC

Wow... such a noob.... :mrgreen: Thanks once again for the help Mr. C.


Victor.

victorbrca
February 28th, 2008, 03:51 AM
In

#!/bin/bash

function teste() {
if [ -d "$i" ] ; then echo "Error: \"$1\" already exists" ; fi
}

teste $1

$i is unassigned. Passing

teste $1
does not implicitly cause $i to become the value of $1

The for loop in the first example cycles through the arguments to teste, assigning them incrementally to $i for one iteration each.

Thanks for the reply!!! :)

victorbrca
February 28th, 2008, 09:59 PM
Got another question for the same script. I'm not able to cd into the new folder.

Please keep in mind that these are exercises from a Bash book that I'm reading. I'm sure it will look very disorganized for most of you.



#!/bin/bash

# pasta="$1"

function teste() {
if [ -d "$1" ] ; then
echo "Error: \"$1\" already exists"
exit 1
fi

echo "$1" | grep -e '^[A-Za-z0-9]*$' > /dev/null

d="$?"

if [ "$d" = "0" ] ; then
mkdir -p "$1"
cd `pwd`/"$1"
pwd
elif [ "$d" != "0" ] ; then
echo "Please use letters or numbers only"
exit 1
else
echo "Error"
exit 1
fi
}


teste $1

Martin Witte
February 28th, 2008, 10:17 PM
I pasted this code into a file called script.bash, and then ran it without problems, the directory I gave as argument was created. an you post what error you get?

martin@toshibap200:~$ ./script.bash x
/home/martin/x
martin@toshibap200:~$

victorbrca
February 28th, 2008, 10:29 PM
I pasted this code into a file called script.bash, and then ran it without problems, the directory I gave as argument was created. an you post what error you get?

martin@toshibap200:~$ ./script.bash x
/home/martin/x
martin@toshibap200:~$


I get the same thing, however it should CD into the new created folder, which is not... :-s

Mr. C.
February 28th, 2008, 10:35 PM
What evidence do you have that it is not changing directories? I hope you don't think that script running in a subshell will change your current shell's current working directory!

By the way, this is superfluous code:


cd `pwd`/"$1"

This is sufficient and cheaper:


cd "$1"

The cd command always appends the current directory when its argument is a relative path.

MrC

victorbrca
February 28th, 2008, 11:13 PM
What evidence do you have that it is not changing directories?

Would the script itself also be executed in a subshell or only the loop? So trying something like this would also have no result?


#!/bin/bash

function teste() {
if [ -d "$1" ] ; then
echo "Error: \"$1\" already exists"
exit 1
fi

echo "$1" | grep -e '^[A-Za-z0-9]*$' > /dev/null

d="$?"

if [ "$d" = "0" ] ; then
mkdir -p "$1"
elif [ "$d" != "0" ] ; then
echo "Please use letters or numbers only"
exit 1
else
echo "Error"
exit 1
fi
}

teste $1
cd "$1"
pwd


I only used an absolute path as a failsafe. I thought somehow that it might be the problem.

Thanks!!!


Vic.

Mr. C.
February 28th, 2008, 11:23 PM
Would the script itself also be executed in a subshell or only the loop? So trying something like this would also have no result?


No result whatsoever on your current shell. For that, you can use shell functions.
A script executed is ALWAYS executed in a subshell. Two concepts here to know: execution of a script (aka: exec) or sourcing a script (runs in current shell). The different looks like:


/path/to/myscript
. /path/to/myscript


See Lecture 9, Sub-Shells chapter: http://cis68b1.mikecappella.com/ for more clarification.

MrC

victorbrca
February 29th, 2008, 02:15 AM
...See Lecture 9, Sub-Shells chapter: http://cis68b1.mikecappella.com/ for more clarification.

MrC

Thanks a lot. I gave it a read and the language used on those documents seemed easy enough for a noob like me to understand. I'll use as part of my studies.

The script now works as well... :)

Thanks again...

Vic.

victorbrca
March 20th, 2008, 03:35 AM
Got another one... :???:

This script works:


#!/bin/bash

echo "Enter app name"
read app

ps x | grep "$app" | grep -v 'grep'
echo
echo "Do you want to kill all items? [y|n] "

read resposta
if [ "$resposta" = "y" ] ; then
termina=`ps x | grep "$app" | grep -v 'grep' | awk '{print $1 ; }'`
for i in `echo $termina` ; do
kill -9 "$i"
done
fi


Now this does not:


read resposta
if [ "$resposta" = "y" ] ; then
termina=`ps x | grep "$app" | grep -v 'grep' | awk '{print $1 ; }'`
for i in "$termina" ; do
kill -9 "$i"
done
fi

I get an error that "kill" cannot read the numbers.


./finish.sh: line 16: kill: 6628
6640
6645: arguments must be process or job IDs


Shouldn't "for i in" be able to read "$var"?

Thanks,

Vic.

Mr. C.
March 20th, 2008, 03:46 AM
Consider the difference between these two:


$ var='1 2 3 4'
$ for i in $var; do echo $i ; done
1
2
3
4
$ for i in "$var"; do echo $i ; done
1 2 3 4

victorbrca
March 20th, 2008, 05:27 AM
"...Consider the difference between these two..."

Wow... you are on all of them!!! Thanks again Mr. C...


Vic.