Bash - 使用stdin和EOF进行Sudo身份验证

3
我在使用sudo -Sbash -cEOF进行认证时遇到了问题。
在下面的代码中:
- 第1个sudo是OK的。 - 第2个sudo身份验证已通过,但输出结果与预期不符。 - 第3个sudo身份验证已通过,但输出结果与预期不符。 - 第4个sudo身份验证已通过,但似乎无法写入文件。 - 第5个sudo无法进行身份验证。
#!/bin/bash

pass="my_pass\n"
#echo -e $pass

ssh -T my_user@my_server << EOF
    whoami
    pwd
    echo $HOSTNAME
    (sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser whoami
    (sleep 3; echo -e $pass; sleep 3) | sudo -S -H -u batchuser bash -c "pwd"
    (sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c "echo $HOSTNAME"
    (sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c "touch test"
    (sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c << TEST1
        sleep 10; echo -e $pass; sleep 3
        whoami
        pwd
    TEST1
EOF

输出:

my_user@my_pc> ./test_ssh.sh
my_user@my_server's password:              <-- I wrote the password here
my_user
/home/my_user
my_pc                                      <-- It's not 'my_server'
Mot de passe de my_user: batchuser
Mot de passe de my_user: /home/my_user     <-- It's not '/home/batchuser'
Mot de passe de my_user: my_pc             <-- It's not 'my_server'
Mot de passe de I86671: touch: cannot touch `test': Permission denied
Mot de passe de my_user: Sorry, try again.
Mot de passe de my_user: Sorry, try again.
Mot de passe de my_user: Sorry, try again.
sudo: 3 incorrect password attempts
my_user@my_pc>

你知道我怎样可以使用EOF传递密码吗?
同时为什么bash -c的输出结果不是预期的呢?

1个回答

1
第一个问题是,在HereDocument中,默认情况下会在调用shell中展开环境变量。您可以通过使用带引号的"EOF"作为起始定界符或转义变量,例如\$HOSTNAME来防止此行为。您应该认真阅读man bash关于Here Documents的内容。它只有三个简短的段落。
第二个sudo的问题是,尽管使用了-H,但仅设置了$HOME环境变量,但并未更改目录。 "cd; pwd"应该解决这个问题。
man sudo中得知:
-H,--set-home 请求安全策略将HOME环境变量设置为目标用户密码数据库条目指定的主目录。根据策略,这可能是默认行为。
第三个sudo可能会出现更大的问题,因为该变量嵌套得更深。对于\$HOSTNAME当然是相同的,但对于其他envvars,您可能需要在前面堆积一堆反斜杠以保护它们。想一想\\\$UID
关于touch test,您需要切换到某个您有写入该文件或处理权限的目录,或以某种方式处理权限。
最后一个sudo的问题在于管道和HereDoc都被设置为sudo命令的stdin,而不是bashstdin,因此这两者被混淆了。您想要的是:
(sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c "
    whoami
    pwd
"

最后一点是(我个人认为)将您的代码编写为以下方式可能会更好地阅读,因为 sleep 也是不必要的。
<<<$pass  sudo -S -p "" bash -c "cd; pwd"

1
我从未花时间感谢你。你最后的提示非常棒。 :) - pihug12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接