0

I want to perform the set of actions inside a different user while running my script, so i am using HEREDOC to perform such actions, but no matter alternatives i try, i cannot able to reference my values in loop inside the HEREDOC.

In this case it prints the first line and exits.

#!/bin/bash

func () {
test=("$@")
sudo su - someuser <<- EOF
    echo "${test[*]}"
    for i in "${test[@]}" ; do
        echo "$i"
    done
EOF
}


arrVar=("AC" "TV" "Mobile" "Fridge" "Oven" "Blender")
arrVar+=("hello.   why would it fail now      with spaces then")

func "$arrVar"  ###### Tried this as well "${arrVar[@]}"

prints the output as like this:

[root@ip-10-9-1-1 ~]# ./test.sh
AC

it works fine just fine if i remove the HEREDOC and run as currentUser, but i need to run this as Different User.

EDIT: @roaima answer looks to be promising , but i had to access lot of outside variables, hence passing them as below wouldn't scale well enough for me.

sudo -u someuser bash -c ' ' -- "lot" "of" "variables" "$@"

so i came to this question in the first place using arrays over strings because of the IFS being not respected inside HEREDOC, perhaps i will get better answer if i post my original issue.

so here it it is:

cp="/usr/bin/cp"
rm="/usr/bin/rm"
mv="/usr/bin/mv"
exec_operations () {

    echo "Executing operations: $@"
    operations=$@
    date=$(date +%Y-%m-%d-%H-%M-%S)
    sudo su - someuser <<- EOF
    IFS=";"
    for operation in $operations ; do
        echo "Performing the following $operation with $cp, $rm & $mv"
    done
    unset IFS
EOF
}
text="cp /tmp/text.txt something/;cp /tmp/text2.txt something/;"
exec_operations "$text"
4
  • Try this: func "${arrVar[@]}" Commented Jan 20, 2023 at 8:44
  • Tangentially relevant: Is there ever a good reason to run sudo su?
    – terdon
    Commented Jan 20, 2023 at 11:04
  • "because of the IFS being not respected inside HEREDOC" - it is respected inside the heredoc, but you're not quoting it right. (And I'm not sure there is a correct way.) Commented Jan 20, 2023 at 11:30
  • i havent understood which part u meant that i have not quoted, i believe u meant in for loop, i have tried this as well it is no different for operation in "${operations}" ; do Commented Jan 20, 2023 at 11:42

1 Answer 1

3

Your invocation func "$arrVar" passes in a string rather than an array. The string happens to correspond to the first element of the array, which is why you see just the first value in your loop (there is only one value).

Use this instead

func "${arrVar[@]}"

You also need to be aware that the unquoted heredoc symbol EOF means that the enclosure is treated as being in double quotes. This in turn means that any reference to a variable such as $i will be evaluated as part of the heredoc, and not as part of its execution. Double quotes will be handled also as part of the expansion, not the execution. Your sudo su (ugh) construct will therefore see something like this:

echo 'AC TV Mobile Fridge Oven Blender hello.   why would it fail now      with spaces then'
for i in 'AC TV Mobile Fridge Oven Blender hello.   why would it fail now      with spaces then' ; do
    echo ''
done

Something like this should work for you instead. I've extended your example to respond to your revised question asking how to pass in extra variables:

#!/bin/bash

func () {
    sudo -u someuser bash -c '
        date=$1; shift
        test=("$@")
        echo "${test[*]}"
        for i in "${test[@]}"
        do
            echo "$date: $i"
        done
    ' -- "$@"
}

arrVar=("AC" "TV" "Mobile" "Fridge" "Oven" "Blender")
arrVar+=("hello.   why would it fail now      with spaces then")
date=$(date --utc +'%Y-%m-%d %H:%M')

func "$date" "${arrVar[@]}"
7
  • but how do i access global variables in this block, like date=$(date +%Y-%m-%d-%H-%M-%S) inside this HEREDOC block ? Commented Jan 20, 2023 at 10:18
  • Pass in the value before the "test[@]}" array, and pick it off inside the subscript before you assign test=("$@") Commented Jan 20, 2023 at 10:32
  • I have edited my question one moe time stating why it may not solve usecase that i had, i am more interested to knowing the answer for edited question than original question for which your answer was more accurate Commented Jan 20, 2023 at 11:17
  • @AlapatiSrikanthChowdary don't use scalar variables to store commands. That way leads to even more problems Commented Jan 20, 2023 at 11:33
  • what if yoou need sudo to make the array? im trying to get a list of files in a dir that needs sudo privs for that, thats my arrray. the array i need to create inside the HEREDOC, as well as loop it. Commented Aug 25, 2023 at 19:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .