Controlar acesso de arquivos usando Shell Script

1. Controlar acesso de arquivos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 01/08/2011 - 10:07h

Olá ;) Este é a minha primeira participação neste forum e espero que não seja a última :)

Estou desenvolvendo um controle de acesso a contadores especiais com base em arquivos textos.
Uso ssh para todas as máquinas que fazem acesso a uma pasta virtual que todas as máquinas podem ler e escrever.
Cada contador é de fato um arquivo que tem apenas numeradores lá dentro, exemplo: ContadorAcess1.txt e seu conteúdo apenas um número: 12 ou 13, ou 14, etc...

Eu consigo controlar o acesso a este contador de forma exclusiva fazendo a verificação se o script está sendo processado pegando o PID do processo na própria máquina que chama os scripts.
Não sei como pegar os processos das outras máquinas que estão acessando um determinado arquivo.

O cenário:

Tenho 59 terminais (máquinas) que fazem acesso via SSH a um diretório chamado: PastaVirtual
Dentro deste diretório eu tenho váris subdiretórios: Controle1, Controle2, Controle3
Dentro de cada diretório tenho um arquivo texto que possui dentro um contador que será atualizado a cada acesso de uma das 59 máquinas.

Eles precisam pegar dentro de cada arquivo o número do contador e este número será usado por este terminal e por mais ninguém neste momento.
Este número servirá para controle de transmissão de informações para pegar e gravar dados em caixas postais diversas. (Sistema interno)

O ideal:

Rodar um processo no servidor onde fisicamente está a pasta virtual que poderá ser em background para ele receber os parametros de vários scripts shell e somente ele fazer o acesso a cada arquivo de contador. Não sei como posso fazer o script servidor e o script cliente que precisa receber a resposta como o resultado que será um número conseguido com o processmento deste script server.

A solução meia boca que consegui fazer até o momento:

1- Um Script Sheel genérico que recebe vários parâmetros de outro script.
2- Ele testa se existe um arquivo X (TRAVA) e se existir, aguarda um tempo e tenta mais tarde.
3- Se o arquivo de TRAVA não existir, ele CRIA o arquivo de trava e faz acesso ao arquivo de contador.

Esta solução funciona para todas as maquinas, mas não é o ideal. Segue abaixo o código atual meia boca. Se alguém entendeu o problema e sabe dar alguma dica para a solução, não passe vontade.

ps: Após ter a solução ideal, quero me comprometer a enviar um artigo sobre o caso porque acho que poderá interessar a outros. Não pelo problema dos contadores, mas pelo controle de acesso genérico que poderá ser feito para acesso a determinada info.

=================================================================================================================================

#!/bin/bash

################################################################################################
# Autor...............: AprendizNoLinux
# Versão..............: 0.09
# Última alteração....: 31-Julho-2011
################################################################################################
# Script Name: CheckContador
################################################################################################
# Objetivo............: Faz acesso exclusivo a um determinado arquivo e atualiza seu contador.
# Parametros..........: 1 - Endereço físico onte deverá estar o arquivo para o contador.
# ....................: 2 - Nome do arquivo que será atualizado o contador.
# ....................: 3 - Quantidade máxima que o arquivo contador poderá ter.
# ....................: 4 - Máquina que solicitou o contador.
# ....................: 5 - Usuário que solicitou o contador.
# ....................: 6 - Arquivo de Log da operação se ativado.
################################################################################################
# Cenário ideal: Ter um serviço rodando no servidor que recebe os parametros e faz o acesso
# a cada arquivo ele mesmo e devolve ao script que solicitou o resultado um número, arquivo,
# ou outro detalhe. Depende dos parametros que ele recebe.
# O problema é que este acesso precisa de exclusividade.
# São mais de 50 máquinas que tentam acesso a vários arquivos de contadores.
# Estou passando as definições dos parâmetros para facilitar o entendimento do pessoal.
################################################################################################

