tags:

views:

47

answers:

4

I'm trying to write a simple bash script that accepts all arguments and interprets them simply as a string.

In other words: tweet Testing out my command-line tweetings. #commandlinetweets

Takes in all the arguments and just uses them bluntly as a string.

Here is the basic form that I have at the moment:

function tweet()
{
echo "Tweeting using curl."
curl -u tchalvak "http://twitter.com/statuses/update.xml" -d status="$@"
echo "Tweet done if spammed info back above."
echo "Tweeted using username tchalvak with status $@"
}

Right now the erroneous result of running the function is:

$ tweet TEst again and again and again.
Tweeting using curl.
Enter host password for user 'tchalvak':
<?xml version="1.0" encoding="UTF-8"?>
<hash>
  <request>/statuses/update.xml</request>
  <error>Status is a duplicate.</error>
</hash>
curl: (6) Couldn't resolve host 'again'
curl: (6) Couldn't resolve host 'and'
curl: (6) Couldn't resolve host 'again'
curl: (6) Couldn't resolve host 'and'
curl: (6) Couldn't resolve host 'again.'
Tweet done if spammed info back above.
Tweeted using username tchalvak with status TEst again and again and again.

So how do I get from multiple arguments to "all these technically multiple arguments should be counted as just one string variable inside the function"?

Edit: Sorry, I should clarify that I figured I'd just hardcode the username for maximum bulletproofing of the tweeting syntax.

Final solution (as long as you ignore command interpretation issues like # hashes not coming through and similar problems that this dirty method is going to cause, heh):

function tweet()
{
STATUS="$*"
echo "Tweeting using curl."
curl -u tchalvak "http://twitter.com/statuses/update.xml" -d status="$STATUS"
echo "Tweet done if spammed info back above."
echo "Tweeted using username tchalvak with status $STATUS"
}
+1  A: 
tweet "TEst again and again and again."

Your call is passing in 6 separate arguments and the "$@" is passing them properly along as six. This command execution has one argument which will be passed along as one.

added in response to comment:

bind_args() {
    $url = $1;
    shift;
    echo "url is $url with $# arguments"
    set -- "$*"
    echo "now there is only $# argument: |$1|"
}

Where url and shift are in there in case you needed something like that. Obviously, the key is "$*" which is unspecial in the way that "$@" is special. The set -- resets the positional parameters.

As a personal convenience, this is fine, but would probably be confusing to people who expected normal shell behavior.

msw
Right, I get that I could hold myself to a standard and quote each time, but I'd prefer to create an unbreakable syntax that simply interprets all the arguments I care to give as a literal string from the outset so that there's nothing to mess up.
Tchalvak
Good to know, thanks!
Tchalvak
+1  A: 

Why not use quoting -

call you function with: tweet "bla bla bla"

and instead of $@ use "${1}" to indicate the entire string as the first argument.

smichak
Tchalvak
+2  A: 

$1 will be the user name
and the test will be the text you want to tweet
shift will skip $1
use $* to consume the rest of the arguments

USER=$1
shift
STATUS="$*"
echo "Tweeting using curl."
curl -u $USER "http://twitter.com/statuses/update.xml" -d status="$STATUS"
echo "Tweet done if spammed info back above."
echo "Tweeted using username $USER with status $STATUS"

sample output as follows

./tweet tchalvak TEst again and again and again.
Tweeting using curl.
Enter host password for user 'tchalvak':
Tweet done if spammed info back above.
Tweeted using username tchalvak with status TEst again and again and again.
TimeZlicer
Sorry, I've actually simplified the function to just hardcode the username, so I'm guessing that the shift isn't even necessary? I'm going to try using that "STATUS" line and the resulting quote of that variable on it's own and see if that solves it... My bad for not clarifying all of the question at once.
Tchalvak
Tchalvak
A: 

Use "$*" instead of "$@". From the bash man page:

       *      Expands to the positional parameters, starting from one.  When the expansion
              occurs  within  double quotes, it expands to a single word with the value of
              each parameter separated by the first character of the IFS special variable.
              That  is,  "$*" is equivalent to "$1c$2c...", where c is the first character
              of the value of the IFS variable.  If IFS is unset, the parameters are sepa-
              rated  by  spaces.  If IFS is null, the parameters are joined without inter-
              vening separators.
       @      Expands to the positional parameters, starting from one.  When the expansion
              occurs  within  double  quotes,  each  parameter expands to a separate word.
              That is, "$@" is equivalent to "$1" "$2" ...  If the double-quoted expansion
              occurs  within  a  word, the expansion of the first parameter is joined with
              the beginning part of the original word,  and  the  expansion  of  the  last
              parameter is joined with the last part of the original word.  When there are
              no positional parameters, "$@" and $@ expand  to  nothing  (i.e.,  they  are
              removed).

William Pursell