我正在尝试在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!