Finalmente, assumi que a parte restante do script está bem. Então eu segui o @ comment da sobremesa e usei shellcheck
que me leva à questão real e sua solução:
SC2095 : Adicione
< /dev/null
para evitar que o ssh engula stdin.
Então você precisa alterar seu script desta maneira:
ssh -p 2222 "$p" 'who -b' < /dev/null | awk '{print $(NF-1)" "$NF}' >> 'file2'
De acordo com a resposta original e graças aos conselhos úteis, fornecidos nos comentários por @EliahKagan e @ rexkogitans , o script completo poderia ser assim:
#!/bin/bash
# Collect the user's input, and if it's empty set the default values
[[ -z "" ]] && OUT_FILE="reboot-indication.txt" || OUT_FILE=""
[[ -z "" ]] && IN_FILE="hosts.txt" || IN_FILE=""
while IFS= read -r host; do
indication="$(ssh -n "$host" 'LANG=C who -b' | awk '{print $(NF-1)" "$NF}')"
printf '%-14s %s\n' "$host" "$indication" >> "$OUT_FILE"
done < "$IN_FILE"
-
< /dev/null/
é substituído pela opção-n
do comandossh
. Deman ssh
:-n Redirects stdin from /dev/null (actually, prevents reading from stdin). This must be used when ssh is run in the background... This does not work if ssh needs to ask for a password or passphrase; see also the -f option.
-
IFS= read -r line
- como @ StéphaneChazelas diz em sua resposta enciclopédica - é o caminho canônico para leia uma linha de entrada com oread
builtin .-
A chave é que
read
lê palavras de uma linha (possivelmente barra invertida continuada), em que palavras são$IFS
delimitadas e barra invertida podem ser usadas para escapar dos delimitadores (ou continuar linhas). Portanto, o comandoread
deve ser ajustado para ler as linhas. -
IFS=
altera o separador de campos interno para a cadeia nula , Assim, preservamos os espaços em branco iniciais e finais no resultado. -
A opção
-r
- r aw input - desativa a interpretação de escapes de barra invertida e continuação de linha nos dados lidos ( referência ).
-
-
printf '%s %s' "$VAR1" "$VAR2"
fornecerá um melhor formato de saída ( referência ). -
LANG=C
garantirá uma saída idêntica dewho -b
em cada servidor, assim, a análise da saída comawk
também será garantida. -
Observe aqui que o arquivo
~/.ssh/config
e parâmetros adicionais como-p 2222
não são necessários ( referência ).
Chame o script acima de ssh-check.sh
(não se esqueça de chmod +x
) e use-o desta forma:
-
Use os valores padrão dos arquivos de entrada ( hosts.txt ) e de saída ( reboot-indicação.txt ):
./ssh-check.sh
-
Defina o valor personalizado para o arquivo de saída; defina o valor personalizado também para os arquivos de entrada:
./ssh-check.sh 'my-custom.out' ./ssh-check.sh 'my-custom.out' 'my-custom.in'
Leia esta resposta para ver como toda a abordagem poderia ser melhorada.