Why double quotation marks doesn't work in ksh function parameters passing?

I'm working on AIX 6, ksh shell. The parameters are some strings quotated by double quotation marks which from a file. They are quotated because there may be spaces in them.
Example:

 "015607" "10" "    " "A"

I want to pass these parameters to a shell function by writing the following command:

 parse $(cat para.txt)

But I didn't get 4 parameters as thought before, instead, there are 5 parameters!

OK, it's hard to say that problem clearly. the script is:

#!/bin/ksh
#################################
#
function parse {
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
}

echo write parameters directly
parse "009085" "              " "0405103025    " "0912" "0"
echo get parameters from file
parse $(cat para.txt)
####################################

The results is:

write parameters directly
[009085]
[              ]
[0405103025    ]
[0912]
[0]
get parameters from file
["009085"]
["]
["]
["0405103025]
["]

Why is that? What's the differents between these 2 ways of function call?
Is there a way to solve this problem?
Thanks for all information on it.

Interesting...

As far as I can guess, when you directly pass parameters to the function using quotes to delimit them, the shell will consider the parameter list without the quotes but with the embedded white-spaces...

set -x

parse "009085" " " "0405103025 " "0912" "0"

+ parse 009085   0405103025  0912 0
[009085]
[ ]
[0405103025 ]
[0912]
[0]

But, when you get the argument list from a file using command substitution, the shell will do nothing more about it. It will use the current IFS value to decide the positional parameters.

parse "$(cat para.txt)"

+ cat para.txt
+ parse "009085" " " "0405103025 " "0912" "0"
["009085"]
["]
["]
["0405103025]
["]

The issue is the order of events. We need to delay the Shell processing the parse line until after the cat has run.

#!/bin/ksh
#################################
#
function parse {
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
    echo "[$1]"
    shift
}

echo write parameters directly
parse "009085" "              " "0405103025    " "0912" "0"
echo get parameters from file
eval parse "$(cat para.txt)"

./scriptname
write parameters directly
[009085]
[              ]
[0405103025    ]
[0912]
[0]
get parameters from file
[009085]
[              ]
[0405103025    ]
[0912]
[0]


Contents of para.txt
"009085" "              " "0405103025    " "0912" "0"

It's amazing...
I found there is so much knowledge need to learn.
Thanks a lot!

1 Like

Though it is a solution to your problem, I don't recall ever putting an eval command in a production script.
There is always a better design like formatting your parameter file such that it is valid Shell syntax and can be executed in the current environment.