LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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

Reply
 
Search this Thread
Old 04-16-2007, 02:00 AM   #1
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Rep: Reputation: 16
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.
 
Old 04-16-2007, 02:37 AM   #2
blackhole54
Senior Member
 
Registered: Mar 2006
Posts: 1,896

Rep: Reputation: 61
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.
 
Old 04-16-2007, 02:49 AM   #3
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,287

Rep: Reputation: 173Reputation: 173
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)
 
Old 04-16-2007, 03:00 AM   #4
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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.
 
Old 04-16-2007, 09:18 AM   #5
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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.
 
Old 04-17-2007, 01:27 AM   #6
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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
 
Old 04-17-2007, 01:29 AM   #7
blackhole54
Senior Member
 
Registered: Mar 2006
Posts: 1,896

Rep: Reputation: 61
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.
 
Old 04-17-2007, 01:55 AM   #8
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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.
 
Old 04-17-2007, 11:54 AM   #9
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,455

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
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
 
Old 04-19-2007, 04:34 AM   #10
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
Thanks a lot, ntubski.
eval did sort things out, even w/o exporting variables involved.
And yes, that was a forward slash there.
 
Old 04-19-2007, 07:04 AM   #11
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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.
 
Old 04-19-2007, 10:44 AM   #12
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,455

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
$? 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
 
Old 04-19-2007, 11:16 AM   #13
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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.
 
Old 04-19-2007, 11:22 AM   #14
cfaj
Member
 
Registered: Dec 2003
Location: Toronto, Canada
Distribution: Mint, Mandriva
Posts: 221

Rep: Reputation: 31
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.

 
Old 04-20-2007, 02:44 AM   #15
GSMD
Member
 
Registered: Dec 2005
Distribution: Gentoo
Posts: 87

Original Poster
Rep: Reputation: 16
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
}
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Passing command line arguments through getopts and long options neville310 Programming 3 04-16-2007 06:38 AM
Bash script - passing command as string lenzj Programming 3 08-24-2006 11:36 AM
Passing a text file to the command line as arguments wimnat Linux - General 2 12-05-2005 08:09 AM
MySQL Can't connect to DB when passing passwd on command line dimsh Linux - Software 2 11-08-2005 02:38 AM
Bash Script Passing variable to Function nutthick Programming 2 02-02-2005 05:15 AM


All times are GMT -5. The time now is 09:14 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration