Команда Bash не будет выполняться в Jupyter Notebook - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь выполнить команду Bash из блокнота Jupyter, которая записывает случайное число в некоторые файлы.Команда, которую я хотел бы выдать, это

echo $(( RANDOM )) &> {output_files[i]}

, где output_files - это список выходных имен Python.Я не могу понять, как успешно поместить переменную Python output_files[i] в команду Bash, поэтому вместо этого я создаю всю команду в виде строки и пытаюсь выполнить ее через Блокнот:

# Create a list of 5 filenames
output_files = [os.path.join(os.getcwd(), 'random-%s.txt' % i) for i in range (5)]

# Write random number to each file
for i in range (5):
    command = "echo $(( RANDOM )) &> " + output_files[i]
    print(command)
    !{command}

КогдаЯ пытаюсь это сделать, файлы ./random-0.txt и т. Д. Создаются, но им не пишется номер - они пусты.Когда я запускаю созданные команды прямо в терминале, он работает точно так, как ожидалось.Файлы созданы и содержат одно случайное число каждый.Строка print(command) производит

echo $(( RANDOM )) &> /filepath/random-0.txt
0
echo $(( RANDOM )) &> /filepath/random-1.txt
echo $(( RANDOM )) &> /filepath/random-2.txt
echo $(( RANDOM )) &> /filepath/random-3.txt
echo $(( RANDOM )) &> /filepath/random-4.txt

. Поиски этой проблемы в Интернете дают ответы на несколько похожих вопросов по переполнению стека, а также по блогам, но в результате все они либо «команд Bash не существует»на Windows "или" Вы можете использовать "!"выполнять команды Bash в ноутбуках Jupyter! "без дополнительной информации о том, как это работает, чтобы я мог отладить проблему, подобную этой.

Как мне сделать эту работу?

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

Почему бы не сделать все это в самом python?Используйте модуль random и функцию randint() для генерации ваших номеров.Определите диапазон по вашему выбору и включите его в (..)

import os
import random
output_files = [os.path.join(os.getcwd(), 'random-%s.txt' % i) for i in range (5)]
for of in output_files:
    with open(of, "w") as text_file:
        text_file.write(str(random.randint(99,1000)))
0 голосов
/ 18 февраля 2019

В ответ на один из ответов, приведенных здесь, я покажу, как это сделать с subprocess.check_call().

Если вы хотите использовать перенаправление оболочки в subprocess, у вас должна быть оболочка:

for i in range(5):
    subprocess.check_call('echo "$RANDOM" >random-{}.txt'.format(i), shell=True)

Вы можете поверхностно попытаться избавиться от shell=True ... но тогда echo и $RANDOM также являются функциями оболочки.

Решение на основе чистого Bashбудет

!for i in {0..4}; do printf "%s\n" "$RANDOM" >random-"$i".txt; done

(Кроме того, числовой контекст в $((RANDOM)) не является неправильным, но совершенно лишним.)

Вы можете интерполировать выражение Python в команду !строка с {...}.Следующее также работает, например:

!{';'.join(['echo $RANDOM >random-{}.txt'.format(i) for i in range(5)])}

В iPython я могу получить ожидаемые результаты с помощью использованной вами конструкции:

in [15]: for i in range(2):
    ...:     c='echo $RANDOM >random-{}.txt'.format(i)
    ...:     !{c}
    ...:

in [16]: !tail random-*.txt
==> random-0.txt <==
15637

==> random-1.txt <==
32475

Если Jupyter использует ядро ​​iPython, яЯ думаю, это должно сработать и для вас.

Обратите внимание, как я использовал простое старое перенаправление > вместо &> - там действительно действительно действительно нет никакой разумной причины хотеть, чтобы сообщения об ошибках были перенаправлены к файлам;и если файл не может быть создан, вы абсолютно не представляете, что не удалось и почему, или даже , что не удалось.(Я подозреваю, что это действительно причина ваших проблем, на самом деле. В доступе отказано? Диск заполнен? Мы не можем знать.)

Хотя я бы предложил вам использовать Python для выполнения этой простой задачи.Запуск подпроцесса для выполнения чего-то относительно простого в самом Python неэффективен и неуклюж, а также несколько хрупок.

0 голосов
/ 18 февраля 2019

Здравствуйте и добро пожаловать в Stack Overflow,

Насколько я могу судить, ваша проблема возникает не из-за выполнения команды bash с !, а из-за того, что вы не "заменяете" output_files[i] по фактическому содержанию.Когда вы запускаете цикл

# Write random number to each file
for i in range (5):
    command = "echo $(( RANDOM )) &> {output_files[i]}"

в каждой итерации, command будет литеральной строкой "echo $(( RANDOM )) &> {output_files[i]}".Как и в первой строке, вы должны использовать подстановку строк, чтобы заменить заполнитель содержимым output_files[i]:

# Write random number to each file
for i in range (5):
    command = ("echo $(( RANDOM )) &> {%s}"%output_files[i])

. Для отладки такой проблемы обычно рекомендуется начать проверку значения.рассматриваемой переменной.Самый простой способ сделать это - добавить print (x) строк, где x - это переменная, содержимое которой вы хотите проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...