[英]Iterate through commands and execute in bash
I wrote a script that transfers a new key to my AWS instances. 我编写了一个脚本,将新密钥传输到我的AWS实例。 The script executes with no errors, but when I check the ~/.ssh/authorized_keys file on the instance, I do not see the new SSH key. 脚本执行没有错误,但是当我检查实例上的〜/ .ssh / authorized_keys文件时,看不到新的SSH密钥。
Here is the script: 这是脚本:
aws_instances=(
"ssh -i \"priv.pem\" ubuntu@99.99.99.1" #server1
"ssh -i \"priv.pem\" ubuntu@99.99.99.2" #server2
"ssh -i \"priv.pem\" ubuntu@99.99.99.3" #server3
)
IFS=""
for t in ${aws_instances[@]}; do
cat ~/newKey.pub | eval $t 'cat >> ~/.ssh/authorized_keys && echo "Key copied"'
done
It does print out "Key copied" 它确实打印出“密钥已复制”
I have changed the ip addresses of the servers. 我已经更改了服务器的IP地址。
If I just execute the following command, it works. 如果我只执行以下命令,它将起作用。
cat ~/newKey.pub | ssh -i "priv.pem" ubuntu@99.99.99.1 'cat >> ~/.ssh/authorized_keys && echo "Key copied"'
What is wrong with my script? 我的脚本有什么问题?
eval
is code smell, avoid it like pest. eval
是代码气味,避免像虫子一样。
I think you can achieve the very same feature like this: 我认为您可以实现类似的功能:
#!/usr/bin/env bash
# See: https://tools.ietf.org/html/rfc5737
# 3. Documentation Address Blocks
#
# The blocks 192.0.2.0/24 (TEST-NET-1), 198.51.100.0/24 (TEST-NET-2),
# and 203.0.113.0/24 (TEST-NET-3) are provided for use in
# documentation.
# Array contains user-name@host-or-ip:ssh-port (ssh-port is optional, default standard 22)
aws_instances=(
'ubuntu@192.0.2.1'
'ubuntu@192.0.2.2:2222'
'ubuntu@192.0.2.3:2022'
)
new_keyfile="${HOME}/newKey.pub"
for instance in "${aws_instances[@]}"; do
ssh_host="${instance%%:*}" # trim the port if specified
port="${instance##*:}" # trim the host and keep port if specified
[[ ${port} == "${instance}" || -z "${port}" ]] && port=22 # use default port
if ssh-copy-id \
-i "${new_keyfile}" \
-p "${port}"
"${ssh_host}"; then
printf \
$"The new key file '%s' has been copied to user@host: '%s', port: %d.\\n" \
"${new_keyfile}" \
"${instance}" \
"${port}"
else
printf >&2 \
$"Could not copy the new key file '%s' to user@host: '%s', port: %d.\\n" \
"${new_keyfile}" \
"${instance}" \
"${port}"
fi
done
You need extra quotes around the second eval
argument. 您需要在第二个eval
参数周围加上引号。
eg: 例如:
cat ~/newKey.pub | eval $t "'"'cat >> ~/.ssh/authorized_keys && echo "Key copied"'"'"
The Problem is that the single quotes get lost on the first call to eval, so the command it tries to execute will be 问题在于,单引号在第一次调用eval时会丢失,因此它将尝试执行的命令为
ssh -i "priv.pem" ubuntu@99.99.99.1 cat >> ~/.ssh/authorized_keys && echo "Key copied"
which just appends the output of your ssh command to your local authorized_keys
file instead of adding the key to the remote host. 该命令仅将ssh命令的输出附加到本地 authorized_keys
文件,而不是将密钥添加到远程主机。
Sometimes simpler is better. 有时越简单越好。 Maybe something like this to eliminate the eval? 也许这样可以消除评估?
for i in 1 2 3
do ssh -i priv.pem ubuntu@99.99.99.$i 'cat >> ~/.ssh/authorized_keys &&
echo "Key copied" '< ~/newKey.pub
done
(In a meeting, can't test - caveat scriptor.) (在会议上,无法测试-警告脚本。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.