Se condição com comando ssh dentro

1

Estou fazendo um script bash para fazer backup do meu computador em um servidor local. Eu preciso compactar os arquivos, mas não consigo encontrar uma maneira de fazer isso se a condição funcionar com um comando ssh dentro:

if [ ssh [email protected] '$(ls -d /snapshots/$(date -v -7d +%Y%m%d)* 2> /dev/null | wc -l) != "0"' ]
then
    ssh [email protected] "tar -czf $ARCHIVES_DIR/$YESTERDAY.tar.gz $SNAPSHOT_DIR/$YESTERDAY* \
    && rm -rf $SNAPSHOT_DIR/$YESTERDAY*"
fi

Eu tenho um erro "Muitos argumentos" (dentro do if).

O que estou fazendo de errado?

    
por ge0ra 14.08.2015 / 15:43

4 respostas

2

Eu sugiro que você simplifique a construção e dê à próxima pessoa que estiver lendo o código a chance de ver o que está acontecendo. Seu principal problema é que você parece estar confundindo sua execução indireta $( ... ) com [ ... ] como um operador de teste. Desculpas se eu entendi mal o fluxo, mas acho que isso é o que você pretende:

# Count files on the remote system and confirm that there is at least one
DATE7=$(date -v -7d '+%Y%m%d')
NFILES=$(ssh [email protected] "ls -d '/snapshots/$DATE7'* 2> /dev/null | wc -l")

# If the ssh worked and we have found files then archive them
if [ $? -eq 0 && 0 -lt $NFILES ]
then
    # Archive the files
    ssh [email protected] "
        tar -czf '$ARCHIVES_DIR/$YESTERDAY.tar.gz' '$SNAPSHOT_DIR/$YESTERDAY'* &&
        rm -rf '$SNAPSHOT_DIR/$YESTERDAY'
    "
fi

Isso supõe que ARCHIVES_DIR , SNAPSHOT_DIR e YESTERDAY estão definidos localmente em outro lugar no seu script.

Lembre-se de que "..." interpola os valores das variáveis imediatamente, enquanto '...' tratará o texto como $WIDGET como uma cadeia de sete caracteres literais começando com um símbolo de dólar. Isso é importante observar, já que tenho seqüências como " '...' " e ' "..." ' neste código.

    
por 14.08.2015 / 16:05
2

É possível usar o status de retorno de um comando como condição, mas a sintaxe correta é sem colchetes. Por outro lado, você precisará dos colchetes ou do comando "test" no host remoto. (Eu prefiro teste para isso.) Tente isso:

if ssh [email protected] 'test $(ls -d /snapshots/$(date -v -7d +%Y%m%d)* 2> /dev/null | wc -l) != "0"'
then
    ssh [email protected] "tar -czf $ARCHIVES_DIR/$YESTERDAY.tar.gz $SNAPSHOT_DIR/$YESTERDAY* \
    && rm -rf $SNAPSHOT_DIR/$YESTERDAY*"
fi

Você também pode querer verificar o comando date. Pelo menos no meu sistema Linux, eu tenho date: invalid option -- 'v' .

    
por 14.08.2015 / 16:04
1

O formulário if [ ... ] é uma chamada para test : a expressão entre colchetes é avaliada de acordo com as regras sintáticas de test , e um código de retorno é emitido, que é o que if interpreta. Você provavelmente quer simplesmente se livrar dos parênteses:

if ssh ... | grep -q .

O comando grep retornará um código de retorno de sucesso ("true" para if ) se tiver alguma correspondência bem-sucedida; no caso atual, se a saída do comando ssh não estiver vazia. Uma tradução mais literal do seu código original seria:

if [ $(ssh ... | wc -l) != 0 ]

No tempo de execução, a expressão $(...) é substituída pela saída de texto pelo comando incluído; um inteiro, o que significa que test vê uma comparação adequada entre esse inteiro e zero.

    
por 14.08.2015 / 15:57
1

Como sua pergunta é apenas sobre a expressão condicional, testei apenas a parte if.

Você pode fazer assim:

if [ $(ssh [email protected] 'ls -d /snapshots/$(date -v -7d +%Y%m%d)* 2> /dev/null | wc -l') != "0" ]
then
    # do something
fi

Um pequeno acréscimo à minha resposta:

Você provavelmente terá que ser responsável por não conseguir fazer essa conexão SSH também (em vez de apenas verificar se a contagem de linhas é diferente de zero).

Porque se a sua conexão falhar, o resultado também será "não zero".

Para um melhor tratamento de erros, você pode usar algo assim:

lines=$(ssh [email protected] 'ls -d /snapshots/$(date -v -7d +%Y%m%d)* 2> /dev/null | wc -l')
result=$?
# If 'ssh'-command succesful:
if [ $result == "0" ]
then
    # If number of lines is non-zero:
    if [ $lines != "0" ]
    then
        # do something
    fi
else
    # handle error based on $result
fi
    
por 14.08.2015 / 16:07