Hi. I'm using !/bin/ksh. I used to be decent at shell programming years ago, but now I am extremely rusty. HELP
My team has a script that takes user input from screen. The user enters grep A0 /dir/dir1/dir2/*filename*. The code works if they enter a filename or directory. It doesn't work if user enters *filename* (or filename*). User gets 'no matches found'.
func_grep()
{
getstr "Search command: " cmdstr
search_cmd=`echo $cmdstr | awk '{ print $1 }'`
expandstr "$cmdstr" /* expandstr assigns v1_file. This part is working
cmd_opt=`echo $cmdstr | awk 'NF > 3 { print $2 }'`
search_key=`echo $cmdstr | awk '{ print $(NF-1)}'`
chk_str $v1_file /*checks for '../'
if [ $? -eq "0" ]
then
if [ -d $v1_file ] # if input is directory then append "*" to
then # search for entire directory
v1_file="$v1_file/*"
fi
$search_cmd $cmd_opt $search_key $v1_file > /ercs/ercs000/reports/grep_$LOGNAME
case $? in
0) echo "\nThe grep output file: /ercs/ercs000/reports/grep_$LOG
NAME has been created." ;;
1) echo "\n\tNo matches were found." ;;
*) echo "\n\tSyntax errors or inaccessible files."
echo "\t$search_cmd $search_key $v1_file"
return 1 ;
esac
}
---------- Post updated at 02:55 PM ---------- Previous update was at 11:41 AM ----------
Ok no replies. In the meantime, I've done some trouble shooting at the command line and figured out that the assignment below in the expandstr function is not working when greping the 'path/*file*' because the $NF contains only the last file name in *file* (instead of all the names) which is because they are delimited by a space.
v1_file=`echo $1 | awk '{ print $NF }`
So I need to capture in a variable everything after
$search_key (/path/file1 /path/file2 /path/file3 etc)
. Any suggestions on how to accomplish that. Hope this is clear.
I wonder how your script can handle * wildcard at all because variables are not in quotes.
Variables in command arguments must be in quotes, otherwise the shell tries to expand them.
And where are the functions chk_str and expandstr?
Thank you so much,
Yes, that is the problem. It is not working and apparently never has (don't ask - lol). When user enters a directory path or directory file name it works fine. Just to reiterate, the user enters grep A0 /dir1/dir2/*partialfilename*
. partialfilename* doesn't work either. Everything is called from func_grep()
chk_str()
23 {
24 if [ -f "$1" -o -d "$1" ]
25 then
26 return 0
27 else
28 echo "\n\tAccess to this file/directory is not allowed."
29 return 1
30 fi
31 }
expandstr()
47 {
48 v1_file=`echo $1 | awk '{ print $NF }`
49 cmd_opt=`echo $1 | awk 'NF > 1 { print $1 }'`
50 v1_file=`trim_str $v1_file`
51 if [ "$v1_file" = "/etc/passwd" -o "$v1_file" = "/etc/ftp.allow" ]
52 then
53 return
54 elif [ "$v1_file" = "${v1_file#/ercs}" ]
55 then
56 v1_file=$TopDir/$v1_file
57 fi
58 }
trim_str()
15 {
16 echo $1 | sed 's/\.\.\///g'
17 }
And get_str? What is get_str? And where does $v1_file come from?
Honestly, it'd be better to replace this stuff than fix it. It's all a horrible mess. Most of that top code could have been just
read cmdstr cmd_opt search_key
instead of 5 lines of echo | awk.
They're not using if-statements properly either. They could have just done
if chk_str "$arg"
then
...
else
...
fi
Also, that "/* ... */" style comment is not treated as a comment by the shell! It should be command stuff # comment stuff
instead!
Also, never use \n \t etc in echo. You can use them in printf, which has unique restrictions of its own. For your purposes, printf "%s\n" "string"
is equivalent to echo "string"
. Put extra newlines in the first part, not the second part, if you need them.
Note that v1_file/* won't expand recursively. It'll fill in the lowermost directory tree and that's it.
My first try:
func_grep() {
read cmdstr cmd_opt search_key # Read arguments from keyboard, separated by space
check_str "$cmdstr" || return 1 # Return immediately on error
expandstr "$cmdstr"
[ -d "$v1_file" ] && v1_file="$v1_file/*" # Expand dir
# $v1_file can't be quoted for * to work, everything else should be quoted.
"$search_cmd" "$cmd_opt" "$search_key" $v1_file > "/ercs/ercs000/reports/grep_$LOGNAME"
case $? in
0) printf "\n%s\n" "The grep output file: /ercs/ercs000/reports/grep_$LOGNAME has been created." ;;
1) printf "\n\t%s\n" "No matches were found." ;;
*) printf "\n\t%s\n" "Syntax errors or inaccessible files."
printf "\t%s\n" "$search_cmd $search_key $v1_file"
return 1 ;
esac
}
I'm going to be off a while. I'll have to study your responses. I will get back with you guys. Thanks for the help. v1_file came from the expandstr function. Getstr gets the grep command the user typed in. It's all there, just out of order.