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 |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
 |
GNU/Linux Basic Guide
This 255-page guide will provide you with the keys to understand the philosophy of free software, teach you how to use and handle it, and give you the tools required to move easily in the world of GNU/Linux. Many users and administrators will be taking their first steps with this GNU/Linux Basic guide and it will show you how to approach and solve the problems you encounter.
Click Here to receive this Complete Guide absolutely free. |
|
 |
|
04-16-2007, 02:00 AM
|
#1
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Rep:
|
passing command line to a BASH function
Here's a wrapper function meant to accept a command to execute and a description.
This should "wrap" commands in a script so that user would see whether smth went wrong.
Code:
COMMAND_WRAPPER () {
printf "%-50s" "$1"
"`$2` 1> /tmp/ws-man.tmp 2>> /tmp/ws-man.tmp" # can't figure out how to make this work
if [ "$?" = "0" ] # execute the command passed and evaluate the result
then
printf "[\E[1;32mdone"
tput sgr0 #reset color; know this is ugly, yet to find a better solution
printf "]\n\n"
return 0
else
printf "[\E[1;31merror"
tput sgr0 #reset color
printf "]\n\n"
printf "=== log start ===\n"
cat /tmp/ws-man.tmp
printf "\n=== log end ===\n"
return 1
fi
}
Now, I can't make the command get executed. I've tried numerous variants, neither worked as expected. The best thing I've got is that the command got executed with redirections treated wrong when doing smth like
Code:
COMMAND_WRAPPER "Creating SVN repo" "svnadmin create $PATH_TO_REPO"
.
Probably it's smth obvious but I'm yet another  who spent a couple of hours banging against the wall  .
TIA.
Last edited by GSMD; 04-16-2007 at 04:06 AM.
|
|
|
|
04-16-2007, 02:37 AM
|
#2
|
|
Senior Member
Registered: Mar 2006
Posts: 1,896
Rep:
|
A couple of prelimary comments:
Using backticks the way you are will cause the output of the command to be (attempted to be) executed. I am not sure that is what you want. (Although perhaps I misunderstand.)
I am not sure whether your redirection might cause problems since you are redirecting two streams to the same file. Since one is a ">" and the other is a ">>" I am not sure what your are trying to do. If you just want to start a new file that contains both stdout and stderr you would usually do it one of the followings ways (all three lines do the same thing):
Code:
command > somefile 2>&1
command 2> somefile 1>&2
command &> somefile
That said, I think the line you want is:
Code:
$* > /tmp/ws-man.tmp 2>&1
This assumes that the command and all of its arguments are different parameters. In other words, don't quote them together as a single argument when you call the function.
Last edited by blackhole54; 04-16-2007 at 02:38 AM.
|
|
|
|
04-16-2007, 02:49 AM
|
#3
|
|
Senior Member
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,211
Rep: 
|
blackhole is right.
you have quoted the whole line, (and you don't need the `backticks`)
so it is read by the shell as a single program with an extremely unusual name!
including the spaces.
(which probably will not exist)
|
|
|
|
04-16-2007, 03:00 AM
|
#4
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Thanks, guys, that's an A+++ class support!
I've implemented
Code:
$2 &> /tmp/ws-man.tmp
.
Last edited by GSMD; 04-16-2007 at 04:06 AM.
|
|
|
|
04-16-2007, 09:18 AM
|
#5
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Banging against the wall again. How should I pass the string like
Code:
COMMAND_WRAPPER "Creating Trac instance" 'trac-admin "$VAR_TEAM_ROOTtrac" initenv "$TEAM $COMPANY project" "qlite:db/trac.db" "svn" "$VAR_TEAM_ROOTsvn" "$TEMPLATES_DIR"'
so that some arguments consist of multiple words?
Thanks.
|
|
|
|
04-17-2007, 01:27 AM
|
#6
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Tried various workaround but neither worked out. Like
Code:
TRAC_COMMAND='trac-admin "$VAR_TEAM_ROOT/trac" initenv "$TEAM $COMPANY project" "sqlite:db/trac.db" "svn" "$VAR_TEAM_ROOT\svn" "$TEMPLATES_DIR/trac/templates"'
COMMAND_WRAPPER "Creating Trac" $TRAC_COMMAND
|
|
|
|
04-17-2007, 01:29 AM
|
#7
|
|
Senior Member
Registered: Mar 2006
Posts: 1,896
Rep:
|
Complex quoting still gives me problems. With that disclaimer (after doing some experiments), I don't see anything wrong with what you are doing (in post #5) unless you need those (what appear to be) variables evaluated when you give the command COMMAND_WRAPPER. Variables are not evaluated inside single quotes. But when your function executes the command trac-admin I would think the single quotes would already be dropped and the variables would get evaluated at that time.
A couple of things you might try (no promises):
You could replace the single quotes with double quotes. If you do that, then you need to "escape" the inner double quotes with a back slashes like so:
Code:
"\"The inner double quotes here are escaped with a back slash\""
The other thing you could try is totally removing the outer (single) quotes and changing this
Code:
$2 > /tmp/ws-man.tmp
to this
Code:
shift
$* > /tmp/ws-man.tmp
The shift throws away the existing first parameter and then changes the orignal second parameter to be first, original third parameter to be second, etc.
If none of this helps, maybe if you post the error message you are getting it will help somebody figure out what is wrong.
EDIT: Clarified that this post was in response to post #5
Last edited by blackhole54; 04-17-2007 at 01:32 AM.
|
|
|
|
04-17-2007, 01:55 AM
|
#8
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Blackhole, thanks for your promptly answers.
I've tried "escaping" double quotes and not using single quotes at all, but this won't help (I'd get a message that only 1 arg is passed to initenv).
For the
Code:
COMMAND_WRAPPER "Creating Trac" 'trac-admin "$VAR_TEAM_ROOT/trac" initenv "$TEAM $COMPANY project" "sqlite:db/trac.db" "svn" "$VAR_TEAM_ROOT\svn" "$TEMPLATES_DIR/trac/templates"'
i get
Code:
Wrong number of arguments to initenv: 7
so "$TEAM $COMPANY project" is obviously treated wrong. So replace it with "$TEAM_$COMPANY_project" and move a bit forward to an error telling that "$TEMPLATES_DIR/trac/templates" is not found. TEMPLATES_DIR is assigned a value right at the previous step (it's an if-then-else). Trying to assign the value manually (TEMPLATES_DIR=/etc/opt/templates) here or at the COMMAND_WRAPPER() won't help either. So I provide a value directly at the command line and finally bump into
Code:
Failed to create environment. [Errno 2] No such file or directory: '/var/opt/ws-man/sample/"$VAR_TEAM_ROOT/trac"
BTW, using "shift" won't help either.
Last edited by GSMD; 04-17-2007 at 02:17 AM.
|
|
|
|
04-17-2007, 11:54 AM
|
#9
|
|
Senior Member
Registered: Nov 2005
Distribution: Debian
Posts: 2,056
|
Try using
Code:
eval $2 &> /tmp/ws-man.tmp
with
Code:
export VAR_TEAM_ROOT=/the/team/root
export TEAM=#fill in the rest...
...
COMMAND_WRAPPER "Creating Trac" 'trac-admin "$VAR_TEAM_ROOT/trac" initenv "$TEAM $COMPANY project" "sqlite:db/trac.db" "svn" "$VAR_TEAM_ROOT/svn" "$TEMPLATES_DIR/trac/templates"'
I assume that backslash was meant to be a forward slash
|
|
|
|
04-19-2007, 04:34 AM
|
#10
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Thanks a lot, ntubski.
eval did sort things out, even w/o exporting variables involved.
And yes, that was a forward slash there.
|
|
|
|
04-19-2007, 07:04 AM
|
#11
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
So that's the way the pre-final version of the function looks like:
Code:
# command wrapper; prints the text and executes commands supplied; then displays the exit status
# $1 - message to display; $* - commands to execute
COMMAND_WRAPPER () {
printf "%-50s" "$1" # print the message
while [ "$#" != "0" ]
do
eval $1 &> /tmp/ws-man.tmp # execute the command
shift
done
if [ "$?" = "0" ] # execute the command passed and evaluate the result
then
printf "[\E[1;32mdone"
tput sgr0 #reset color
printf "]\n"
return 0
else
printf "[\E[1;31merror"
tput sgr0 #reset color
printf "]\n"
printf "=== log start ===\n"
cat /tmp/ws-man.tmp
printf "\n=== log end ===\n\n"
return 1
fi
}
I want to drop out of the cycle if any of the commands returns an error state. So that's what I try to do:
Code:
while [ "$#" != "0" ] && [ "$?" = "0" ]
do
shift
eval $1 &> /tmp/ws-man.tmp # execute the command
done
Yet it won't work (so the loop continues until the last argument).
Could anyone please help sort this out?
Thanks.
|
|
|
|
04-19-2007, 10:44 AM
|
#12
|
|
Senior Member
Registered: Nov 2005
Distribution: Debian
Posts: 2,056
|
$? holds the status of the last command, [ "$#" != "0" ] is a command, so when you test $? it always holds 0.
You could switch the order of the tests, but it would probably be better to save the return status immediately after doing eval.
Code:
RETURNED=0
while [ "$#" != "0" ] && [ "$RETURNED" = "0" ]
do
shift
eval $1 &> /tmp/ws-man.tmp # execute the command
RETURNED=$?
done
|
|
|
|
04-19-2007, 11:16 AM
|
#13
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Thanks. To me it was not obvious, but after reading your reply I recalled that [ "some statement" ] is a shortcut to test "some statement". Thanks again, I'll try this.
|
|
|
|
04-19-2007, 11:22 AM
|
#14
|
|
Member
Registered: Dec 2003
Location: Toronto, Canada
Distribution: Mandriva, Ubuntu, LFS, gNewSense
Posts: 221
Rep:
|
Quote:
|
Originally Posted by blackhole54
That said, I think the line you want is:
Code:
$* > /tmp/ws-man.tmp 2>&1
|
That should be:
Code:
"$@" > /tmp/ws-man.tmp 2>&1
Otherwise multiword arguments will be split. Using "$@" maintains the arguments as given on the command line.
|
|
|
|
04-20-2007, 02:44 AM
|
#15
|
|
Member
Registered: Dec 2005
Distribution: Gentoo
Posts: 87
Original Poster
Rep:
|
Instead of utilizing a variable, I just switched places:
Code:
COMMAND_WRAPPER () {
printf "%-50s" "$1" # print the message
while [ "$?" = "0" ] && [ "$#" != "0" ]
do
shift
eval $1 &> /tmp/ws-man.tmp # execute the command
done
if [ "$?" = "0" ] # execute the command passed and evaluate the result
then
printf "[\e[1;32mdone\e[m]\n"
return 0
else
printf "[\e[1;31merror\e[m]\n"
printf "=== log start ===\n"
cat /tmp/ws-man.tmp
printf "\n=== log end ===\n\n"
return 1
fi
}
|
|
|
|
| Thread Tools |
Search this Thread |
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -5. The time now is 01:32 PM.
|
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|