sprucio
January 22, 2012, 11:39am
1
I'm writing a Korn script but am having trouble because the shell interprets the asterisk in this case. Can anyone tell me if there is a way to fix this so that grep takes in STDIN without the interpretation?
line="30 09 * * 1-4 /home/user01/bin/start"
echo "$line" | grep 'start'
I am not sure what you mean. With the example that you provided, the shell will not interpret the asterisks.
sprucio
January 22, 2012, 12:01pm
3
You are correct .. I thought I typed those in manually in to the shell and tested it ... How about this? It's more of what the script looks like:
#!/bin/ksh
line="01 01 * * 5 /home/user01/bin/start"
if [ $( echo "$line" | grep 'start' ) ]
then
start="$final"
fi
print $start
It fails at the if statement.
Try this...
#!/bin/ksh
line="01 01 * * 5 /home/user01/bin/start"
if grep -q 'start' <<<$line
then
start="$final"
fi
echo $start
Hope somewhere you have final populated!
--ahamed
sprucio
January 22, 2012, 12:15pm
5
Sorry, $final is populated somewhere in the script ... In the following script, I modified it so that it just uses $line instead.
$ cat g.ksh
#!/bin/ksh
line="01 01 * * 5 /home/user01/bin/start"
if grep -q 'start' <<<$line
then
start="$line"
fi
echo $start
$ ./g.ksh
./g.ksh[5]: syntax error at line 5 : `<' unexpected
change the <<< to << 2 "<" characters not 3
if echo "$line" | grep -q 'start'
then
start="final"
fi
--ahamed
Try:
#!/bin/ksh
final="test bla bla"
line="01 01 * * 5 /home/user01/bin/start"
if echo "$line" | grep 'start' >/dev/null 2>&1
then
start="$final"
fi
echo "$start"
Or without external programs...
#!/bin/ksh
final="test bla bla"
line="01 01 * * 5 /home/user01/bin/start"
case $line in
*start*) start="$final"
esac
echo "$start"
agama
January 22, 2012, 12:32pm
9
Why use grep at all? Take advantage of Kshell's pattern matching:
#!/usr/bin/env ksh
final="test bla bla"
line="01 01 * * 5 /home/user01/bin/start"
if [[ $line == *"start"* ]]
then
start="$final"
fi
Depending on how this is being used, and thus the number of grep processes that are avoided, this is much more efficient.
1 Like
agama:
Why use grep at all? Take advantage of Kshell's pattern matching:
#!/usr/bin/env ksh
final="test bla bla"
line="01 01 * * 5 /home/user01/bin/start"
if [[ $line == *"start"* ]]
then
start="$final"
fi
Depending on how this is being used, and thus the number of grep processes that are avoided, this is much more efficient.
Why limit it to ksh? Scrutinizer's case statement (which also avoids external commands) will work in all Bourne-type shells.
1 Like
agama
January 22, 2012, 4:31pm
11
Right. I missed the case example and specifically mentioned kshell because the original post indicated kshell was being used.
sprucio
January 22, 2012, 5:50pm
12
Hey guys,
Thanks for all the input so far. It's been really helpful. It looks like this line is working currently:
if [[ $line == *"start"* ]]
In this following snippet, line 9 only needs one set of square brackets but lines 13 and 16 needs two set of square brackets. Any thoughts?
8 function match {
9 temp=$( echo "$line" | egrep '(start|stop)' )
10
11 if [ ! -z "$temp" ]
12 then
13 if [[ $( echo "$temp" | grep 'start') ]]
14 then
15 start="$temp"
16 elif [[ $( echo "$temp" | grep 'stop') ]]
17 then
18 end="$temp"
19 fi
20 fi
21 }
agama
January 22, 2012, 6:04pm
13
The open square bracket [
is a symbolic link to the test command and gives the appearance of wrapping the expression in parenthesis-like format that most programmers are used to. The double bracket, is a part of the shell syntax.
The expression that appears between single brackets is given to the test command while the expression inside of double brackets is interpreted by the shell. The shell interpretation supports the evaluation of the command exit code like you want to do, while the test command does not and that is why you need the double brackets where you've discovered that you do.
In my humble opinion, there is rarely a case where single brackets (the test command) are needed; using double bracketed expressions is much more efficient especially when loops are involved.
sprucio:
Hey guys,
Thanks for all the input so far. It's been really helpful. It looks like this line is working currently:
if [[ $line == *"start"* ]]
In this following snippet, line 9 only needs one set of square brackets but lines 13 and 16 needs two set of square brackets. Any thoughts?
8 function match {
9 temp=$( echo "$line" | egrep '(start|stop)' )
10
11 if [ ! -z "$temp" ]
12 then
13 if [[ $( echo "$temp" | grep 'start') ]]
14 then
15 start="$temp"
16 elif [[ $( echo "$temp" | grep 'stop') ]]
17 then
18 end="$temp"
19 fi
20 fi
21 }
You don't need grep, and you don't need double (or single) brackets.
Use case:
match() {
case $line in
*start*) start=$line ;;
*stop*) end=$line ;;
esac
}
---------- Post updated at 06:12 PM ---------- Previous update was at 06:06 PM ----------
The open square bracket [
is a shell builtin command, and it is synonymous with test
:
$ type test [
test is a shell builtin
[ is a shell builtin
IMNSHO, there is rarely a case where double brackets are needed (I never use them).
The double brackets are not part of the POSIX definition of the shell, and thus are less portable.
agama
January 22, 2012, 6:38pm
15
cfajohnson:
[indent]
The open square bracket [
is a shell builtin command, and it is synonymous with test
:
$ type test [
test is a shell builtin
[ is a shell builtin
This I didn't realise, mostly because /usr/bin/[ seems to persist everywhere. Wrongly, I assumed it still then required a fork/exec to use it. Thanks for the correction.
POSIX requires that regular built-in commands also exist as separate binaries.
Indeed. One of the reasons why [/usr]/bin/cd is available in POSIX compliant OSes.