2009-10-18 72 views
0

我想从我的轨道内传递一个字节数组应用到另一个Ruby脚本(里面还有我的Rails应用程序),例如:无法处理的字节数组

`./app/animations/fade.sh "\x01\x01\x04\x00" &` 

息率ArgumentError (string contains null byte)

我想我很为难与我怎么能形成这个字符串比它传递给我的脚本,这将在这种方式中使用它:

@sp.write ["#{ARGV[0]}", "f", "\x12"] 

我想形成串(在我铁轨ap p)如果可能,请这样:

led = "\x01#{led.id}\x04\x00" 

但是我总是收到ArgumentError (string contains null byte)错误。有没有一种方法可以从我的rails应用程序中的元素形成这个字符串,然后将其传递给我的外部脚本?

回答

1

你应该只通过标准输入传递数据,而不是命令行。您可以使用IO.popen用于此目的:

IO.popen("./app/animations/fade.sh", "w+") do |f| 
    f.write "\x01\x01\x04\x00" 
end 

而且在阅读方面:

input = $stdin.read 
@sp.write [input, "f", "\x12"] 

(顺便说一句,这是比较常见的名字Ruby脚本.rb代替.sh;如果fade.sh意味着是一个Ruby脚本,正如我从你在其示例内容中使用的语法中假设的那样,你可能想要命名它fade.rb

+0

哦,我假设'fade.sh'是一个真正的'sh'脚本。因此,我用'sh'测试。显然,ruby可以更好地读取'stdin'中的字节。 – dlamblin 2009-10-18 19:42:43

1

您的脚本可以接受STDIN的输入吗?也许使用read

如果你不能这样做,你可以编码你的空值,并逃避你的编码。
E.G. 48656c6c6f0020576f726c64可以编码为48656c6c6f200102020576f726c64
这反过来,如果双方都同意2020 = 20,2001年将再次解码= 00

更新我觉得编码是你必须做的,因为我尝试使用read什么,结果有点太难了。可能还有另一种选择,但我还没有看到它。

这里是我的脚本和两个测试流程:

dlamblin$ cat test.sh 
echo "reading two lines of input, first line is length of second." 
read len 
read ans 
echo "C string length of second line is:" ${#ans} 
for ((c=0; c<$len; c++)) 
do 
    /bin/echo -n "${ans:$c:1}," 
done 
echo ' ' 
exit 

dlamblin$ echo -e '12\0012Hello \0040World' | sh test.sh 
reading two lines of input, first line is length of second. 
C string length of second line is: 12 
H,e,l,l,o, , ,W,o,r,l,d, 

dlamblin$ echo -e '12\0012Hello \0000World' | sh test.sh 
reading two lines of input, first line is length of second. 
C string length of second line is: 5 
H,e,l,l,o,,,,,,,, 

#Octals \0000 \0012 \0040 are NUL NL and SP respectively 
+0

那么我需要使用rails生成它的输入。它适用于一个很好的时尚字符串。但由于某些原因,不是字节。 – 2009-10-18 06:03:26

+1

我假设你知道参数是作为字符串传递的,并且C字符串是空终止的,并且UNIX使用C字符串。你看到的行为并不神秘。 – dlamblin 2009-10-18 06:07:58

+0

啊。我明白了,所以我可以通过一个ASCII字符串,然后在脚本中我可以创建字节数组?你的行动计划是什么? +1 – 2009-10-18 06:11:14

1

你可以使用的base64以绕过

$ cat > test.sh 
echo $1 | base64 -d 
$ chmod a+x test.sh 

的字节串,然后从红宝石:

irb 
>> require 'base64' 
=> true 
>> `./test.sh "#{Base64.encode64 "\x01\x01\x04\x00"}"` 
=> "\x01\x01\x04\x00"