Execute os comandos em série e pare quando o primeiro comando sair com 0

1

Eu tenho estes 3 comandos:

  mongo cdt_prod_playground --host "mngdb-cbt-stg-01:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"
  mongo cdt_prod_playground --host "mngdb-cbt-stg-02:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})" 
  mongo cdt_prod_playground --host "mngdb-cbt-stg-03:27058" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"

Eu quero executá-los e parar quando o primeiro tiver sucesso. Uma maneira de fazer isso eu acho que seria para eles em uma matriz e sair do loop quando os comandos forem bem-sucedidos, mas como eu faço isso?

(O motivo é que eu preciso fazer isso é porque eu não sei qual host é a réplica definida PRIMARY, então eu só tenho que testar a força bruta, porque eu não tenho a autorização para executar rs.status() .)

    
por Alexander Mills 23.03.2018 / 20:42

3 respostas

3

Em vez de tentar um comando em todos os membros do conjunto de réplicas para descobrir qual deles é o primário atual, você deve usar uma cadeia de caracteres de conexão do conjunto de réplicas com sua linha de comando mongo . Opcionalmente, você pode incluir credenciais de nome de usuário e senha na string de conexão, em vez de usar parâmetros de linha de comando separados.

Exemplo usando o shell do MongoDB 3.6.3:

mongo "mongodb://USERNAME:PASSWORD@mngdb-cbt-stg-01:27058,mngdb-cbt-stg-02:27058/DATABASE?replicaSet=cdt_prod_playground" --eval "db.${file%.*}.remove({})"

Você não precisa listar todos os membros do conjunto de réplicas na cadeia de conexão. Eu usei dois no meu exemplo acima, pois isso deve garantir a descoberta do primário em um conjunto de réplicas de três membros (que precisa de 2/3 de membros votantes disponíveis para manter um primário). O driver / cliente determinará os membros atuais contanto que você inclua o replicaSet name na string de conexão e que pelo menos um dos membros da string de conexão esteja íntegro.

Consulte Formato de URI da cadeia de conexão para obter uma referência das informações disponíveis. opções.

Observe também que chamar db.collection.remove({}) excluirá documentos individuais enquanto mantém as definições de índice. Se você tiver uma quantidade significativa de dados de coleta para remover, seria mais rápido chamar db.colellection.drop() e recriar todos os índices necessários.

The reason is I need to do this is because I don't know which host is the replica set PRIMARY, so I just have to test it brute force, because I don't have the authorization to run rs.status()

Se você precisar descobrir o programa principal atual, use o comando isMaster . Esse comando é usado pelos drivers e clientes do MongoDB (como o mongo shell) como parte da negociação de conexão inicial. Quando conectado a um membro do conjunto de réplicas, a saída isMaster inclui primary e outros detalhes para a atual estado do conjunto de réplicas .

Como no MongoDB 3.6, o comando isMaster não requer autenticação, pois é usado para fornecer informações que os drivers / clientes precisam para a descoberta do servidor e negociar uma conexão autenticada.

    
por 24.03.2018 / 01:08
2

IIUC, você pode unir as linhas com || se mongo retornar diferente de zero no erro. Conforme descrito em man bash :

An OR list has the form

           command1 || command2

   command2 is executed if and only if command1 returns a non-zero exit status.  The return status of AND and OR lists is the exit status of the last command executed in the list.

Eu não tenho mongo aqui, mas posso postar um exemplo succeeds.sh :

#!/usr/bin/env sh
nonexistent-command || \
echo a || \
echo b || \
echo c    

Executar:

$ ./succeeds.sh
./succedds.sh: line 3: nonexistent-command: command not found
a

Como você pode ver, o script para em a porque é o primeiro comando que foi bem-sucedido.

    
por 23.03.2018 / 20:55
1
hostlist=(mngdb-cbt-stg-01:27058 mngdb-cbt-stg-02:27058 mngdb-cbt-stg-03:27058)
hostnum=0
set -u
/bin/false; while [[ 0 -ne $? ]]; do 
  mongo cdt_prod_playground --host "${hostlist[$hostnum]}" -u cdtprodplayground -p "x" --eval "db.${file%.*}.remove({})"
  hostnum=$((hostnum+1))
done
    
por 23.03.2018 / 20:52