使用heredoc在远程服务器上运行while循环

使用heredoc在远程服务器上运行while循环

我正在尝试在远程计算机上运行下面的脚本,我在这里面临两个问题

  1. 此处文档中定义的 while 循环正在无限运行
  2. 读取回车键在远程主机上不起作用

如果没有 sshpass 命令脚本可以在本地主机上正常工作。

有人可以调查一下并提供帮助吗?

      1 #!/bin/bash
      2 #read -p "Enter the user name to connect to server: " user
      3 #read -s -p "Enter the password : "   passd
      4 #sshpass -p $passd ssh -qt -o StrictHostKeyChecking=no -o ConnectTimeout=4 $user@$1 << 'MYSCR'
      5 ##############################################################################################################################################
      6 while :
      7 do
      8 clear
      9 echo "Server Name - $(hostname)"
     10 echo "1. Check Server Information"
     11 echo "2. Check Network Information"
     12 echo "q. to Exit"
     13 read -p "Enter your choice [ 1 - 3 ]" choice
     14 case $choice in
     15 1)
     16 echo "Server Date                       : `date`"
     17 echo "Server Uptime                     :`uptime`"
     18 read -p "Press [Enter] key to continue..."
     19 readEnterKey
     20 ;;
     21 2)
     22 echo "File system information"
     23 df -hP | column -t
     24 read -p "Press [Enter] key to continue..."
     25 readEnterKey
     26 ;;
     27 q)
     28 echo "Bye!"
     29 exit 0
     30 ;;
     31 *)
     32 echo "Error: Invalid option..."
     33 read -p "Press [Enter] key to continue..."
     34 readEnterKey
     35 ;;
     36 esac
     37 done
     38 #MYSCR

答案1

几个问题:

  • 读取一行,它是IFS= read -r line.read -s -p "Enter the password : " passd特别是对于密码包含反斜杠或以 字符开头或结尾的用户,您将无法正常工作$IFS。所以应该是IFS= read -rsp 'Enter the password: ' passd || exit

  • 在 bash 中,列表上下文中的参数扩展必须加引号。"$user@$1",不是$user@$1举例。

  • 听起来-o StrictHostKeyChecking=no有点像请破解我。除非网络可以完全信任,否则向客户端验证服务器几乎与向服务器验证客户端一样重要。该指令就像是说“相信用户就是他们所说的任何人,而不要求他们提供身份证明”如果它是在服务器端完成的。

  • 密码和其他秘密信息绝不应该在命令参数中传递,因为它们是系统内的公共信息。手册sshpass页对此有一个很大的警告。使用SSHPASS="$passd" sshpass -e ssh...,或者最好仍然使用比密码身份验证更好的身份验证形式。

  • 在让变量存储秘密数据之前,最好先对其进行处理,unset以确保它们不会导出到环境中(并且泄漏到命令,这些命令本身可能会将它们泄漏到更远的地方;这里可能不是这种情况)。在 bash 中,那就是unset -v passd.

  • 使用sshpass ... ssh ... << 'HEREDOC',此处文档成为标准sshpass输入,该标准输入将ssh其传递给远程命令。在这里,您没有指定要运行哪个命令,因此它将是远程用户的登录 shell,无论它是什么。

    由于ssh的 stdin 不是终端设备,因此它会请求sshd 不要在远程端创建伪终端,即使-t 这样做也一样,因此 shell 将以非交互方式启动,这也一样好否则将开始回显提示并执行交互式 shell 在您想要执行脚本时执行的所有操作。

    所以在这里,该 shell 将从其标准输入读取要执行的代码。

    但该代码也恰好从其标准输入中读取。那read -p "Enter your choice [ 1 - 3 ]" choice,将从该定理中读取。值得庆幸的是,在 shell 读取read完整循环的代码之前while,它不会运行,因此它只会读取此处文档中之后的内容,或者如果之后没有任何内容,它只会读取任何内容并返回eof 时失败。

bash在这里,您需要在远程主机上运行shell(因为您使用的是 bash 特定的语法),而不是用户的登录 shell(谁会使用 bash 作为登录 shell?:-b),以非交互方式运行并传递它除了通过 stdin 之外,还有其他方式的代码。如果 ssh 服务器AcceptEnv LC_*的配置中有一些常见的,您可以这样做:

code=$(
cat <<'EOF'
the code there
EOF
)

进而:

SSHPASS="$passd" LC_CODE="$code" sshpass -e ssh -o SendEnv=LC_CODE -qt "$user@$1" '
  exec bash -c -- "$LC_CODE"'

这里假设远程主机上的登录 shell$user理解该语法,即$var用于引用变量的位置,并且可以使用双引号进行引用(这对于类似 Bourne 的 shell 来说是必要的,以避免 split+glob)。如果他们的登录 shell 是rc或 衍生的 或zshfish,exec bash -c -- $LC_CODE就足够了(尽管引号仅对类似 shell 有害rc);如果是cshtcshexec bash -c -- $LC_CODE:q

写它:

SSHPASS="$passd" LC_CODE="$code" sshpass -e ssh -o SendEnv=LC_CODE -qt "$user@$1" '
  exec bash -c '\''eval -- "$LC_CODE"'\'

如果用户的登录 shell 是上述任何一个,则可以工作,因为bash -c 'eval -- "$LC_CODE"'至少所有类 Bourne、类 rc、类 csh 和 Fish shell 都可以理解相同的代码。还有一个优点是不会在ps -Awww远程主机的输出中公开该代码。

您可以在以下位置了解更多信息:如何在不知道远程用户的登录 shell 的情况下通过 ssh 执行任意简单命令?

SSHPASS="$passd" sshpass -e ssh -qt "$user@$1" " $code"

正如 @aviro 的答案(在 之前添加额外的空格,以or开头的$code情况所需)仅当用户的登录 shell 恰好是 时才有效。另请注意,它在本地和远程系统的输出中公开了代码。$code-+bashps -Awww


¹ 在这种情况下,它确实sshd如此bash -c thatcode,并且至少在当前版本的 openssh 中,它不这样做bash -c -- thatcode(可能是因为并非所有 shell 都支持或需要它,--或者更可能是因为该问题(在实践中不太可能发生)已被忽视;C 语言也有同样的问题system()几十年来一直被忽视)

答案2

当您使用此处文档时,文本将写入标准输入(标准输入)的过程,在这种情况下 - 到标准输入你的ssh流程。由于您将此处文档重定向到标准输入您的ssh,它无法读取您的键盘。

而不是在标准输入ssh 的,将其分配给一个变量,然后使用该变量作为ssh在远程主机上运行的命令。

# Read the here-document into the $COMMAND variable
read -r -d '' COMMAND << 'MYSCR'
while :
do
  clear
...
MYSCR

# Run ssh with $COMMAND
sshpass -p $passd ssh -qt -o StrictHostKeyChecking=no -o ConnectTimeout=4 $user@$1 "$COMMAND"

相关内容