我想在运行脚本时在不同用户内执行一组操作,因此我使用 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" "$@"
所以我首先使用数组而不是字符串来解决这个问题,因为IFS在 HEREDOC 内部不受尊重,如果我发布我原来的问题,也许我会得到更好的答案。
所以它是:
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[@]}"