MyProg="Contador1.sh" # Deve ser recebido por parâmetro. OBRIGATÓRIO
MyArquivoContador="Contador1.txt" # Arquivo contador que deverá ser enviado por parâmetro via php. OBRIGATÓRIO.
MyValorTotalContador=20 # Informa o valor máximo para o contador. Ao atingir este número será reduzido a 1.
Tentando=10 # Vai ficar tentando até chegar neste valor total
MyArqDebug="Debug_$MyProg-$MyArquivoContador" # Variável de controle para gerar o arquivo de Debug das operações.
DEBUG=1 # Se o debug está com 0 (zero), não entra nas rotinas de paradas. Se 1, roda debug salvando detalhes e paradas.
ExecutaPassoPorPasso=0 # Se o Debug está ativado e este parâmetro for deixado com 1, faz o debug passo a passo.
TravaDoArquivo="TRAVA_"$(echo $MyArquivoContador | sed "s/\..*//g")".temp" # Arquivo de trava para minimizar conflitos de gravação e acesso no momento do processamento.
if test -f $TravaDoArquivo
then
echo "=================================================================="
echo [Maquina: $(uname -n)]-[IdUser: $(id -u)]-[Usuário: $(whoami)]
echo "=================================================================="
echo " Arquivo em uso por outro usuário ou terminal "
echo "=================================================================="
UserLockFile=$(cat $TravaDoArquivo )
echo "Usando o arquivo: $UserLockFile "
source ProgressBar.sh 10
else
echo "=================================================================="
echo [Maquina: $(uname -n)]-[IdUser: $(id -u)]-[Usuário: $(whoami)]
echo "=================================================================="
echo " Arquivo NÃO exite vamos trabalhar ???? Deixei aqui para entender que agora vou fazer o que for necessário"
# Criando o arquivo meia boca quebra galho de TRAVA para que os outros scripts não façam nada.
UserLockFile=$(echo $(uname -n) $(whoami) $(id -u) $(date "+%t##### Data: %d/%m/%Y%t ##### %tHora: %H:%M:%S #####"))
echo $UserLockFile > $TravaDoArquivo # Gravando arquivo de trava
fi


if [ $DEBUG == 1 ] # Se o debug estiver ativado irá gerar o arquivo de log.
then
clear
if [ $ExecutaPassoPorPasso = 1 ]
then
MyMensagem=" O Debug Está ativado. Tecle enter em cada operação."
MeuRetorno=[ . PauseScript.sh "$MyMensagem" ] # Executa Pausa no Script. Pressione enter para continuar.
$MeuRetorno
fi
echo "==================================================================" >> $MyArqDebug
echo Iniciando a gravação de Debug.... $(date) >> $MyArqDebug
echo [Maquina: $(uname -n)]-[IdUser: $(id -u)]-[Usuário: $(whoami)] >> $MyArqDebug
echo [Localização: $(pwd)]-[Script: $0] >> $MyArqDebug
echo "==================================================================" >> $MyArqDebug
else
# Debug não está ativado e não irá gravar os dados extras.
:
fi

MeuAcumulador=1 # Quantidade que será somada ao contador.

if test -f $MyArquivoContador
then
: # Já existe o arquivo e não será feito nada.
else # Debug PODE ou não estar desativado, momento é importante e iremos gravar a criação do arquivo assim mesmo.
MyMensagem=""
MyMensagem=" Criando o arquivo contador $MyMensagem agora."
MeuRetorno=[ . PauseScript.sh "$MyMensagem" ] # Executa Pausa no Script. Pressione enter para continuar.
$MeuRetorno
echo "==================================================================" >> $MyArqDebug
echo [Criando arquivo contador: $MyArquivoContador em: $(date)] >> $MyArqDebug
echo [Maquina: $(uname -n)]-[IdUser: $(id -u)]-[Usuário: $(whoami)] >> $MyArqDebug
echo [Localização: $(pwd)]-[Script: $0] >> $MyArqDebug
echo "==================================================================" >> $MyArqDebug
MeuAcumulador=0
echo $MeuAcumulador > $MyArquivoContador # Salvando o arquivo acumulador com o valor incializado com 0
fi


MeuContadorAnterior=$(cat $MyArquivoContador | tr -d -c 0-9 ) # Pega o valor existente do arquivo para executar adição de contador. Trata para ter certeza que só teremos números.

let MeuContadorAtual=MeuContadorAnterior+1 # Transformando e acionando 1 na variável do contador atual.

