Echo: Argument List too long

2019-08-25 01:43发布

问题:

I'm running into an issue where my argument list for echo is too long and would like some ideas on how to get around this issue, or at least test for the condition so I can properly handle it, and it won't kill my script

for file in `cat filelist`; do 
    PROTOCOLS1=`egrep -i 'rsh|rsync|remsh' "$file" | egrep -v '^[ |      ]*#'`
    FIELDS=`echo $PROTOCOLS1|wc -l`
    if [[ $FIELDS -gt 1024 ]]; then
        echo $file >> $debuglog
    else
        set -A myarray $PROTOCOLS1
        do stuff.....
    fi
done

So the problem is that when my arg list for echo is too long, $FIELDS is set to null, and thus my test for $FIELDS -gt 1024 always is true and does not get caught. Problem is when it goes to the array it's obviously too big and I get a subscript out of range error and my script exits.

Any ideas are greatly appreciated.


Edit 9/18

OK so the problem is a little more basic.

myserver-v1> echo $variable
myserver-v1> /usr/bin/echo: too many args

I want to test for this in my script

I tried the following, which works, but I get all this crap to stdout, which fills up my debug log and is annoying

echo $variable
if [[ $? -ne 0 ]]; then
write to error log
fi

Is there a way to test echo $variable....without sending it to stdout? I tried the following, but neither seemed to work, so I am kind of at a loss here.

[[ ! `echo $variable ]]
[[ `echo $variable ]]

回答1:

If you keep the unquoted variable $PROTOCOLS1 in the echo, you could simplify life by replacing:

FIELDS=`echo $PROTOCOLS1|wc -l`

with

FIELDS=1

This is because when you echo $PROTOCOLS1 without any quotes around it, you will only have one (possibly very long) line of output. Alternatively, you can use:

FIELDS=$(echo "$PROTOCOLS1" | wc -l)

where the double quotes will preserve the newlines in the value of PROTOCOLS1 (but it gets you back to the 'argument list too long' problem).

So, you need to think about using:

FIELDS=$(egrep -i 'rsh|rsync|remsh' "$file" | egrep -c -v '^[ |      ]*#')

which gets the second egrep to do the line counting for you. Obviously, since the later portion of the script uses $PROTOCOLS1, you will need to re-evaluate the egreps to get the data, but you should think about whether your processing scheme is appropriate. If you are running into a string value that is too long, you are probably not doing the processing in the best way. What the alternatives are depends on what you are trying to do, and the question does not reveal that. It might be appropriate to do the extra processing with a scripting language such as Perl, Python or Ruby.