comando do Grep usando o conteúdo de um heredoc

1

Estou criando um script para atualizar um computador remoto e quero saber se algum usuário está usando o computador antes de eu atualizar. Eu tenho uma lista de usuários e criei um heredoc com todos eles. O comando que estou tentando fazer é algo como isto:

ps -ef | grep -f | cat <<- END
    user1
    user2
    user3
END

O que não funciona. O que posso fazer para poder filtrar o comando ps com base na minha lista de usuários usando um heredoc?

    
por JefersonFG 22.04.2016 / 20:07

2 respostas

4

Resposta curta: ps -u user1,user2,user3

Seu comando grep está incompleto, pois a opção -f requer um argumento. Seu comando cat está recebendo sua entrada do documento here, portanto, mesmo que você tenha corrigido o comando grep , sua saída será descartada.

Se você estivesse procurando por um usuário codificado, você usaria

ps -ef | grep alice

(exceto que esta não é uma boa maneira de fazer isso, como explicarei mais adiante). A entrada para grep é a saída de ps -ef . Você pode passar vários padrões de pesquisa passando várias opções -e :

ps -ef | grep -e alice -e bob

Isto imprime linhas contendo alice ou bob . Para obter a lista de entradas de um arquivo, você pode usar a opção -f , mas isso requer um nome de arquivo.

cat <<EOF >users.txt
alice
bob
END
ps -ef | grep -f users.txt

A entrada padrão já foi inserida para o texto que você está filtrando, portanto, não é possível reutilizá-lo para o padrão de pesquisa. Desejar múltiplas entradas é um problema comum, então algumas shells (ksh, bash, zsh) oferecem uma solução: substituição de processos (que é o que don_crissti sugerido em um comentário ):

ps -ef | grep -f <(cat <<END
alice
bob
END
)

Essa abordagem é útil se a lista de usuários for gerada por um comando complexo, mas com uma lista codificada, é desnecessariamente complexa: grep -e alice -e bob faz o mesmo trabalho.

O problema com essa abordagem é que ela combina nomes de usuário em qualquer lugar da linha. O comando ps tem uma opção para listar apenas os processos de um conjunto específico de usuários. Apenas use isso.

ps -u alice,bob

Se você estiver em um sistema incorporado com uma versão de ps que não suporta -u , veja se ele aceita -o USER e use grep -x para corresponder à linha inteira.

busybox ps -o user | grep -x -e alice -e bob
    
por 23.04.2016 / 01:59
1

Em geral, eu recomendaria a resposta de Gilles .

Se você precisa que seu script seja compatível com POSIX e seu ps não suporta -u , isso pode funcionar:

ps -ef | grep -e \
"^smtpd
^dbus
^ntp"

Ou seja. canalize a saída de ps -ef a grep -e pattern_list . O pattern_list é fornecido como uma string de múltiplas linhas, cada padrão começa com ^ para ancorá-lo no início de uma linha.

    
por 23.04.2016 / 02:17