在Shell中以其他用户身份运行时无法初始化变量

时间:2018-12-11 09:02:35

标签: linux bash shell variables scope

我正在运行一个shell脚本,它将以不同的用户身份进行一些工作(该脚本如下所示)。我可以在以其他用户身份运行时访问脚本中声明的变量。在用户范围内分配的变量未初始化。

#!/bin/bash
presentdir="$(pwd)"
sudo -H -u user1 bash <<EOF
echo "$presentdir"
#its is printing the value on console
EOF

这是可行的,但是我应该在用户bash中初始化变量。当我尝试这种方式时,它显示为空。

sudo -H -u user1 bash <<EOF
presentdir="$(pwd)"
echo "$presentdir"
#its just prints empty line
EOF

我做对了还是缺少什​​么?

EDIT1:

pre_dir=$(dirname "$0")
sudo -u user bash <<"EOF"
echo $pre_dir
#its not printing anything
EOF

如何访问上面和内部定义的变量?

EDIT2: 我想通了。只需通过传递-E并保存变量即可保留当前环境。

export pre_dir=$(dirname "$0")
sudo -E -u user bash <<"EOF"
echo $pre_dir
#its prints file directory 
EOF

2 个答案:

答案 0 :(得分:2)

扩展发生在原始用户端,而不是sudo之后的端。

sudo -H -u user1 bash <<EOF
presentdir="$(pwd)"
echo "$presentdir"
EOF

现在扩展后看起来像这样:

sudo -H -u user1 bash <<EOF
presentdir="/home/orinal_user"
echo ""
EOF

即。扩展$presentdir$(pwd)都发生在原始用户端。

所以顺序是:

  1. 首先在heredoc <<EOF ... EOF
  2. 中展开所有变量
  3. 然后运行sudo bash
  4. 然后sudo bash再次扩展变量(但是什么也没剩下)。

您要

  1. 运行sudo bash
  2. 然后展开变量

您需要确定要在哪一侧进行扩展。就个人而言,我根本不会使用heredoc,而是使用-c选项,这使我可以更明确地控制报价:

sudo -H -u user1 bash -c 'presentdir="$(pwd)"; echo "$presentdir"'

将在{em> $(pwd)之后打印<{1}}运行的输出。

或用双引号将变量:

sudo -u user1

第一个扩展将sudo -H -u user1 bash <<EOF presentdir="\"\$(pwd)\"" echo "\"\$presentdir\"" EOF 扩展为"\"\$var\"",然后在"$var"侧的第二个扩展将sudo bash扩展为其文字值。

或者您可以将Heredoc分隔符括在引号中("$var"'无关紧要)

"

这将使Heredoc不在原始用户方面扩展(小而有用的技巧)。

答案 1 :(得分:1)

$variable$(command)都在执行消耗此处文档的命令之前先在此处文档中展开。

在第二种情况下,传递给bash的{​​{1}}的字符串实际上是

user1

您可以在此文档中使用presentdir="working directory before running sudo -H" echo "" 转义$来修复脚本。您可以将\$替换为sudo -H -u user1 bash以打印将要传递的字符串。