遍历文件并通过期望发送命令

Loop through file and send commands over expect

我正试图将命令从一个文件发送到一个超出预期的设备。我试着从我的本地机器一次发送一个,但我所有的文件路径都是相对于本地的,而不是相对于远程设备的。我的解决方案是尝试将文件上传到设备并从那里加载命令。当我尝试加载文件时,我不断遇到权限问题,即使我从设备上抓取文件也没有读取问题。该文件每行有 1 个命令。

devicepath=rsync://root@localhost:$PORT_RSYNC/root/var/root/file.txt
/usr/bin/rsync -Pavr  $devicepath
    
expect <<- expect_feed
set  send_slow  {1  .001}
spawn ssh -o NoHostAuthenticationForLocalhost=yes -p $PORT_SSH root@localhost
expect -re "password:"
send -s "password\r"
expect -re $PROMPT_ROOT
send -s "chmod 777 /var/root/file.txt\r"
expect -re $PROMPT_ROOT
set f [cat /var/root/file.txt]
set cmds [split [read $f] "\n"]
close $f
foreach line $cmds {
    send -s "$line\r"
    expect -re $PROMPT_ROOT
expect_feed

这产生:

root# cat: /var/root/file.txt: Permission denied

我也试过了

set f [open /var/root/file.txt]

...但它给出了同样的错误。

如果您发送的文件包含 shell 命令,请将其视为此类并简单地 source 它在远程主机上

devicepath=rsync://root@localhost:$PORT_RSYNC/root/var/root/file.txt
/usr/bin/rsync -Pavr "" "$devicepath"

export PROMPT_ROOT PORT_SSH

expect << 'EXPECT_FEED'
    set send_slow {1  .001}
    spawn ssh -o NoHostAuthenticationForLocalhost=yes -p $env(PORT_SSH) root@localhost
    expect -re "password:"
    send -s "password\r"
    expect -re $env(PROMPT_ROOT)
    send -s ". /var/root/file.txt\r" ;# <<<<
    expect -re $env(PROMPT_ROOT)
    send "exit\r"
    expect eof
EXPECT_FEED

我更喜欢使用引用的 heredocs:shell 变量可以通过环境传递给 expect。

我假设 root 的 shell 是 POSIX 类型的 shell,其中 . 是“源”命令。

感谢您的宝贵建议。它是这样工作的。

既然它一次发送一行并等待响应,那么它可能会在没有发送慢的情况下工作得很好。

文件中的最后一个命令是 'quit',以便 return 到 root 提示符,我想这可能是硬编码的

cmdpath=
export cmdpath

    expect << 'EXPECT_FEED'
        set send_slow {1  .001}
        set commandfile [open $env(cmdpath)]
        spawn ssh -o NoHostAuthenticationForLocalhost=yes -p $env(PORT_SSH) root@localhost
        expect -re "password:"
        send -s "password\r"
        expect -re $env(PROMPT_ROOT)
        send -s ">the name of the process accepting commands<\r"
        while { [gets $commandfile line] != -1 } {
            expect -re $env(PROMPT)
            send -s "$line\r" }
        expect -re $env(PROMPT_ROOT)
        send "exit\r"
        expect eof
EXPECT_FEED