Eu tenho um arquivo list.txt incluindo uma lista de arquivo de log.
Por exemplo
server_log1
server_log2
........
server_log50
Eu tenho outro script de shell usado para baixar esses logs. Funcionou assim
./script.sh serverlog1
Eu quero fazer isso automaticamente, isso significa que ele pode passar automaticamente o nome de cada arquivo de log em list.txt para ser executado.
Isso é possível? eu tentei
#!/bin/bash
for i in `cat /home/ec2-user/list.txt` ; do
sh ./workaround.sh $i
done
Mas não funcionou
O método mais fácil para ler argumentos pode ser descrito da seguinte maneira;
Cada argumento é referenciado e analisado pelo
$IFS
ou atualmente definidointernal file separator
. O caractere padrão é um espaço.Por exemplo, considere o seguinte;
# ./script.sh arg1 arg2
A lista de argumentos nesse exemplo é
arg1 = $1
earg2 = $2
que pode ser reescrita comoarg1 arg2 = $@
.Outra observação é o uso de uma lista de logs, com que frequência isso muda? Minha suposição é diária. Por que não usar a saída do diretório como a matriz do seu loop iterativo? Por exemplo;
Ou melhor ainda, use o
functions
in bash para eliminar a confusão.Embora essas sejam apenas sugestões para melhorar seu conhecimento de scripts de shell, devo saber se há um erro que você está recebendo e também precisa saber os detalhes de cada código de script e/ou funcionalidade. Fazer o uso do
-x
argumento também ajuda a depurar o script.Se você está simplesmente transferindo logs, pode querer eliminar todos os scripts e usar
rsync
,rsyslog
ousyslog
porque todos são muito mais adequados para a tarefa em questão.Neste exemplo,
xargs
será executado./script.sh
várias vezes com um único argumento lido de sua entrada padrão.A entrada padrão vem do arquivo
list.txt
por meio de um redirecionamento de entrada de shell simples. Isso pressupõe que olist.txt
arquivo contém um argumento para usar com o script por linha.O
./script.sh
script será executado uma vez para cada linha dolist.txt
arquivo.Sobre a
-n
bandeira paraxargs
Outra solução seria permitir que o script leia diretamente de
list.txt
, ou receba vários argumentos de linha de comando (as entradas delist.txt
) e baixe os arquivos em um ou vários lotes. Mas como não sabemos qual é a mecânica do script, não posso fazer nenhuma explicação detalhada de como fazer isso.dentro do script: você precisa de um loop de leitura como
while read ; do ......... ; done < filename
tratar linhas como variável $ REPLY ...por exemplo
irá renomear qualquer nome de arquivo de dentro de liste.txt para filename.old
você tem a estrutura agora que pode adaptar às suas necessidades, dependendo do que você quer dizer com "no nome de cada arquivo de log em list.txt a ser executado." :)
( Observação: eu pessoalmente acho que a abordagem de Kusalananda é a melhor neste cenário específico, então adicionarei apenas algumas informações explicativas e recomendações)
Não leia linhas com
for
Usando essa abordagem você:
A abordagem
while
+read
é preferível, mas não é uma solução à prova de balas :Cite suas variáveis
Escreva
"$i"
em vez de$i
. Variáveis sem aspas são provavelmente a principal fonte de bugs e brechas de segurança em scripts de shell.Perguntas relacionadas:
Usar
$(...)
em vez de`...`
$(...)
é compatível com POSIX e pode ser aninhado mais facilmente.Você também pode modificar seu script para suportar vários argumentos e até mesmo uma
--batch
opção.Se você não sabe por onde começar, tenho um script de amostra/modelo que oferece suporte a esses recursos (ele usa a sintaxe específica do Bash, no entanto).
Exemplo de uso:
Talvez eu tenha lido esta pergunta incorretamente, mas a maneira como a li foi como fazer com que meu script pessoal aceite vários argumentos da maneira como, por exemplo, o wget pode executar "wget url1 url2 url3"
cole todo o seu script dentro do seguinte, onde diz "linhas do meu script" e salve este arquivo como seu novo script.:
Observe que, se o seu script se referir a $ 1, você terá que alterá-lo para $ A e, é claro, verificar todas as outras referências.
os argumentos são armazenados em um espaço de linha separado em uma variável chamada $@. este hack usa tr para trocar os espaços com uma nova linha e armazena isso em uma nova variável chamada ARGUMENTS. o restante do script executa seu script para cada linha dessa variável.
Eu escrevi isso para obter meu bash web scraper que aceita UM e apenas um argumento para aceitar vários URLs, portanto, pode não funcionar com scripts que normalmente aceitam mais de um argumento