2016-12-07 104 views
1

执行的>>贝壳操作,我想从里面朱莉娅追加一个文件中使用反引号从朱莉娅程序

run(`cat file2 >> file1`) 

但这不起作用。看起来>>操作符不能被正确解释。有没有办法用管道或其他技巧来做到这一点?

+0

''>>是一个shell指令。朱莉娅的反引号并没有启动一个shell。这是预期的行为。 –

+0

@Charles Duffy我可以使用Julia里面的>>吗?如果我把它分成'run(pipeline(\'cat file2 \',\'>> file1 \')'它也不起作用。(这可能是一个更好的例子)。 – ultradian

+0

你可以在我的回答中给出的精确方式使用它 - 在传递给显式'sh -c'调用的脚本文本中。否则,您需要使用管道'stdout ='参数将输出连接到'file1'。 –

回答

4

下面将运行一个字符串字面shell脚本,绕过安全装置朱莉娅为您设置:

script = "cat file2 >> file1" 
run(`sh -c $script`) 

假设file1file2是参数,下面是一个更安全的当量(不容易外壳注入攻击,因为它传递file1file2出带从脚本文本):

script = "cat \"\$1\" >> \"\$2\"" 
source = "file1" 
dest = "file2" 
run(`sh -c $script _ $source $dest`) 

这传递_为$ 0 file1作为$1file2作为$2


最后,为了避免外壳完全,指定stdout=是你的文件句柄:

source = "file1" 
dest = "file2" 
run(pipeline(`cat $source`, stdout=open(dest, "a"))) 
+0

非常。我特别喜欢这个管道建议,但是想编辑它以使其运行(管道(\'cat file2 \',stdout = open(“file1”,“a”))'让我做出这样一个小小的改变。有没有办法做到这一点(迷恋)额外的清晰度? – ultradian

+0

编辑;谢谢。 –

+0

顺便说一句 - 我非常同意@TasosPapastylianou,如果你真正的目标是附加到一个文件,而不是能够正确地从Julia调用任意的shell代码,更好的方法是使用原生的Julia基元;我现在有点责怪自己,因为没有仔细阅读问题意图 –

5

,如果你想在一般要做到这一点编程这不是从主要问题体清澈,或者只是试图从茱莉亚REPL内部交互地发出一个shell命令 ......但是你的标题显示它是后者; if就是这种情况*,您可以通过在REPL处输入;并发出您的shell命令,进入shell模式

对于前一种情况,如果你必须追加使用run命令文件,然后使用内置pipeline机制提供了这个代替。阅读帮助文件,你会看到一个可选的append参数可以提供。例如

run(pipeline(`cat file1`; stdout="file2", append=true)); 
# or even 
run(pipeline(`cat`; stdin="file1", stdout="file2", append=true)); 

说了这么多,如果你一般编程这样做,因为所有你正在做的文件1是从中读取,你应该只是阅读和正常写入文件,而不是和避免壳命令干脆:

open("file1", "r") do f1; 
    open("file2", "a") do f2; write(f2, readstring(f1)); end 
end 

这是朱莉娅特定的,更安全的,独立于平台,更多的信息。


*:如果这的情况下,你可能需要编辑你的问题的标题:)

+0

我总体上是一致的,也就是说,就“更安全”而言 - 我的回答是否有任何地方没有充分的预防措施,或者是对于以前未知的错误(至今尚未发现的壳虫类似于shellshock,在Julia中引用未知的bug的可能性等等)? –

+0

感谢您的解决方案。你是正确的,原来的标题是误导性的,并建议我只是想执行一个shell命令 - 所以我改变了标题。为了完全展开,我一直在从Julia脚本中执行一套(编译的C)程序,并习惯性地试图通过另一个'run'语句继续修改它们的输入和输出文件。解释'>>'是@CharlesDuffy使用插值技巧解决的问题。作为一个新手,我没有考虑shell注入攻击,也对任何潜在的bug /风险感兴趣。 – ultradian

+0

@CharlesDuffy我没有太具体的想法:)但是,你刚才说的,是的,嘿。我的意思是,为简单的读写操作使用直接的本地功能通常比较安全,而不是为错误/攻击引入另一个入口点。无论如何,我只是覆盖了所有的基础,因为这个问题似乎足以说明上面的任何一个:)(ultradian,谢谢澄清!) –