我正在尝试从Jupyter Notebook内部执行一个Bash命令,该命令将一个随机数写入一些文件。我想发出的命令是
echo $(( RANDOM )) &> {output_files[i]}其中output_files是输出文件名列表。我不知道如何将Python变量output_files[i]成功地放入Bash命令中,所以我将整个命令创建为一个字符串,并尝试通过Notebook执行:
# 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对这个问题的Web搜索在Stack Overflow和博客上找到了几个类似的问题,但所有这些问题的结果要么是“Windows上不存在Bash命令”,要么是“您可以使用'!‘在Jupyter Notebook中执行Bash命令!”没有更多关于它是如何工作的信息,所以我可以调试这样的问题。
我该怎么做呢?
发布于 2019-02-18 21:06:44
为什么不在python中做所有的事情呢?使用randint()函数的random模块生成您的数字。定义您选择的范围并将其包含在(..)中
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)))发布于 2019-02-18 20:57:44
你好,欢迎来到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是要检查其内容的变量。
发布于 2019-02-18 22:14:18
作为对这里的一个答案的回应,让我展示一下如何使用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中相对容易的事情是低效和笨拙的,而且有些脆弱。
https://stackoverflow.com/questions/54747724
复制相似问题