【问题标题】:Bash+Expect script not running properly in crontabBash+Expect 脚本在 crontab 中无法正常运行
【发布时间】:2018-09-07 00:00:54
【问题描述】:

我有一个应该定期运行的 bash 脚本。该脚本应连接到远程 SFTP 服务器并从那里获取文件。 由于这是一个 SFTP 服务器,我不得不将期望与 bash 脚本一起使用。 该脚本在我手动运行时运行良好,但在通过 crontab 运行时失败。 有问题的函数是get_JSON_file() 请指教...

这是代码:

#!/bin/bash

export xxxxx
export xxxxx
export PATH=xxxxx

check_if_file_is_open(){
while :
do
    if ! [[ `lsof | grep file.txt` ]]
    then
        break
    fi
    sleep 1
done
}


get_JSON_file(){
/usr/bin/expect -f <(cat << EOF
spawn sftp -P port user@ip
expect "Password:"
send "password\r"
expect "$ "
send "get path/to/file/file.json\r"
send "exit\r"
interact
EOF
)
}


get_JSON_file
check_if_file_is_open
cp file.txt /path/to/destination/folder

【问题讨论】:

标签: linux bash shell cron expect


【解决方案1】:

Expect 的 interact 仅在 stdin 位于 tty/pty 上但 cron 作业未在 tty/pty 上运行时有效。因此,将interact 替换为expect eof(或expect -timeout 12345 eof,如有必要)。

【解决方案2】:

这是将期望命令传递给期望解释器的一种非常尴尬的方式。改用(引用的)heredoc,你会放弃 -f 选项 for expect

get_JSON_file(){
    /usr/bin/expect <<'EOF'
        spawn sftp -P port user@ip
        expect "Password:"
        send "password\r"
        expect "$ "
        send "get path/to/file/file.json\r"
        send "exit\r"
        expect eof
EOF
}

调试expect 脚本最重要的技巧是调用expect 的调试输出。在解决问题时,请使用

expect -d <<'EOF'

在 crontab 中,您希望将 stderr 重定向到 stdout,以便获得调试输出

* * * * * /path/to/script.sh 2>&1

【讨论】:

    【解决方案3】:

    要在 shell 脚本中运行函数,不应使用括号。

    然后你的代码变成:

    #!/bin/bash
    
    export xxxxx
    export xxxxx
    export PATH=xxxxx
    
    function check_if_file_is_open(){
    while :
    do
        if ! [[ `lsof | grep file.txt` ]]
        then
            break
        fi
        sleep 1
    done
    }
    
    
    function get_JSON_file(){
    /usr/bin/expect -f <(cat << EOF
    spawn sftp -P port user@ip
    expect "Password:"
    send "password\r"
    expect "$ "
    send "get path/to/file/file.json\r"
    send "exit\r"
    interact
    EOF
    )
    }
    
    
    get_JSON_file
    check_if_file_is_open
    cp file.txt /path/to/destination/folder
    

    【讨论】:

    • 这是一个重要的修复,但对解决 OP 脚本中的各种其他缺陷和低效率无济于事。
    • 我没有括号,当我调用函数时。我在这里错误地添加了它))主要问题是sftp命令没有被执行(或没有正确执行)
    • 糟糕,抱歉。这是我看到的一个明显错误。我不是使用 sftp 工具的专家,因为我主要使用 cURL 或 wget(也可能是 scp/rsync)来获取文件。这可以很容易地自动化,并且可以省略 -send/expect/interact- 构造。
    猜你喜欢
    • 2023-03-04
    • 2014-02-20
    • 2021-10-25
    • 2018-12-27
    • 2014-07-12
    • 2016-10-20
    • 1970-01-01
    • 2017-12-02
    • 2018-08-10
    相关资源
    最近更新 更多