if (("$MeuContadorAtual > $MyValorTotalContador"))
then
MeuContadorAtual=1
echo "============================================================="
echo "Reduzido p/1. Anterior: $MeuContadorAnterior valor MÁXIMO é: $MyValorTotalContador "
echo "============================================================="
else
:
# echo "============================================================="
# echo "Quantidade ANTERIOR era $MeuContadorAnterior e agora será $MeuContadorAtual "
# echo "============================================================="
fi

# Neste momento já temos o novo contador para gravar no arquivo. A gravação será feita o mais rápido possível.

if [ $DEBUG == 1 ] # Se o debug estiver ativado irá gerar o arquivo de log.
then
echo "=================================================================="
echo [Maquina: $(uname -n)]-[Usuário: $(whoami)]-[$(date)]
echo [#######] Contador anterior: $MeuContadorAnterior ------\> Contador atual $MeuContadorAtual [#######]
echo "=================================================================="
echo "==================================================================" >> $MyArqDebug
echo [Maquina: $(uname -n)]-[Usuário: $(whoami)]-[$(date)] >> $MyArqDebug
echo [#######] Contador anterior: $MeuContadorAnterior ------\> Contador atual $MeuContadorAtual [#######] >> $MyArqDebug
echo "==================================================================" >> $MyArqDebug
. PauseScript.sh
fi

echo $MeuContadorAtual > $MyArquivoContador # Gravação efetiva do arquivo com o novo contador.

# Liberando o arquivo de trava.
# Aqui eu apago o arquivo de TRAVA temporário. Termina o seu trabalho enviando as informações ao script que solicitou as infos...




  


2. Como identificar o Acesso a processos remotos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 02/08/2011 - 12:13h

Continuo batendo lata e tentando a solução mas tá difícil gente. :)


3. Re: Controlar acesso de arquivos usando Shell Script

Perfil removido
removido

(usa Nenhuma)

Enviado em 03/08/2011 - 00:36h

Primeiro tire esses ### x 100 e esses === x 100.
Putz!!! Isso só deixa seu código deveras sujo e portanto menos atraente para quem pensou em te dar ajuda. E também esses comentarios estilo C.

E modularize os passos do seu script. Esse estilo que você usou deve ser morto.

Leia esse post. Para começar.
http://sekysu.blogspot.com/2010/11/utilidade-das-funcoes-de-usuarios-em.html


4. Re: Controlar acesso de arquivos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 03/08/2011 - 06:11h

olá @ronin (Paulo),

concordo que abusei dos comentários, vou retirar. Estou seguindo as dicas do livro do Aurélio Marinho Chagas ( Shell Script profissional) e do livro Programação Shell Script Linux do Julio Cezar Neves (5ª edição)

Sobre o artigo http://sekysu.blogspot.com/2010/11/utilidade-das-funcoes-de-usuarios-em.html entendi perfeitamente e vou procurar fazer assim. Preciso aprender a dominar os retornos de funções e tratamentos. Aprendiz é aquela água.

Estou lendo estes artigos seus:

1) http://www.vivaolinux.com.br/artigo/Introduzindo-prazerosamente-aos-poucos...-o-shell-script/
2) http://www.vivaolinux.com.br/artigo/Introduzindo-um-pouco-mais-a-fundo-o-shell-script-%28revisado%29...

Vou retirar os comentários ao mínimo e retirar o que não interessa.

Obrigado.





5. Re: Controlar acesso de arquivos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 03/08/2011 - 06:25h


#!/bin/bash
# Script Name: CheckContador
################################################################################################
# Cenário ideal: Ter um serviço rodando no servidor que recebe os parametros e faz o acesso
# a cada arquivo ele mesmo e devolve ao script que solicitou o resultado um número, arquivo,
# São mais de 50 máquinas que tentam acesso a vários arquivos de contadores.
################################################################################################

