# modifying argument variables



## oliver@ (Feb 1, 2013)

Hi,

imagine my shell script gets called with a random amount of arguments.
Those arguments must be passed to another program:


```
/usr/local/bin/binary "$@"
```

So far so good. But - I need to modify the parameters before they are passed.
I need to remove a specific string from one of the parameters. Which parameter the string contains is not known. The parameters may contain spaces and it is important that an argument/parameter which contains a space is forwarded as a single parameter to the binary.

What I tried:


```
#!/bin/sh

while [ $# -gt 0 ] ; do
        if echo "$1" |grep -q ' ' ; then
                OPT=$OPT' "'$1'"'
        else
                OPT=$OPT' '$1
        fi
        echo $1
        shift 1
done

OPT=$(echo "$OPT" | sed 's|:vrc_maxrate=[0-9]*||g')
OPT=$(echo "$OPT" | sed 's|:vrc_buf_size=[0-9]*||g')

set -- $OPT
echo $3
/usr/local/bin/mencoder.orig "$@"
```

But this is not working, assume the script gets called like this:


```
/usr/local/bin/mencoder -ss 0 "1 2 3" 4 5
```

$3 does not contain "1 2 3", instead it contains "1


```
$ /usr/local/bin/mencoder -ss 0 "1 2 3" 4 5
-ss
0
1 2 3
4
5
"1
```
Any ideas how to solve this problem properly?


----------



## SirDice (Feb 1, 2013)

I would suggest using getopt(1).


----------



## oliver@ (Feb 1, 2013)

For getopt I would need to know what parameters are being passed to the script, right? I don't know them as the final validation is done by the binary being called.


I'm now using perl but would prefer a shell solution.


```
#!/usr/bin/perl -w

foreach $i (0 .. $#ARGV) {
        $ARGV[$i]=~s/:vrc_maxrate=[0-9]*//g;
        $ARGV[$i]=~s/:vrc_buf_size=[0-9]*//g;
}
system("/usr/local/bin/mencoder.orig",@ARGV);
```


----------



## fonz (Feb 1, 2013)

oliver@ said:
			
		

> For getopt I would need to know what parameters are being passed to the script, right?


Correct. And it can only handle parameters of the form *-a*, *-b*, *-c foo* and such. I also seem to remember that getopt(1) is considered obsolete and getopt*s* (which is an sh built-in command) should be used instead, but I can't recall where I read that, so don't quote me on it.


----------



## oops (Feb 2, 2013)

oliver@ said:
			
		

> ```
> ...
> set -- $OPT
> echo $3
> ...


Try to *eval*uate special characters (dobulequotes) within argument value before *set*ting new positional parameters.

```
+ set -- -ss 0 '"1' 2 '3"' 4 5
```
becomes

```
+ eval set -- -ss 0 '"1' 2 '3"' 4 5
+ set -- -ss 0 '1 2 3' 4 5
```
Notice how sh(1) denotes (with xtrace) a single parameter containing special characters (whitespace, doublequotes).


----------

