Bash - 使用标准输入和 EOF 的 Sudo 身份验证
Bash - Sudo authentication using stdin and EOF
我在使用 sudo -S
、bash -c
和 EOF
进行身份验证时遇到问题。
在下面的代码中:
- 第一个
sudo
可以
- 第二个
sudo
认证可以,但不能用
预期输出
- 3rd
sudo
身份验证正常,但与
预期输出
- 4th
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
的输出不是预期的?
第一个问题是在HereDocument中环境变量默认在调用shell中展开。您可以通过使用 "EOF"
和引号作为起始分隔符或转义 $HOSTNAME
等变量来防止此行为。
你应该认真阅读 man bash
关于 Here Documents
的内容。就像三个短段落。
第二个 sudo 的问题在于,虽然使用了 -H
,但它只设置了 $HOME
环境变量,而没有更改目录。 "cd; pwd"
应该可以解决这个问题。
来自man sudo
:
-H, --set-home
Request that the security policy set the HOME environment variable to
the home directory specified by the target user's password database
entry. Depending on the policy, this may be the default behavior.
第三个 sudo 可能会带来更大的问题,因为该变量嵌套得更深。对于 $HOSTNAME
它当然是一样的,但对于其他环境变量,您可能必须在前面堆放一堆反斜杠以保护它们。想想\$UID
.
至于 touch test
,您必须将目录更改为您有权写入该文件或以某种方式处理权限的地方。
最后一个 sudo 的问题是管道和 HereDoc 都被设置为 sudo
命令的 stdin
,而不是 bash
,所以不知何故这两个混淆了向上。
你想要的是:
(sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c "
whoami
pwd
"
最后一件小事是(恕我直言)像这样编写代码可能会更好读,因为 sleep
也是不必要的:
<<<$pass sudo -S -p "" bash -c "cd; pwd"
我在使用 sudo -S
、bash -c
和 EOF
进行身份验证时遇到问题。
在下面的代码中:
- 第一个
sudo
可以 - 第二个
sudo
认证可以,但不能用 预期输出 - 3rd
sudo
身份验证正常,但与 预期输出 - 4th
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
的输出不是预期的?
第一个问题是在HereDocument中环境变量默认在调用shell中展开。您可以通过使用 "EOF"
和引号作为起始分隔符或转义 $HOSTNAME
等变量来防止此行为。
你应该认真阅读 man bash
关于 Here Documents
的内容。就像三个短段落。
第二个 sudo 的问题在于,虽然使用了 -H
,但它只设置了 $HOME
环境变量,而没有更改目录。 "cd; pwd"
应该可以解决这个问题。
来自man sudo
:
-H, --set-home
Request that the security policy set the HOME environment variable to the home directory specified by the target user's password database entry. Depending on the policy, this may be the default behavior.
第三个 sudo 可能会带来更大的问题,因为该变量嵌套得更深。对于 $HOSTNAME
它当然是一样的,但对于其他环境变量,您可能必须在前面堆放一堆反斜杠以保护它们。想想\$UID
.
至于 touch test
,您必须将目录更改为您有权写入该文件或以某种方式处理权限的地方。
最后一个 sudo 的问题是管道和 HereDoc 都被设置为 sudo
命令的 stdin
,而不是 bash
,所以不知何故这两个混淆了向上。
你想要的是:
(sleep 3; echo -e $pass; sleep 3) | sudo -S -u batchuser bash -c "
whoami
pwd
"
最后一件小事是(恕我直言)像这样编写代码可能会更好读,因为 sleep
也是不必要的:
<<<$pass sudo -S -p "" bash -c "cd; pwd"