argumentos de função de pipe para argumentos de linha de comando em python

3

Eu tenho um código python ( cmd.py ) que aceita arquivos como argumentos de linha de comando e processa usando parse_args. Eu quero passar arquivos de outro código ( files.py ) para cmd.py , assim como passar argumentos de função. Isso pode ser feito sem modificar o cmd.py?

    
por Akhitha 11.04.2014 / 09:36

2 respostas

3

Sim, isso pode ser feito:

cmd.py 'files.py'

Em seguida, o primeiro files.py é executado e a saída (Exemplo: "file1.txt file2.txt") é a entrada para o cmd.py.

Exemplo:

cat 'ls'

Isso "gatos" todos os arquivos encontrados por ls no diretório de trabalho.

    
por 11.04.2014 / 09:44
1

Existem algumas coisas que podem ser feitas aqui. A primeira é a simples substituição de comandos:

cmd.py $(files.py)

Um problema aqui é que, se houver espaços, tabulações ou novas linhas no nome do arquivo, esses nomes de arquivo não serão passados como um único argumento e, em vez disso, serão divididos em argumentos diferentes nos quais esses caracteres ocorrem.

Uma alternativa é, se cmd.py gerar cada arquivo em uma linha separada, você poderá definir o shell IFS para conter apenas uma nova linha:

IFS='
'
cmd.py $(files.py)

Isso significa que apenas os nomes de arquivos que contêm uma nova linha são um problema, reduzindo o número de casos em que ela falhará.

Outro problema é o que acontece se houver um número maior de arquivos de saída de files.py . Pode ser que a linha de comando se torne mais longa do que o sistema pode manipular (o fator limitante é quando o tamanho total da linha de comando mais algumas outras coisas totaliza ARG_MAX no Linux). O programa xargs foi projetado para essa situação e, se a linha de comando for muito longa para uma única execução de um programa, ela será dividida em execuções diferentes. Se isso ajudar, você pode fazer:

files.py | xargs cmd.py

É claro que isso também tem potencial para problemas, já que espera que nomes de arquivos que contenham caracteres problemáticos sejam citados / escapados como você faria ao digitar seus nomes diretamente no shell. Uma opção é alterar cmd.py para que a saída seja adequadamente citada, no entanto, algumas versões de xargs podem aceitar nomes de arquivos separados de nova linha de maneira semelhante à configuração de IFS acima. Se a opção -d for suportada (isso é com o GNU xargs no Linux):

files.py | xargs -d '\n' cmd.py

Finalmente, talvez a melhor maneira (agora suportada pela maioria das implementações xargs ) seja se você pode ter os arquivos de entrada separados por um nulo em vez de uma nova linha. Isso manipulará facilmente qualquer nome do arquivo sem introduzir citações complexas, já que null é o único caractere não permitido em um nome de arquivo Unix:

files.py | xargs -0 cmd.py
    
por 11.04.2014 / 11:11

Tags