我有一个程序使用heredoc“stop_remoteServer_script.sh”创建动态shell脚本
下面的heredoc模板
cat<<_STOP > stop_remoteServer_script.sh
#!/bin/bash
serverName=\$1
function getServerpid {
pid=\$( ps -ef|grep \${serverName}|grep -v grep |awk '{print \$2}' )
echo \$pid
}
function kill_soaServer {
echo "Killing \${serverName} ........"
ps -ef|grep \${serverName} |grep -v grep|awk '{print \$2}'|xargs kill -9
echo "status of killing server is $?"
}
check_soaServer=\$( getServerpid );
while [[ "X\${check_soaServer}" != "X" ]]
do
cmd_status=\$( kill_soaServer )
sleep 30s
check_soaServer=\$( getServerpid )
done
kill_soaServer \${serverName}
_STOP
发送到远程盒子执行的实际脚本
模板输出
#!/bin/bash
serverName=$1
function getServerpid {
pid=$( ps -ef|grep ${serverName}|grep -v grep |awk '{print $2}' )
echo $pid
}
function kill_soaServer {
echo "Killing ${serverName} ........"
ps -ef|grep ${serverName} |grep -v grep|awk '{print $2}'|xargs kill -9
echo "status of killing server is 0"
}
check_soaServer=$( getServerpid );
while [[ "X${check_soaServer}" != "X" ]]
do
cmd_status=$( kill_soaServer )
sleep 30s
check_soaServer=$( getServerpid )
done
kill_soaServer ${serverName}
现在我有一个低于预期的代码块,它将使用服务器名称参数调用远程框中的上述生成的代码
sName=$1
CMD="ssh -o StrictHostKeyChecking=no ${remoteUserName}\@${remoteHostName} "
# script with parameter
script="./stop_remoteServer_script.sh ${sName}"
/usr/bin/expect<<END
set force_conservative 0
spawn bash -c "${CMD} /bin/bash < ${script} "
expect "* password: "
send -- "${MYPWD}\r"
expect "*$*"
expect eof
END
我收到的错误如下
spawn bash -c ssh -o StrictHostKeyChecking=no [email protected] /bin/bash < ./stop_remoteServer_script.sh soa_server2
[email protected]'s password:
/bin/bash: soa_server2: No such file or directory
任何人都可以帮我如何发送参数,手动它可以工作
===================
根据建议进行额外尝试:
我使用虚拟盒创建了一个简单的网络并在下面进行了尝试
主程序
#!/bin/bash
# script with parameter
echo "running exp example"
sName="abc123ibc"
script="a.sh"
echo "thes script is $script \n"
/usr/bin/expect -d <<END
set force_conservative 0
set timeout -1
set prompt "*$*"
puts "before swapn"
spawn scp ./a.sh -o StrictHostKeyChecking=no ansibleadm\@192.168.1.102:/home/ansibleadm/
expect "id_rsa*"
send -- "ansibleadm\r"
expect "*$*"
expect eof
puts "second spawn"
spawn ssh -o StrictHostKeyChecking=no ansibleadm\@192.168.1.102 /bin/bash -c ./a.sh $sName > log.txt
expect "id_rsa*"
send -- "ansibleadm\r"
expect ""
puts "after spawn"
expect eof
END
还有一个a.sh
#!/bin/bash
sleep 12s
echo "inside swapned script"
touch ~/sample.txt
cat > ~/sample.txt<<EOF
hi suman $1
EOF
在sample.txt中我总是得到的是变量缺失的下面
[ansibleadm@AppServer ~]$ cat sample.txt
hi suman
我已经启用了期望的调试器,下面是调试日志
[ansibleadm@Centos-Control ~]$ ./exp.sh
running exp example
thes script is a.sh \n
expect version 5.45.4
argv[0] = /usr/bin/expect argv[1] = -d
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
executing commands from command file
before swapn
spawn scp ./a.sh -o StrictHostKeyChecking=no [email protected]:/home/ansibleadm/
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {33533}
expect: does "" (spawn_id exp6) match glob pattern "id_rsa*"? no
Enter passphrase for key '/home/ansibleadm/.ssh/id_rsa':
expect: does "\rEnter passphrase for key '/home/ansibleadm/.ssh/id_rsa': " (spawn_id exp6) match glob pattern "id_rsa*"? yes
expect: set expect_out(0,string) "id_rsa': "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\rEnter passphrase for key '/home/ansibleadm/.ssh/id_rsa': "
send: sending "ansibleadm\r" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "*"? yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) ""
a.sh 100% 114 165.9KB/s 00:00
-o: No such file or directory
StrictHostKeyChecking=no: No such file or directory
expect: read eof
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\r\n\ra.sh
||| 0% 0 0.0KB/s --:-- ETA\ra.sh
||| 100% 114 165.9KB/s 00:00 \r\n-o: No such file or directory\r\nStrictHostKeyChecking=no: No such file or directory\r\n"
second spawn
spawn ssh -o StrictHostKeyChecking=no [email protected] /bin/bash -c ./a.sh abc123ibc > log.txt
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {33541}
expect: does "" (spawn_id exp10) match glob pattern "id_rsa*"? no
Enter passphrase for key '/home/ansibleadm/.ssh/id_rsa':
expect: does "\rEnter passphrase for key '/home/ansibleadm/.ssh/id_rsa': " (spawn_id exp10) match glob pattern "id_rsa*"? yes
expect: set expect_out(0,string) "id_rsa': "
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) "\rEnter passphrase for key '/home/ansibleadm/.ssh/id_rsa': "
send: sending "ansibleadm\r" to { exp10 }
expect: does "" (spawn_id exp10) match glob pattern ""? yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) ""
after spawn
expect: read eof
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) "\r\n"
[ansibleadm@Centos-Control ~]$
答案1
你使生成过于复杂:
CMD="ssh -o StrictHostKeyChecking=no ${remoteUserName}\@${remoteHostName} "
# script with parameter
script="./stop_remoteServer_script.sh ${sName}"
/usr/bin/expect<<END
set force_conservative 0
spawn ${CMD} bash ${script}
...
如果脚本有执行权限,你bash
也可以删除。
因为 $script 变量包含空格:
- 这:
/bin/bash < ${script}
- 变成这样:
/bin/bash < ./stop_remoteServer_script.sh soa_server2
- bash 解释为:
/bin/bash soa_server2 < ./stop_remoteServer_script.sh
- 导致“soa_server2:没有这样的文件”错误
答案2
要要求bash
从 stdin 读取命令,您需要该-s
选项,后跟要传递给调用的参数。例如:
$ echo 'date +$1' | bash -s %Y
2021
所以在你的命令-s
后面添加。/bin/bash
spawn
请注意,对于-c
命令后面的参数,$0
您需要首先设置,例如:
bash -c 'echo $(date +$1)' dummy %Y