如何与通过 SSH 发送的脚本建立双向通信?

  • 本文关键字:脚本 建立 双向通信 SSH bash ksh
  • 更新时间 :
  • 英文 :


我正在尝试在Windows盒子(使用bash cli)和qnx盒子(使用ksh cli,尽管目前我正在使用linux VM与ksh98进行测试)之间建立双向通信。

我似乎不能得到重定向很正确,虽然。下面是我的简单设置:

#!/usr/bin/bash
cleanup() {
exec >&$SSH_STDIN- ; rm ssh_stdin
exec <&$SSH_STDOUT-; rm ssh_stdout
echo "Cleaned up."
}
trap 'cleanup' EXIT
mkfifo ssh_stdin ; exec  {SSH_STDIN}<>./ssh_stdin
mkfifo ssh_stdout; exec {SSH_STDOUT}<>./ssh_stdout
echo "SSH_STDIN:  $SSH_STDIN"
echo "SSH_STDOUT: $SSH_STDOUT"
repeat() { echo "$2"; echo "$2" >&$1; }
fn() {
sleep 5
echo AWAKE! >&2
set +o xtrace
while read -u $SSH_STDOUT a b; do
case "$a" in
Hi!)             sleep 1; repeat $SSH_STDOUT "Ho!" ;;
and-away-we-go!) sleep 1; repeat $SSH_STDOUT "quit";;
*) echo "UNRECOGNIZED: $a $b";;
esac
done
}
fn&
ssh user@127.0.0.1 -p 2022  '
. /etc/profile  # Used to setup path
repeat() { echo "$2"; echo "$2" >&$1; }
repeat 2 "Hi!"
while read a b; do
case "$a" in
Ho! ) sleep 1; repeat "and-away-we-go!";;
quit ) exit 0;;
* ) echo "UNRECOGINZED: $a $b";;
esac
done
' >&$SSH_STDIN <&$SSH_STDOUT

我觉得我很接近了。我做错了什么?也许这可以不使用命名fifo ?

编辑

输出:

$ ./test-writer.sh
SSH_STDIN:  11
SSH_STDOUT: 12
user@127.0.0.1's password:
Hi!
AWAKE!
./test-writer.sh: line 21: read: read error: 12: Communication error on send

然后挂起,在我按Ctrl-C后:

./test-writer.sh: line 6: echo: write error: Communication error on send

这是bash -x

$ bash -x ./test-writer.sh
+ trap cleanup EXIT
+ mkfifo ssh_stdin
+ exec
+ mkfifo ssh_stdout
+ exec
+ echo 'SSH_STDIN:  11'
SSH_STDIN:  11
+ echo 'SSH_STDOUT: 12'
SSH_STDOUT: 12
+ fn
+ ssh user@127.0.0.1 -p 2022 '
. /etc/profile  # Used to setup path
repeat() { echo "$2"; echo "$2" >&$1; }
repeat 2 "Hi!"
while read a b; do
case "$a" in
Ho! ) sleep 1; repeat "and-away-we-go!";;
quit ) exit 0;;
* ) echo "UNRECOGINZED: $a $b";;
esac
done
'
+ sleep 5
user@127.0.0.1's password:
Hi!
+ echo 'AWAKE!'
AWAKE!
+ set +o xtrace
./test-writer.sh: line 21: read: read error: 12: Communication error on send

挂起后,我按Ctrl-C得到:

+ cleanup
+ exec
+ rm ssh_stdin
+ exec
+ rm ssh_stdout
+ echo 'Cleaned up.'
./test-writer.sh: line 6: echo: write error: Communication error on send

虽然我有一个解决方案使用coproc,我想知道为什么这个解决方案不工作。

感谢@KamilCuk关于使用coproc的提示,我能够想出一个不那么笨拙的答案。

#!/usr/bin/bash
cleanup() {
# Do I even need this?
exec <&${ssh_fd[0]}- >&${ssh_fd[1]}-
echo "Cleaned up."
}
trap 'cleanup' EXIT
coproc ssh_fd {
ssh user@127.0.0.1 -p 2022  '
. /etc/profile  # Used to setup path
repeat() { echo "$2"; echo "$2" >&$1; }
repeat 2 "Hi!"
while read a b; do
case "$a" in
Ho! ) sleep 1; repeat 2 "and-away-we-go!";;
quit ) exit 0;;
* ) echo "UNRECOGINZED: .$a. .$b." >&2;;
esac
done
'
}
repeat() { echo "$2"; echo "$2" >&$1; }
fn() {
set +o xtrace
while read -u ${ssh_fd[0]} a b; do
case "$a" in
Hi!)             sleep 1; repeat ${ssh_fd[1]}  "Ho!" ;;
and-away-we-go!) sleep 1; repeat ${ssh_fd[1]}  "quit";;
*) echo "UNRECOGNIZED: $a $b";;
esac
done
}
fn

输出:

$  ./test-writer.sh
user@127.0.0.1's password:
Hi!
Ho!
and-away-we-go!
quit

我实际上并没有改变代码中的任何东西,只是删除和移动了一些东西。我是对的!我就快到了!Thx @KamilCuk !

不过,虽然我有这个解决方案,我想知道为什么原来的那个不起作用。我认为应该,如果他们能弄明白,我就接受这些答案。

实际上,我还在寻找解决方案。我不确定为什么开发人员没有重定向所有的句柄,包括STDERR!

最新更新