#!/bin/sh
echo -n "Enter the raspberry ip address you want to connect:"
read Rasp_id
sshpass -p "the@Donut" ssh -t -X -oStrictHostKeyChecking=no pi@$Rasp_id << E2
echo -e "Enter the case you want to echo\n 1.1 a \n 2.1 b"
read option
case "\$option" in
1)
echo "a"
;;
2)
echo "b"
;;
esac
E2
我正在编写一个脚本来启动 ssh 会话,然后在远程计算机上执行一些修改,它将给出语法错误,如下所示:
bash: line 3: syntax error near unexpected token `)'
bash: line 3: ` 1)'
答案1
问题是您正在混合使用 stdin 的用途,提供要在远程计算机上执行的程序以及该程序的输入。
正如所写,发生以下情况。
- 远程 shell
echo -e "Enter the case you want to echo\n 1.1 a \n 2.1 b"
从 stdin 读取并进行回显。 - 远程 shell
read option
从 stdin 读取并执行读取。 read
从标准输入读取并将case "\$option" in
选项设置为此。- 远程 shell
1)
从 stdin 获取并给出语法错误。
答案2
在这里,为了补充@icarus的答案,你可以这样写:
#!/bin/sh -
if [ "$#" -eq 0 ]; then
printf >&2 'Enter the raspberry ip address you want to connect to: '
IFS= read -r ip
set -- "$ip"
fi
for ip do
printf >&2 '%s\n' "Connecting to $ip"
SSHPASS=the@Donut sshpass -e \
ssh -oStrictHostKeyChecking=no "pi@$ip" "$(cat << 'EOF'
printf >&2 '%s\n' 'Enter the case you want to echo' \
' 1.1 a' \
' 2.1 b'
IFS= read -r option
case "$option" in
(1) echo a;;
(2) echo b;;
esac
EOF
)"
done
那是:
- 避免
echo
(echo -n
/echo -e
不是标准 sh+utilities 语法) - 避免
read
默认的后处理并读取一行原始输入。 - 允许用户将主机名作为参数传递,这使得脚本更容易自动化。
- 发出提示和其他与实际不符的内容输出stderr 上的脚本(同样,它可以自动化,您可以执行类似的操作
actual_output=$(that-script)
)。 - 避免在命令行上传递密码,因为这是公开的。由于该脚本包含敏感信息,因此您需要收紧对其的访问权限,以便密码仅暴露给需要访问它的用户。
- 该脚本作为参数而不是其标准输入传递
ssh
,以便该脚本仍然可以通过标准输入查询用户。 - 这是通过捕获其输出来完成的,
cat
该输出被馈送到此处文档,该文档的终止符 (EOF
) 已被引用,因此此处文档中不会进行任何扩展。 - 此处删除了不必要的 X11 转发,因为其中没有需要连接到 X 服务器的命令。
- 还删除了伪 tty,因为该脚本中没有任何内容需要它。
- 添加了一些缺失的引号。
上面假设pi
用户的登录 shell$ip
类似于 POSIX-sh。