Passing variables to functtion - $@ is correct but $1 is not

Hello I have a problem in a calling function.

#!/bin/bash
#
function SEARCH_IN_CURRENT_ITEM () {


    echo �
    echo �
    echo �
    echo "PARAM : $@"

    local B_ITEM_A
    local B_ITEM_B
   B_ITEM_A="${1}"
   echo "B_ITEM_A : $B_ITEM_A"
   B_ITEM_B="$1"
   echo "B_ITEM_B : $B_ITEM_B"

    echo "FILE : $B_ITEM_B"
    file -h  "$B_ITEM_B"
    echo
    echo

}

export -f SEARCH_IN_CURRENT_ITEM


#
#
# +--------------------+
# |    FUNCTION END    |
# +--------------------+
#
#
#

MY_HOME="$1"
echo "MY_HOME : $MY_HOME"

export A_USER A_HOME A_USER_ID

CMD="find $MY_HOME/Desktop -exec bash -c 'SEARCH_IN_CURRENT_ITEM  {} ' \; "
echo "COMMAND : $CMD"
eval "$CMD"  2> /dev/null

The output is :

�
�
�
PARAM : /home/user_install/Desktop/Computer Start Seq
B_ITEM_A : /home/user_install/Desktop/Computer
B_ITEM_B : /home/user_install/Desktop/Computer
FILE : /home/user_install/Desktop/Computer
/home/user_install/Desktop/Computer: cannot open `/home/user_install/Desktop/Computer' (No such file or directory)

The value of PARAM is correct
The value of B_ITEM_A is not correct
The value of B_ITEM_B is not correct

Any help is welcome.

 B_ITEM_A="${2}"
   echo "B_ITEM_A : $B_ITEM_A"
   B_ITEM_B="$3"

Should they not be $2 and $3 (red changes)?

As you have spaces within your file or directory names bash word splitting is separating the filename into separate arguments. This could become even more troublesome if the paths contain newline or quote characters.

I'm a little unsure why you need to use eval at all here, but I will assume you are trying to do some sort of tricky expansion of the find arguments and will leave it alone for now. The solution could be much simpler (and safer) without eval being involved.

In this solution I am utilizing the find -print0 option with xargs -0 . This is not available on all *NIX* flavors and may cause you some portability issues.

...
CMD="find $MY_HOME/Desktop -print0"
echo "COMMAND : $CMD"
eval $CMD | xargs -0 -n 1 -I {} bash -c 'SEARCH_IN_CURRENT_ITEM "$@"' _ {}
1 Like

Coming back to your original question: I don't think that in your output the "start seq" come from the invocation shown, as that will have ONLY one single parameter: the file name(s) that find detected. So: The value of PARAM is NOT correct as shown. Please give us more detail of what you want to achieve and what data are present, if you want to pursue that approach further (and not switch to the road indicated by Chubler_XL).

Hello.
First Happy new year to everybody.

No.
As I could not have a good result, I have tried 2 ways to get the only and one passed parameter.
One way with this syntax : xxxxxx="${1}"
And another way like : xxxxxx="$1"
I must confess that I don't know the difference between the 2.

---------- Post updated at 14:29 ---------- Previous update was at 14:16 ----------

Not at all.
The param value is correct

/home/user_install/Desktop/Computer Start Seq

. This is the name of a file "Computer Start Seq" which is kept in a folder named "Desktop" in the user home ( $HOME ) : "/home/user_install/Desktop/Computer Start Seq" .

This is what "find ....... -exec...... " pass to the called function within the '{}'

---------- Post updated at 14:47 ---------- Previous update was at 14:29 ----------

I use this syntax because I don't know other way to print what is the command which is going to be processed.

I did not really achieve what I wanted to do using xargs.

I will read the xargs man page and try to understand how your example works.

---------- Post updated at 14:56 ---------- Previous update was at 14:47 ----------

After many tries, it seems that the problem is solve by adding singglequote.
Bad result :

CMD="find $MY_HOME/Desktop -exec bash -c 'SEARCH_IN_CURRENT_ITEM  {} ' \; "
echo "COMMAND : $CMD"
eval "$CMD"  2> /dev/null

Good result in a real run :

CMD="find $MY_HOME/Desktop -iname "*playonlinux*"   -exec bash -c \"SEARCH_IN_CURRENT_ITEM  '{}' \" \; "
echo "COMMAND : $CMD"
eval "$CMD"  2> /dev/null

---------- Post updated at 14:57 ---------- Previous update was at 14:56 ----------

Any comments are welcome.

Your function is being called with three arguments. You can't fix that in the function. You have to fix that in the code that is calling your function!

Show us the code that invokes SEARCH_IN_CURRENT_ITEM . We would have to guess that the code that invokes your function is something like:

SEARCH_IN_CURRENT_ITEM $filename

when it needs to instead be something like:

SEARCH_IN_CURRENT_ITEM "$filename"

There is absolutely no difference between the two commands:

printf '%s\n' "$1"
printf '%s\n' "${1}"

And, there is absolutely no difference between the two commands:

printf '%s\n' "$11"
printf '%s\n' "${1}1"

But there is a huge difference between the two commands:

printf '%s\n' "$11"
printf '%s\n' "${11}"

Run the command:

set -- 1 2 3 4 5 6 7 8 9 A B C D E F

and then run the above pairs of commands to see how they work.

Not at all. The function is called with one parameter (a single string) which may have or not one or more space. This single string is the name of a file which is return by the find command.

The complete script is in thread #1

I will do your tip.
Thank you for helping.

Yes at all. If it were being used properly, the parameter would not split.

# Wrong way
functionname parameter with spaces

# right way
functionname "parameter with spaces"

This also works for variables:

functionname "$variable"