Скрипт Bash + Expect не работает должным образом в crontab - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть скрипт 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

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

Expect's interact работает, только когда stdin для tty / pty, но задание cron не работает на tty / pty. Поэтому замените interact на expect eof (или expect -timeout 12345 eof, если необходимо).

0 голосов
/ 06 сентября 2018

Это очень неловкий способ передачи ожидаемых команд ожидающему интерпретатору. Вместо этого используйте (в кавычках) heredoc, и вы исключите опцию -f для ожидаемого

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 -d <<'EOF'

и в crontab вы захотите перенаправить stderr в stdout, чтобы получить отладочный вывод

* * * * * /path/to/script.sh 2>&1
0 голосов
/ 06 сентября 2018

Для запуска функции внутри сценария оболочки не следует использовать круглые скобки.

Ваш код становится:

#!/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
...