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"文字列を渡します。この文字列は配列の最初の要素と正確に一致するため、ループ内の最初の値のみを表示できます(1つの値しかありません)。

代わりにこれを使用してください

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

関連情報