MyProg="Contador1.sh" # Deve ser recebido por parâmetro. OBRIGATÓRIO
MyArquivoContador="Contador1.txt" # Arquivo contador que deverá ser enviado por parâmetro via php. OBRIGATÓRIO.
MyValorTotalContador=20 # Informa o valor máximo para o contador. Ao atingir este número será reduzido a 1.
MyArqDebug="Debug_$MyProg-$MyArquivoContador" # Variável de controle para gerar o arquivo de Debug das operações.
DEBUG=0
TravaDoArquivo="TRAVA_"$(echo $MyArquivoContador | sed "s/\..*//g")".temp" # Arquivo de trava para minimizar conflitos de gravação e acesso no momento do processamento.
if test -f $TravaDoArquivo
then
echo -e '\E[;31m'"{TEXTO}33[1m Arquivo em uso por outro usuário ou terminal:{TEXTO}33[0m" $(uname -n) #Negrito Vermelho e sem fundo ou branco.
UserLockFile=$(cat $TravaDoArquivo )
echo $UserLockFile
else
# Criando o arquivo meia boca quebra galho de TRAVA para que os outros scripts não façam nada.
UserLockFile=$(echo $(uname -n) $(whoami) $(id -u) $(date "+%t###Data:%d/%m/%Y%t###%tHora:%H:%M:%S###"))
echo $UserLockFile > $TravaDoArquivo # Gravando arquivo de trava
fi

MeuAcumulador=1 # Quantidade que será somada ao contador.

if test -f $MyArquivoContador
then
: # Já existe o arquivo e não será feito nada.
else # Debug PODE ou não estar desativado, momento é importante e iremos gravar a criação do arquivo assim mesmo.
MeuAcumulador=0
echo $MeuAcumulador > $MyArquivoContador # Salvando o arquivo acumulador com o valor incializado com 0
fi

MeuContadorAnterior=$(cat $MyArquivoContador | tr -d -c 0-9 ) # Pega o valor existente do arquivo para executar adição de contador. Trata para ter certeza que só teremos números.

let MeuContadorAtual=MeuContadorAnterior+1

if (("$MeuContadorAtual > $MyValorTotalContador"))
then
MeuContadorAtual=1
fi

echo $MeuContadorAtual > $MyArquivoContador # Gravação efetiva do arquivo com o novo contador.

# Liberando o arquivo de trava.
# Aqui eu apago o arquivo de TRAVA temporário. Termina o seu trabalho enviando as informações ao script que solicitou as infos...

exit


===================================================
Solução meia boca acima funciona, mas não tenho total controle sobre o servidor remoto de SSH. Cada máquina carrega seu script e faz o teste de trava.
O ideal era o servidor ficar rodando algum script em background e os terminais deveriam Chamar algum script ou o script do servidor pegar algum sinal dos terminais.
Estou empacado neste ponto.

Obrigado a quem puder dar alguma dica do caminho das pedras.


6. Re: Controlar acesso de arquivos usando Shell Script

Perfil removido
removido

(usa Nenhuma)

Enviado em 03/08/2011 - 11:27h

Estamos chegando lá...

Recomendo para você configurar seu editor para quebrar automaticamente as linhas de código na coluna 80.

Limite o uso de arquivos temporarios. E use comentarios de código assim

# comentario
echo 'Oi'

e não assim
echo 'Oi' # comentario

Fica muito simples achar a linha que faz algo.

Esqueça essas ascii arts toscas.

Nomes compostos de variaveis devem ser separdos por "_" - underscore e não camelCase e em maiusculas mas tomando cuidado para não sobreescrever variveis de ambiente.

Geralmente eu prefixo as funções escritas por mim com underlines e usando camelCase

function _verboSubstantivo() { ... }

para não misturar/sobreescrever causar confusão com os comandos nativos da shell.

Se os comandos que compõe uma variavel tiverem mais de 3 pipes melhor escrever uma função.

Codigo bem escrito não necessita de muitos comentários...


Por hora é só. Espero não ter sido chato, já sendo :D.



7. Re: Controlar acesso de arquivos usando Shell Script

Perfil removido
removido

(usa Nenhuma)

Enviado em 03/08/2011 - 11:58h

Note o aumento da legibilidade do script, mas, ele, ainda merece ser refatorado... 8D
Tente pegar cada linha de comentario que indique uma ação e trasforma-la em uma função.
Nota: Os nomes das variaveis estão estranhos de proposito. Corrija-os
Boa Sorte!!!

