HEREDOC을 사용하여 쉘 스크립트 내에서 다른 사용자와 배열을 반복하면 작동하지 않습니다.

HEREDOC을 사용하여 쉘 스크립트 내에서 다른 사용자와 배열을 반복하면 작동하지 않습니다.

스크립트를 실행할 때 여러 사용자 내에서 일련의 작업을 수행하고 싶어서 HEREDOC을 사용하여 이러한 작업을 수행하고 있지만 어떤 대안을 시도해도 HEREDOC 내부 루프에서 내 값을 참조할 수 없습니다. .

이 경우 첫 번째 줄을 인쇄하고 종료됩니다.

#!/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[@]}"

인쇄물은 다음과 같습니다.

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

HEREDOC을 제거하고 currentUser로 실행하면 제대로 작동하지만 다른 사용자로 실행해야 합니다.

편집: @roaima 답변은 유망해 보이지만 많은 외부 변수에 액세스해야 하므로 다음과 같이 전달하는 것이 충분히 확장되지 않습니다.

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

그래서 저는 먼저 문자열 대신 배열을 사용하여 이 문제를 해결했습니다.IFSHEREDOC에서는 존중되지 않습니다. 원래 질문을 게시하면 더 나은 답변을 얻을 수 있을 것입니다.

그래서 그것은:

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"

답변1

귀하의 호출은 func "$arrVar"배열 대신 문자열을 전달합니다. 이 문자열은 배열의 첫 번째 요소와 정확히 일치하므로 루프에서 첫 번째 값만 볼 수 있습니다(값은 하나만 있음).

대신 이것을 사용하십시오

func "${arrVar[@]}"

또한 따옴표가 없는 구분 기호는 EOF대괄호가 큰따옴표 안에 있는 것처럼 처리된다는 것을 의미합니다. 이는 예를 들어 변수에 대한 모든 참조가 $i실행의 일부가 아닌 구분된 문서의 일부로 평가된다는 것을 의미합니다. 큰따옴표도 수행되지 않고 확장의 일부로 처리됩니다. 당신의 sudo su() 구성하면 다음과 같은 내용이 표시됩니다.

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

이와 같은 것이 당신에게 도움이 될 것입니다. 추가 변수를 전달하는 방법을 묻는 수정된 질문에 답하기 위해 예제를 확장했습니다.

#!/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[@]}"

관련 정보