Como passar vários argumentos para executar com script .sh

1

Eu tenho um arquivo list.txt incluindo uma lista de arquivos 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, o que 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

    
por The One 22.02.2018 / 08:28

4 respostas

1

O método mais fácil de ler argumentos pode ser descrito da seguinte forma:

Cada argumento é referenciado e analisado pelo $IFS ou atualmente definido internal file separator . O caractere padrão é um espaço.

Por exemplo, tome o seguinte; # ./script.sh arg1 arg2

A lista de argumentos nesse exemplo é arg1 = $1 e arg2 = $2 , que pode ser reescrito como arg1 arg2 = $@ .

Outra nota é o uso de uma lista de registros, com que freqüência isso muda? Minha suposição é diária. Por que não usar a saída do diretório como o array de seu loop iterativo? Por exemplo:

for i in $(ls /path/to/logs); do ./workaround.sh $i; done

Ou melhor ainda, passe a usar functions no bash para eliminar a desordem.

função process_file () {   # transfer code code / command }

função iterate_dir () {   local -a dir = ($ (ls $ 1))   para o arquivo em $ {dir [@]}; Faz     arquivo process_file $   feito }

iterate_dir / path / to / log / para '

Embora sejam apenas sugestões para melhorar o seu conhecimento de script de shell, preciso saber se há um erro que você está recebendo e também preciso saber os detalhes de cada código de script e / ou funcionalidade. Fazer o uso do argumento -x ajuda a depurar scripts também.

Se você estiver simplesmente transferindo logs, talvez queira eliminar todos os scripts e usar rsync , rsyslog ou syslog , pois todos são muito mais adequados para a tarefa em questão.

    
por 22.02.2018 / 12:32
2

dentro do script: você precisa de um loop de leitura como while read ; do ......... ; done < filename para tratar linhas como variável $ REPLY ...

por exemplo

while read 
do
mv $REPLY $REPLY.old
done < liste.txt

irá renomear qualquer nome de arquivo de dentro de liste.txt para filename.old

você tem a estrutura agora que pode se adaptar às suas necessidades, dependendo do que você entende por "no nome de cada arquivo de log em list.txt a ser executado." :)

    
por 22.02.2018 / 08:33
2
xargs -n 1 ./script.sh <list.txt

Neste exemplo, xargs executará ./script.sh várias vezes com um único argumento lido de sua entrada padrão.

A entrada padrão vem do arquivo list.txt através de um simples redirecionamento de entrada do shell. Isso pressupõe que o arquivo list.txt contenha um argumento para usar com o script por linha.

O script ./script.sh será executado uma vez para cada linha no arquivo list.txt .

Sobre o -n flag para xargs

-n number

Invoke utility using as many standard input arguments as possible, up to number (a positive decimal integer) arguments maximum.

Outra solução seria permitir que o script fosse lido diretamente a partir de list.txt ou receber vários argumentos de linha de comando (as entradas de list.txt ) e fazer o download dos arquivos em um ou vários lotes. Mas como não sabemos o que é a mecânica do roteiro, não posso fazer nenhuma explicação detalhada de como fazer isso.

    
por 22.02.2018 / 12:48
1

( Observação: Eu pessoalmente acho que a abordagem do Kusalananda é a melhor neste específico cenário, então vou apenas adicionar algumas informações explicativas e recomendações)

Não leia linhas com for

Usando essa abordagem você:

  • Confie na divisão de palavras para fazer as coisas funcionarem.
  • Estão sujeitos a efeitos colaterais indesejados, como globbing .
  • Slurp o arquivo inteiro na memória de uma só vez (pode ser um problema com arquivos grandes).

A abordagem while + read é preferível, mas não é uma solução à prova de bala :

while IFS= read -r line; do
  # Your code here
done < file

Cite suas variáveis

Escreva "$i" em vez de $i . Variáveis sem aspas são provavelmente a principal fonte de bugs e falhas de segurança nos scripts de shell.

Perguntas relacionadas:

Use $(...) 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 opção --batch .

Se você não sabe por onde começar, eu tenho um script de exemplo / modelo que suporta esses recursos usa a sintaxe específica do Bash, no entanto).

Exemplo de uso:

$ cat list.txt
list_item_1
list_item_2
list_item_3
$ script --batch list.txt item_1 item_2
Operands:
  1: [list_item_1]
  2: [list_item_2]
  3: [list_item_3]
  4: [item_1]
  5: [item_2]
    
por 22.02.2018 / 14:45