2015-04-07 5 views
0

Я пытаюсь воспроизвести команду du с использованием python. Проблема заключается в том, что иногда у меня нет доступа к некоторым файлам/каталогам, которые я обычно прыгают, перенаправив обнулить или сокрытие Permission denied линии с помощью grep -vВыполнение команды «du» в python

Вот функция

def du(path): 
    """disk usage in kilobytes""" 
    print "calculating disk usage for " + path + " ..." 
    # return subprocess.check_output(['du', '-s', 
    # path]).split()[0].decode('utf-8') 
    try: 
     output = subprocess.check_output(['ls', '-d', path, '|', 'parallel', '--no-notice', 'du', '-s', '2>&1', '|', 'grep', '-v', '"Permission denied"'], shell=True, stderr=subprocess.STDOUT).split()[0].decode('utf-8') 
    except subprocess.CalledProcessError as e: 
     raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) 
    return output 

проблема в том, что он фиксирует код выхода и все равно выдает ошибку, есть ли что-то, что я могу изменить в этой функции, чтобы пропустить строки, лишенные разрешений?

Благодаря

EDIT

Я добавил модификацию функции, которая работала для меня в случае, если кто-то хочет, чтобы получить это сделать один день здесь обновленная функция

def du(path): 
    """disk usage in kilobytes""" 
    print "calculating disk usage for " + path + " ..." 
    # return subprocess.check_output(['du', '-s', 
    # path]).split()[0].decode('utf-8') 
    try: 
     p1 = subprocess.Popen(('ls', '-d', path), stdout=subprocess.PIPE) 
     p2 = subprocess.Popen(('parallel', '--no-notice', 'du', '-s', '2>&1'), stdin=p1.stdout, stdout=subprocess.PIPE) 
     p3 = subprocess.Popen(('grep', '-v', '"Permission denied"'), stdin=p2.stdout, stdout=subprocess.PIPE) 
     output = p3.communicate()[0] 
     #output = subprocess.check_output(['ls', '-d', path, '|', 'parallel', '--no-notice','du', '-s', '2>&1', '|', 'grep', '-v', '"Permission denied"'], shell=True, stderr=subprocess.STDOUT).split()[0].decode('utf-8') 
    except subprocess.CalledProcessError as e: 
     raise RuntimeError("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) 
    return ''.join([' '.join(hit.split('\t')) for hit in output.split('\n') if len(hit) > 0 and not "Permission" in hit]) 

ответ

0

Если вы не хотите, чтобы он выбросил ошибку, не используйте raise в вашем блоке, кроме блока. Может быть, просто напечатайте stderr. Вы также можете захотеть быть более полным и проверить конкретную ошибку, чтобы убедиться, что вы избегаете бросать определенные.

Кроме того, вы можете захотеть использовать os.path.getsize вместо обхода в ls.

+0

был не я, который был downvoted – Rad

+0

'sys.stderr' make вызов' sys.exit() 'в процессе, который я считаю. – Zizouz212

+0

'python -c 'import sys; sys.exit (1) '; echo $? 'выходит с 1. Но' python -c 'import sys; print >> sys.stderr, "foobar" '; echo $? 'выходит с 0 – Monadically

0

Возможно, вы можете просто посмотреть встроенный модуль du модуля sh.

from sh import du 

Вы можете назвать его аргументы, которые вы хотели бы:

du() 

Все, что вам нужно на модуле можно найти здесь: https://github.com/amoffat/sh (включая установку, и в том числе обсуждение sudo) ,

Quoth:

ш (ранее ПБС) является полноценной заменой подпроцесса для Python 2.6 - 3.4, что позволяет вызвать любую программу, как если бы это была функции ...

+0

Я даже не знал, что это существует, спасибо. Сегодня я знал что-то новое :) – Rad

Смежные вопросы