2017-08-15 1 views
3

Je veux exécuter un script bash à partir d'un programme python. Le script a une commande comme ceci:Comment puis-je exécuter ce script shell à l'intérieur de python?

find . -type d -exec bash -c 'cd "$0" && gunzip -c *.gz | cut -f 3 >> ../mydoc.txt' {} \; 

Normalement, je courrais un appel subprocess comme:

subprocess.call('ls | wc -l', shell=True) 

Mais ce n'est pas possible ici à cause des signes citant. Aucune suggestion?

Merci!

+5

Pouvez-vous échapper les marques '' 'avec un' \ '? – ifconfig

+0

Wow. Cela fonctionne réellement. Je ne pensais pas que cela fonctionnerait puisque l'autre commande va dans chaque sous-répertoire. Merci! – 0x1

+0

Copie possible de [pourquoi "(guillemet simple) ou" (guillemets doubles) non autorisé dans subprocess.check \ _output() dans python?] (Https://stackoverflow.com/questions/22224800/why-are-single -quote-or-double-quote-not-allowed-in-subprocess-check-outpu) – agtoever

Répondre

3

Échappe aux marques ' avec un \.

-à-dire Pour chaque: ', remplacer par: \'

2

triples guillemets ou triples guillemets doubles (« » « une chaîne de caractères » « » ou « » « une autre chaîne » « ») sont à portée de main aussi bien . Voir here (oui, sa documentation python3, mais tout fonctionne à 100% en python2)

mystring = """how many 'cakes' can you "deliver"?""" 
print(mystring) 
how many 'cakes' can you "deliver"? 
4

Bien que la question est déjà répondu, je vais sauter encore parce que je suppose que vous voulez exécuter ce script bash parce que vous n'avez pas le code Python fonctionnellement équivalent (qui est fondamentalement inférieur à 40 lignes, voir ci-dessous). Pourquoi faire ceci à la place du script bash?

  • Votre script est maintenant capable de fonctionner sur tout système d'exploitation qui a un interpréteur Python
  • La fonctionnalité est beaucoup plus facile à lire et à comprendre
  • Si vous avez besoin quelque chose de spécial, il est toujours plus facile d'adapter votre propre code
  • Plus Pythonic :-)

S'il vous plaît garder à l'esprit qui est (comme votre script bash) sans aucune vérification d'erreur et le fichier de sortie est une variable globale, mais qui peut être changé facilement.

import gzip 
import os 

# create out output file 
outfile = open('/tmp/output.txt', mode='w', encoding='utf-8') 

def process_line(line): 
    """ 
    get the third column (delimiter is tab char) and write to output file 
    """ 
    columns = line.split('\t') 
    if len(columns) > 3: 
     outfile.write(columns[3] + '\n') 

def process_zipfile(filename): 
    """ 
    read zip file content (we assume text) and split into lines for processing 
    """ 
    print('Reading {0} ...'.format(filename)) 
    with gzip.open(filename, mode='rb') as f: 
     lines = f.read().decode('utf-8').split('\n') 
     for line in lines: 
      process_line(line.strip()) 


def process_directory(dirtuple): 
    """ 
    loop thru the list of files in that directory and process any .gz file 
    """ 
    print('Processing {0} ...'.format(dirtuple[0])) 
    for filename in dirtuple[2]: 
     if filename.endswith('.gz'): 
      process_zipfile(os.path.join(dirtuple[0], filename)) 

# walk the directory tree from current directory downward 
for dirtuple in os.walk('.'): 
    process_directory(dirtuple) 

outfile.close()