Detectando sucesso / falha de upload em uma sessão SFTP de linha de comando com script?

5

Estou escrevendo um script de shell BASH para carregar todos os arquivos em um diretório para um servidor remoto e, em seguida, excluí-los. Ele será executado a cada poucas horas por meio de um trabalho CRON.

Meu script completo está abaixo. O problema básico é que a parte que deve descobrir se o arquivo carregado com sucesso ou não não funciona. O status de saída do comando SFTP é sempre "0", independentemente de o upload ter sido bem-sucedido ou não.

Como posso descobrir se um arquivo foi carregado corretamente ou não, para que eu possa saber se deseja excluí-lo ou deixá-lo ser?

#!/bin/bash

# First, save the folder path containing the files.
FILES=/home/bob/theses/*

# Initialize a blank variable to hold messages.
MESSAGES=""
ERRORS=""


# These are for notifications of file totals.
COUNT=0
ERRORCOUNT=0

# Loop through the files.
for f in $FILES
do
    # Get the base filename
    BASE='basename $f'

    # Build the SFTP command. Note space in folder name.
    CMD='cd "Destination Folder"\n'
    CMD="${CMD}put ${f}\nquit\n"


    # Execute it.
    echo -e $CMD | sftp -oIdentityFile /home/bob/.ssh/id_rsa [email protected]

    # On success, make a note, then delete the local copy of the file.
    if [ $? == "0" ]; then
        MESSAGES="${MESSAGES}\tNew file: ${BASE}\n"
        (( COUNT=$COUNT+1 ))

        # Next line commented out for ease of testing
        #rm $f
    fi

    # On failure, add an error message.
    if [ $? != "0" ]; then
        ERRORS="${ERRORS}\tFailed to upload file ${BASE}\n"
        (( ERRORCOUNT=$ERRORCOUNT+1 ))
    fi

done

SUBJECT="New Theses"

BODY="There were ${COUNT} files and ${ERRORCOUNT} errors in the latest batch.\n\n"

if [ "$MESSAGES" != "" ]; then
    BODY="${BODY}New files:\n\n${MESSAGES}\n\n"
fi

if [ "$ERRORS" != "" ]; then
    BODY="${BODY}Problem files:\n\n${ERRORS}"
fi

# Send a notification. 
echo -e $BODY | mail -s $SUBJECT [email protected]

Devido a algumas considerações operacionais que fazem minha cabeça doer, não posso usar o SCP. O servidor remoto está usando o WinSSHD no Windows e não tem privilégios EXEC, portanto, qualquer comando SCP falhará com a mensagem "Falha na solicitação do Exec no canal 0". O upload, portanto, deve ser feito por meio do comando SFTP interativo.

    
por Will Martin 16.04.2012 / 23:30

5 respostas

6

Se você agrupar sua sessão SFTP, o status de saída $? dirá se é uma transferência com falha ou não.

echo "put testfile1.txt" > batchfile.txt
sftp -b batchfile.txt user@host
if [[ $? != 0 ]]; then
  echo "Transfer failed!"
  exit 1
else
  echo "Transfer complete."
fi

Editado para adicionar: isso é algo que usamos em um script de produção no trabalho, por isso tenho certeza de que é válido. Não podemos usar o scp porque alguns de nossos clientes estão no SCO Unix.

    
por 17.04.2012 / 05:28
1

É tradição do serverfault não questionar indevidamente as condições prévias, mas tenho que perguntar: não é possível você 1) montar o sistema de arquivos remoto via SMB, ou 2) usar o fuse / sshfs? (Eu assumo aqui que a máquina de envio é uma caixa do Linux enquanto você está usando bash e ssh.)

Para responder a sua pergunta, acho que seu problema é simples. Considere:

quest@wonky:~$ false
quest@wonky:~$ if [ $? != "0" ] ; then echo asdf ; fi
asdf
quest@wonky:~$ if [ $? != "0" ] ; then echo asdf ; fi

Tente ao invés disso:

quest@wonky:~$ false
quest@wonky:~$ res=$?
quest@wonky:~$ if [ $res != "0" ] ; then echo asdf ; fi
asdf
quest@wonky:~$ if [ $res != "0" ] ; then echo asdf ; fi
asdf

Para explicar: sua segunda instrução if "if [$?!=" 0 "]; depois" testa o status de saída da última instrução, que não é mais sftp, mas a instrução if anterior.

Então eu imagino, o sftp realmente sairá com um valor diferente de zero se tiver problemas para fazer o upload de arquivos? Testes de rastreamento indicam que o meu não.

    
por 16.04.2012 / 23:50
0

Use rsync(.exe) e insira --remove-source-files & co., nem se importam com uploads falhos, ele vai! ; -)

Sim, você pode amarrar isso com o ssh, veja --rsh

    
por 16.04.2012 / 23:40
0

Jarhead

que tal executar o script Batch sftp no sistema operacional Windows para detectar sucesso / falha?

Eu uso% errorlevel% para detectar sucesso / falha, em algum momento o% errorlevel% é retornado por 0, mas essa sessão falha e o arquivo não é enviado para o servidor. meu script está abaixo

como posso detectar o sftp carregado corretamente? THX muito

@echo off
(echo cd %4
  echo put %2
  echo exit)>sftpScript.txt
sftp -b sftpScript.txt %3
set result=%errorlevel%
if result EQU 0 (
  del sftpScript.txt
  del %2
) else (
  del sftpScript.txt
)
exit %result%
    
por 21.11.2012 / 03:58
0

** editado para usar um arquivo em lote Para expandir a solução baseada em lote.
Na cópia do sftp que estou executando, um arquivo de lote sai em um erro, mesmo que existam vários comandos além do ponto de erro

Pela lógica originalmente postada, ao verificar $ ?, você está testando o resultado de todo o lote. Se você está bem com a remoção de alguns dos arquivos que foram transmitidos com sucesso, então construa o arquivo de lote com! Rm após cada put. Se o put falhar, o! Rm não será executado

(for F in *.pgp
do
echo put $F
echo !rm $F
done;echo quit) > Batchfile ; sftp -b Batchfile user@targetServer
    
por 03.02.2017 / 20:52