#!/bin/bash
# name CheckContador
#
# Requisitos: Descreva o que o arquivo faz
# - Ter um serviço rodando no servidor que receba os parametros e faz o acesso
# a cada arquivo.
# - Devolve ao script que solicitou o resultado: um número.
# São mais de 50 máquinas que tentam acesso a vários arquivos de contadores.
#
# since aaaa-mm-dd (GMT)
# author Paulo Riceli Dias Lelis (./.ronin)
# version
# lincense
# more http://sekysu.blogspot.com

# VARIAVEIS
# Deve ser recebido por parâmetro.
# OBRIGATÓRIO
MY_PROG='Contador1.sh'

# Arquivo contador que deverá ser enviado por parâmetro via php.
# OBRIGATÓRIO.
MY_ARQ_CONT='Contador1.txt'

# Informa o valor máximo para o contador.
# Ao atingir este número será reduzido a 1.
MY_VAL_TOT_CONT=20

# Variável de controle para gerar o arquivo de Debug das operações.
MY_ARQ_DEBUG="Debug_$MY_PROG-$MY_ARQ_CONT"

DEBUG=0

# Arquivo de trava para minimizar conflitos de gravação
# e acesso no momento do processamento.
KEYLOCK_FILE="TRAVA_$( echo $MY_ARQ_CONT | sed "s/\..*//g").temp"



if [ -f $KEYLOCK_FILE ]
then
MSG='Arquivo em uso por outro usuário ou terminal:'

# Negrito Vermelho e sem fundo ou branco.
echo -e '\E[;31m'"{TTEXTO}33[1m $MSG {TTEXTO}33[0m" $(uname -n)

USER_LOCK_FILE=$( cat $KEYLOCK_FILE )
echo $USER_LOCK_FILE
else
# Criando o arquivo meia boca quebra galho de TRAVA
# para que os outros scripts não façam nada.
USER_LOCK_FILE=$( echo $(uname -n) \
$(whoami) $(id -u) \
$(date "+%t###Data:%d/%m/%Y%t###%tHora:%H:%M:%S###") \
)

# Gravando arquivo de trava
echo $USER_LOCK_FILE > $KEYLOCK_FILE

fi

# Quantidade que será somada ao contador.
MY_CONT=1

# Já existe o arquivo e não será feito nada.
if [ ! -f $MY_FILE_CONT ]
then

# Debug PODE ou não estar desativado.
# Momento é importante e iremos gravar a criação do arquivo assim mesmo.
MY_CONT=0

# Salvando o arquivo acumulador com o valor incializado com 0
echo $MY_CONT > $MY_FILE_CONT

fi

# Pega o valor existente do arquivo para executar adição de contador.
# Trata para ter certeza que só teremos números.
MY_FILE_CONT_ANT=$( cat $MY_FILE_CONT_ | tr -d -c 0-9 )

let MY_CONT_ATUAL=MY_CONT_ANT+1

if (("$MY_CONT_ATUAL > $MY_VAL_TOT_CONT"))
then
MY_CONT_ATUAL=1
fi
# Gravação efetiva do arquivo com o novo contador.
echo $MY_CONT_ATUAL > $MY_FILE_CONT

# Liberando o arquivo de trava.
# Aqui eu apago o arquivo de TRAVA temporário.
# Termina o seu trabalho enviando as informações
# ao script que solicitou as infos.

exit




8. Re: Controlar acesso de arquivos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 03/08/2011 - 20:39h

Olá @ronin,

prometo que na solução final se encontrar, vou refazer da forma sugerida por você. :)





9. Re: Controlar acesso de arquivos usando Shell Script

Perfil removido
removido

(usa Nenhuma)

Enviado em 04/08/2011 - 12:11h

Amigo, eu não disponho de um "cenario" remoto para testar vossa ideia. Portanto fica dificil para mim lhe fornecer ajuda.

Boa sorte!!!


10. Re: Controlar acesso de arquivos usando Shell Script

11. Re: Controlar acesso de arquivos usando Shell Script

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 06/08/2011 - 21:13h

Olá @ronin , estou fazendo de uma forma que será possível testar uma grande parte em uma estação. Talvez na segunda-feira já tenho uma versão alfa de teste da boquetagem rsrs.

Lembre-se que estou aprendendo. :)

GA






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts