Como serializar a execução de comandos no linux?

6

Eu quero ter certeza de que apenas um script possa ser executado por qualquer usuário regular de um sistema por vez. Pode haver vários usuários conectados e cada um deles deve ser capaz de executar um comando somente após a execução de quaisquer comandos em execução de outros usuários.

Há muito tempo atrás, no UNIX, eu estava usando o comando batch com uma definição de fila adequada "apenas uma tarefa" para serializar a execução de scripts. Ele resolveu muitos problemas de gerenciamento de bloqueio (precisava apenas de um tempo limite para definir os scripts).

Agora, no Linux, o comando batch executa de maneira diferente, uma tarefa é executada a cada minuto, as tarefas são executadas em paralelo até que a média de carga 1,5 seja atingida.

Eu fiz minha própria biblioteca de shell de gerenciamento de bloqueio para serializar a execução, mas gostaria de saber se existe um comando padrão para fazer isso.

    
por Emmanuel 05.12.2017 / 14:39

3 respostas

2

flock é realmente excelente para isso. Você pode usar flock em um wrapper em torno do seu shell script, usá-lo na linha de comando ou incorporá-lo ao seu próprio script.

A melhor coisa sobre flock é que enquanto espera, ele não espera em um loop ocupado.

Ele também sempre limpa o bloqueio quando o processo sai / flock sai.

Os métodos baseados na criação de arquivos / diretórios atômicos podem ser bloqueados se o processo sair sem limpeza (ou se houver um kernel panic ou falha de energia, ...).

Com flock , o kernel do Linux faz a limpeza.

Do manual,

(
flock -s 200  
# ... commands executed under lock ...
) 200>/var/lock/mylockfile

Neste formulário, você pode envolver um bloco de código específico no seu script de shell.

Ou você pode executá-lo assim,

/usr/bin/flock /tmp/lockfile command

Se não quiser bloquear / esperar indefinidamente, você pode especificar um tempo limite:

-w  --timeout <secs>     wait for a limited amount of time

Ou apenas use um argumento sem bloqueio:

-n  --nonblock           fail rather than wait
    
por 06.12.2017 / 19:58
1

Talvez o que você queira aqui seja um limite rígido do número de processos que seu usuário pode executar? Certifique-se de incluir o processo de seu shell e quaisquer outras coisas necessárias que serão necessárias para serem executadas durante a sessão.

Isso pode ser definido em /etc/security/limits.conf Adicione uma linha como:

testuser hard nproc 2

Observe que isso gerará um erro sobre não conseguir bifurcar se houver muitas coisas tentando ser executadas de uma só vez. Mude 2 para se adequar às suas necessidades e 'testuser' para o usuário que você deseja limitar.

    
por 05.12.2017 / 15:26
0

Use mkdir , que é um processo atômico para bloquear outros. Apenas um no momento kan cria um diretório:

#!/bin/bash
if ! mkdir /tmp/TheLock 2> /dev/null ; then
    echo Error, user \'$(stat -c %U /tmp/TheLock)\' has the task
else
    echo Yes, I got it\!
    sleep 1 # do stuff
    rmdir /tmp/TheLock
fi

Se você executar o script primeiro, ele será lido:

Yes, I got it!

Se alguém tentar executá-lo ao mesmo tempo, a saída seria:

Error, user 'Emmanuel' has the task
    
por 05.12.2017 / 16:56