通过使用 Expect 配置 mgre 的 ODD 错误:无效的命令名称“0”
ODD error via using Expect to config mgre: invalid command name "0"
我正在使用一个 shell 脚本嵌入一个 expect 脚本以通过 ssh 连接到远程服务器以配置 dmvpn(ipsec+mgre+nhrp),我还使用 temlate cli 呈现为每个协议的配置.
我的文件结构如下:
- dmvpn.sh
- ipsec_sec.cli(ipsec.secrets 的模板文件)
- ipsec_cnf.cli(ipsec.conf 的模板文件)
- mgre.cli(mgre 的模板文件)
- nrhp.cli(nhrp 模板文件)
dmvpn.sh:
我使用以下代码导入模板文件
source ./dmvpn/ipsec_sec.cli
source ./dmvpn/ipsec_cnf.cli
source ./dmvpn/mgre.cli
source ./dmvpn/nhrp.cli
以及渲染模板的以下代码:
sec_cmd=`eval $sec`
cnf_cmd=`eval $cnf`
mgre_cmd=`eval $mgre`
nhrp_cmd=`eval $nh`
mgre.cli:
mgre='
if [ "$remote_ip" == "0.0.0.0" ]; then
echo "ip tunnel add $if_name mode gre local $local_ip key $key ttl $ttl";
else
echo "ip tunnel add $if_name mode gre local $local_ip remote $remote_ip key $key ttl $ttl";
fi;
echo "ip addr add $ip_mask dev $if_name";
echo "ip link set dev $if_name up";
echo "uci set network.$if_name=interface";
echo "uci set network.$if_name.ifname=$if_name";
echo "uci set network.$if_name.proto=static";
echo "uci set network.$if_name.ipaddr=$wip";
echo "uci set network.$if_name.netmask=$msk";
echo "uci commit network";
echo "/etc/init.d/network restart";
'
期待 dmvpn.sh 中的脚本:
expect "#"
send "cat > /etc/ipsec.secrets << EOF
$sec_cmd
EOF\r"
expect "#"
send "sed -i \"/conn ${ipsec_name}/,/ type/d\" /etc/ipsec.conf \r"
expect "#"
send "cat >> /etc/ipsec.conf << EOF
$cnf_cmd
EOF\r"
expect "#"
send "ipsec reload\r"
expect "#"
send "$mgre_cmd\r"
expect "#"
send "$nhrp_cmd\r"
每个模板文件都以相同的方式设计,但是,在执行 $mgre_cmd 时,我收到以下错误:
root@OpenWrt:~# invalid command name "0"
while executing
"0"
invoked from within
"send "ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255
ip addr add 2.2.12.1/24 dev gre1
ip link set dev gre1 up
uci set network.gre1=inte..."
$nhrp_cmd、$sec_cmd、$cnf_cmd都没有出现这样的错误,不知道为什么。 nhrp.cli如下:
nhrp='
echo "vtysh \r
conf \r
int $if_name \r
ip nhrp network-id $network_id";
if [ "$nhs_wan_ip" == "0.0.0.0" ]; then
echo "ip nhrp nhs dynamic nbma $nhs_ip";
else
echo "ip nhrp nhs $nhs_wan_ip nbma $nhs_ip";
fi;
if $shortcut; then
echo "ip nhrp shortcut";
fi;
if $redirect; then
echo "ip nhrp redirect";
fi;
echo "tunnel source $tunnel_source \r
end \r
write \r
exit ";
'
完整的expect脚本如下:
/usr/bin/expect<<-EOF
log_file dmvpn/${host}_add_dmvpn.log
spawn ssh -p $port $user@$host
expect {
-re "Are you sure you want to continue connecting (yes/no)?" {
send "yes\r"
}
"*password:" {
send "${loginpass}\r"
}
-re "Permission denied, please try again." {
exit
}
}
expect "#"
send "cat > /etc/ipsec.secrets << EOF
$sec_cmd
EOF\r"
expect "#"
send "sed -i \"/conn ${ipsec_name}/,/ type/d\" /etc/ipsec.conf \r"
expect "#"
send "cat >> /etc/ipsec.conf << EOF
$cnf_cmd
EOF\r"
expect "#"
send "ipsec reload\r"
expect "#"
send "$mgre_cmd\r"
expect "#"
send "$nhrp_cmd\r"
expect "#"
send "exit\r"
expect eof
EOF
echo $mgre_cmd
的结果:
ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255 ip addr add 2.2.12.1/24 dev gre1 ip link set dev gre1 up uci set network.gre1=interface uci set network.gre1.ifname=gre1 uci set network.gre1.proto=static uci set network.gre1.ipaddr=2.2.12.1 uci set network.gre1.netmask=255.255.255.0 uci commit network /etc/init.d/network restart
当我使用/usr/bin/expect -d <<-EOF
时,我得到以下信息:(只执行$mgre_cmd)
spawn ssh -p 22 root@10.25.110.1
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {15176}
Gate keeper glob pattern for 'Are you sure you want to continue connecting (yes/no)?' is 'Are you sure you want to continue connecting *'. Activating booster.
Gate keeper glob pattern for 'Permission denied, please try again.' is 'Permission denied, please try again?'. Activating booster.
expect: does "" (spawn_id exp7) match regular expression "Are you sure you want to continue connecting (yes/no)?"? Gate "Are you sure you want to continue connecting *"? gate=no
"*password:"? no
"Permission denied, please try again."? Gate "Permission denied, please try again?"? gate=no
root@10.25.110.1's password:
expect: does "root@10.25.110.1's password: " (spawn_id exp7) match regular expression "Are you sure you want to continue connecting (yes/no)?"? Gate "Are you sure you want to continue connecting *"? gate=no
"*password:"? yes
expect: set expect_out(0,string) "root@10.25.110.1's password:"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "root@10.25.110.1's password:"
send: sending "zzs\r" to { exp7 }
expect: does " " (spawn_id exp7) match glob pattern "#"? no
expect: does " \r\n" (spawn_id exp7) match glob pattern "#"? no
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
uCPE 1.0.0, r11063-85e04e9f46
-----------------------------------------------------
expect: does " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n" (spawn_id exp7) match glob pattern "#"? no
]0;root@OpenWrt: ~root@OpenWrt:~#
expect: does " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n\u001b]0;root@OpenWrt: ~\u0007root@OpenWrt:~# " (spawn_id exp7) match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n\u001b]0;root@OpenWrt: ~\u0007root@OpenWrt:~#"
invalid command name "0"
while executing
"0"
invoked from within
"send "ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255\r
ip addr add 2.2.12.1/24 dev gre1 \r ip link set dev gre1 up \r uci set network.g..."
我终于成功了!虽然我仍然不知道 mgre.cli 和其他 clis 之间有什么区别。
我将此命令 send "$mgre_cmd \r"
更改为 send -- {$mgre_cmd}
和 send -- \r
我注意到在 shell 脚本中执行 expect 命令或 tcl 命令时,我们有时需要使用转义字符来修复命令。我们可以用send -- {}
来翻译整个命令的意思。
我正在使用一个 shell 脚本嵌入一个 expect 脚本以通过 ssh 连接到远程服务器以配置 dmvpn(ipsec+mgre+nhrp),我还使用 temlate cli 呈现为每个协议的配置. 我的文件结构如下:
- dmvpn.sh
- ipsec_sec.cli(ipsec.secrets 的模板文件)
- ipsec_cnf.cli(ipsec.conf 的模板文件)
- mgre.cli(mgre 的模板文件)
- nrhp.cli(nhrp 模板文件)
dmvpn.sh: 我使用以下代码导入模板文件
source ./dmvpn/ipsec_sec.cli
source ./dmvpn/ipsec_cnf.cli
source ./dmvpn/mgre.cli
source ./dmvpn/nhrp.cli
以及渲染模板的以下代码:
sec_cmd=`eval $sec`
cnf_cmd=`eval $cnf`
mgre_cmd=`eval $mgre`
nhrp_cmd=`eval $nh`
mgre.cli:
mgre='
if [ "$remote_ip" == "0.0.0.0" ]; then
echo "ip tunnel add $if_name mode gre local $local_ip key $key ttl $ttl";
else
echo "ip tunnel add $if_name mode gre local $local_ip remote $remote_ip key $key ttl $ttl";
fi;
echo "ip addr add $ip_mask dev $if_name";
echo "ip link set dev $if_name up";
echo "uci set network.$if_name=interface";
echo "uci set network.$if_name.ifname=$if_name";
echo "uci set network.$if_name.proto=static";
echo "uci set network.$if_name.ipaddr=$wip";
echo "uci set network.$if_name.netmask=$msk";
echo "uci commit network";
echo "/etc/init.d/network restart";
'
期待 dmvpn.sh 中的脚本:
expect "#"
send "cat > /etc/ipsec.secrets << EOF
$sec_cmd
EOF\r"
expect "#"
send "sed -i \"/conn ${ipsec_name}/,/ type/d\" /etc/ipsec.conf \r"
expect "#"
send "cat >> /etc/ipsec.conf << EOF
$cnf_cmd
EOF\r"
expect "#"
send "ipsec reload\r"
expect "#"
send "$mgre_cmd\r"
expect "#"
send "$nhrp_cmd\r"
每个模板文件都以相同的方式设计,但是,在执行 $mgre_cmd 时,我收到以下错误:
root@OpenWrt:~# invalid command name "0"
while executing
"0"
invoked from within
"send "ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255
ip addr add 2.2.12.1/24 dev gre1
ip link set dev gre1 up
uci set network.gre1=inte..."
$nhrp_cmd、$sec_cmd、$cnf_cmd都没有出现这样的错误,不知道为什么。 nhrp.cli如下:
nhrp='
echo "vtysh \r
conf \r
int $if_name \r
ip nhrp network-id $network_id";
if [ "$nhs_wan_ip" == "0.0.0.0" ]; then
echo "ip nhrp nhs dynamic nbma $nhs_ip";
else
echo "ip nhrp nhs $nhs_wan_ip nbma $nhs_ip";
fi;
if $shortcut; then
echo "ip nhrp shortcut";
fi;
if $redirect; then
echo "ip nhrp redirect";
fi;
echo "tunnel source $tunnel_source \r
end \r
write \r
exit ";
'
完整的expect脚本如下:
/usr/bin/expect<<-EOF
log_file dmvpn/${host}_add_dmvpn.log
spawn ssh -p $port $user@$host
expect {
-re "Are you sure you want to continue connecting (yes/no)?" {
send "yes\r"
}
"*password:" {
send "${loginpass}\r"
}
-re "Permission denied, please try again." {
exit
}
}
expect "#"
send "cat > /etc/ipsec.secrets << EOF
$sec_cmd
EOF\r"
expect "#"
send "sed -i \"/conn ${ipsec_name}/,/ type/d\" /etc/ipsec.conf \r"
expect "#"
send "cat >> /etc/ipsec.conf << EOF
$cnf_cmd
EOF\r"
expect "#"
send "ipsec reload\r"
expect "#"
send "$mgre_cmd\r"
expect "#"
send "$nhrp_cmd\r"
expect "#"
send "exit\r"
expect eof
EOF
echo $mgre_cmd
的结果:
ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255 ip addr add 2.2.12.1/24 dev gre1 ip link set dev gre1 up uci set network.gre1=interface uci set network.gre1.ifname=gre1 uci set network.gre1.proto=static uci set network.gre1.ipaddr=2.2.12.1 uci set network.gre1.netmask=255.255.255.0 uci commit network /etc/init.d/network restart
当我使用/usr/bin/expect -d <<-EOF
时,我得到以下信息:(只执行$mgre_cmd)
spawn ssh -p 22 root@10.25.110.1
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {15176}
Gate keeper glob pattern for 'Are you sure you want to continue connecting (yes/no)?' is 'Are you sure you want to continue connecting *'. Activating booster.
Gate keeper glob pattern for 'Permission denied, please try again.' is 'Permission denied, please try again?'. Activating booster.
expect: does "" (spawn_id exp7) match regular expression "Are you sure you want to continue connecting (yes/no)?"? Gate "Are you sure you want to continue connecting *"? gate=no
"*password:"? no
"Permission denied, please try again."? Gate "Permission denied, please try again?"? gate=no
root@10.25.110.1's password:
expect: does "root@10.25.110.1's password: " (spawn_id exp7) match regular expression "Are you sure you want to continue connecting (yes/no)?"? Gate "Are you sure you want to continue connecting *"? gate=no
"*password:"? yes
expect: set expect_out(0,string) "root@10.25.110.1's password:"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "root@10.25.110.1's password:"
send: sending "zzs\r" to { exp7 }
expect: does " " (spawn_id exp7) match glob pattern "#"? no
expect: does " \r\n" (spawn_id exp7) match glob pattern "#"? no
_______ ________ __
| |.-----.-----.-----.| | | |.----.| |_
| - || _ | -__| || | | || _|| _|
|_______|| __|_____|__|__||________||__| |____|
|__| W I R E L E S S F R E E D O M
-----------------------------------------------------
uCPE 1.0.0, r11063-85e04e9f46
-----------------------------------------------------
expect: does " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n" (spawn_id exp7) match glob pattern "#"? no
]0;root@OpenWrt: ~root@OpenWrt:~#
expect: does " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n\u001b]0;root@OpenWrt: ~\u0007root@OpenWrt:~# " (spawn_id exp7) match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) " \r\n _______ ________ __\r\n | |.-----.-----.-----.| | | |.----.| |_\r\n | - || _ | -__| || | | || _|| _|\r\n |_______|| __|_____|__|__||________||__| |____|\r\n |__| W I R E L E S S F R E E D O M\r\n -----------------------------------------------------\r\n uCPE 1.0.0, r11063-85e04e9f46\r\n -----------------------------------------------------\r\n\u001b]0;root@OpenWrt: ~\u0007root@OpenWrt:~#"
invalid command name "0"
while executing
"0"
invoked from within
"send "ip tunnel add gre1 mode gre local 10.25.110.1 key 123 ttl 255\r
ip addr add 2.2.12.1/24 dev gre1 \r ip link set dev gre1 up \r uci set network.g..."
我终于成功了!虽然我仍然不知道 mgre.cli 和其他 clis 之间有什么区别。
我将此命令 send "$mgre_cmd \r"
更改为 send -- {$mgre_cmd}
和 send -- \r
我注意到在 shell 脚本中执行 expect 命令或 tcl 命令时,我们有时需要使用转义字符来修复命令。我们可以用send -- {}
来翻译整个命令的意思。