使用 Bash heredoc 调用另一个脚本时,变量不会传递

使用 Bash heredoc 调用另一个脚本时,变量不会传递

我在本地用户中保存了一个名为 ( executeAdM.sh) 的 shell 脚本,当我执行此脚本时,我会通过从指令文件中获取命令来切换到 sudo 用户。但是当我执行此脚本时,我还会传递参数,这些参数实际上是 sudo 用户的某个目录路径。请参阅下面的脚本。

本地用户脚本 ( executeADM.sh):

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<\EOF
#ls -lrt
pwd
for entry in $(ls -r)
  do
  if [ "$entry" = "testingADM.sh" ];then
    ./"$entry" "$1"
  fi
done
EOF

我正在执行上述操作:

./executeADM.sh "/global/u70/globe/ADM"

当上述脚本执行时,它会成功切换到其他用户,并且使用 sudo 用户我执行一个for循环,搜索另一个名为 的脚本testingADM.sh

一旦找到脚本,我就会使用从本地用户传递的参数执行该脚本,并且testingADM.sh应该为我设置路径。

这不起作用——它没有读取从本地用户传递的参数。

sudo 用户脚本(testingADM.sh):

#!/bin/bash
changepath=$1
cd "$changepath"
pwd

当我在脚本中对路径变量进行硬编码时,一切都正常。但我不想这样:

 #!/bin/bash
 changepath=somepath
 cd "$changepath"
 pwd

问题是,它不是转到 而是"/global/u70/globe/ADM"将路径作为"/global/u70/globe/",这是我执行 之后的路径sudo。它只是没有传递变量。


根据以下建议,我最终得到了以下结果:

#!/bin/bash
echo password | sudo -S -l
sudo /usr/bin/su - user  <<EOF
#ls -lrt
#pwd
echo "$1"
./testingADM.sh "$1"
EOF

echo命令不打印任何内容;显示空白。当我更改\EOF为时,它起作用了EOF

有人能解释一下以下之间的区别吗:

\EOF , "EOF" , 'EOF' , EOF

或者说前三个意思是一样的吗?那他们之间有什么区别呢?

答案1

不要引用或转义你的 heredoc 限制字符串(即使用EOF\EOF"EOF",否则,像 这样的特殊变量$将不会被解释。请参阅这里了解更多信息和示例(例如示例 19-7)。

这是一个可以运行的最小脚本:

$ cat test.sh
#!/bin/bash
sudo su - $(whoami) <<EOF
./test2.sh "$1"
EOF

$ cat test2.sh
#!/bin/bash
foo=$1
echo "$foo"

$ ./test1.sh "/path/to/file"
"/path/to/file"

注意:

  • 根本不需要 heredoc。只需./test2.sh在之后直接调用即可sudosudo -u $(whoami) test2.sh "$1"
  • 您不应该循环输出ls
  • 无需循环for搜索单个文件。只需直接使用其名称调用脚本即可。

您还应该引用您的变量,即:

  • 使用以下命令执行脚本./executeADM.sh "/path/with white/space"
  • 调用./"$entry" "$1"你的脚本
  • 在您的其他脚本中,使用cd "$path"

一般来说:

  • 始终使用双引号括住变量。(不要使用单引号括住它们 - 它们不会扩展。)
  • 不要使用名为 的变量path。(就像您不会使用名为 、 等的变量一样userhome

答案2

编辑
从我的脑海里。你的路径包含空格吗?

如果是,则需要按如下方式执行./executeADM.sh 'somePath'

$1在进一步传递时,最好将其保存到变量中,这样更容易阅读。我会path=$1在批处理文件中添加,您将./$entry "$path"

相关内容