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

时间:2015-08-09 10:21:01

标签: bash sudo eof

我无法使用sudo -Sbash -cEOF进行身份验证。

在下面的代码中:

  • 第一个sudo没问题
  • 第二次sudo验证是可以的,但不是 预期产出
  • 第3次sudo验证是可以的,但不是 预期产出
  • 第4次sudo身份验证即可,但我似乎并非如此 能够写一个文件
  • 第五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 个答案:

答案 0 :(得分:1)

第一个问题是在HereDocument中,默认情况下,环境变量在调用shell中展开。您可以使用带引号的"EOF"作为起始分隔符或转义\$HOSTNAME之类的变量来阻止此行为。 您应该认真阅读有关man bash的{​​{1}}。它就像三个短段。

第二个sudo的问题是虽然使用Here Documents,但它只设置-H envvar,但不会更改目录。 $HOME应该解决这个问题。

来自"cd; pwd"

  

-H, - set-home

     

请求安全策略将HOME环境变量设置为   目标用户的密码数据库指定的主目录   条目。根据策略,这可能是默认行为。

第三个sudo可能会出现更大的问题,因为该变量嵌套得更深。对于man sudo它当然是相同的,但对于其他envvars,你可能需要在前面堆积一堆反斜杠来保护它们。想想\$HOSTNAME

对于\\\$UID,您必须将目录更改为您有权编写该文件或以某种方式处理权限的位置。

最后一个sudo的问题是管道和HereDoc都为touch test命令设置为stdin,而不是sudo,所以不知何故这两个混淆了。 你想要的是:

bash

最后一件小事是,(imho)编写这样的代码可能会更好地阅读,因为(sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c " whoami pwd " 也是不必要的:

sleep