Ruby on rails 无法操作字节数组

Ruby on rails 无法操作字节数组,ruby-on-rails,ruby,Ruby On Rails,Ruby,我正在尝试将一个字节数组从我的rails应用程序内部传递到另一个ruby脚本(仍在我的rails应用程序内部),例如: `./app/animations/fade.sh "\x01\x01\x04\x00" &` 产生参数错误(字符串包含空字节) 我想我很难理解如何形成这个字符串,然后将它传递给我的脚本,脚本将以这种方式使用它: @sp.write ["#{ARGV[0]}", "f", "\x12"] 如果可能的话,我希望(在我的rails应用程序上)形成如下字符串: led =

我正在尝试将一个字节数组从我的rails应用程序内部传递到另一个ruby脚本(仍在我的rails应用程序内部),例如:

`./app/animations/fade.sh "\x01\x01\x04\x00" &`
产生参数错误(字符串包含空字节)

我想我很难理解如何形成这个字符串,然后将它传递给我的脚本,脚本将以这种方式使用它:

@sp.write ["#{ARGV[0]}", "f", "\x12"]
如果可能的话,我希望(在我的rails应用程序上)形成如下字符串:

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

但我不断得到
ArgumentError(字符串包含空字节)
error。是否有一种方法可以从rails应用程序中的元素形成此字符串,然后将其传递给外部脚本?

您的脚本是否可以接受STDIN的输入?可能使用
读取

如果您不能做到这一点,您可以对空值进行编码并转义编码。
例如,48656c6c6f0020576f726c64可以编码为48656C6C6F20010205076F726C64
如果双方同意2020=20和2001=00,则会再次解码

更新我认为编码是你必须要做的,因为我尝试使用
读取
,结果有点太难了。可能还有其他选择,但我还没有看到

以下是我的脚本和两次测试运行:

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
dlamblin$cat test.sh
echo“读取两行输入,第一行是第二行的长度。”
雷恩
读ans
echo“C第二行的字符串长度为:${ans}

对于((c=0;c您的脚本是否可以接受来自
STDIN
的输入?可能使用
read

如果您不能做到这一点,您可以对空值进行编码并转义编码。
例如,48656c6c6f0020576f726c64可以编码为48656C6C6F20010205076F726C64
如果双方同意2020=20和2001=00,则会再次解码

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

以下是我的脚本和两次测试运行:

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
dlamblin$cat test.sh
echo“读取两行输入,第一行是第二行的长度。”
雷恩
读ans
echo“C第二行的字符串长度为:${ans}

对于((c=0;c),可以使用base64传递bytestring

$ cat > test.sh
echo $1 | base64 -d
$ chmod a+x test.sh
然后从ruby:

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

您可以使用base64来传递bytestring

$ cat > test.sh
echo $1 | base64 -d
$ chmod a+x test.sh
然后从ruby:

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

您应该只通过标准输入而不是命令行传入数据。为此,您可以使用:

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

您只需通过标准输入传递数据,而不是通过命令行。为此,您可以使用:

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

我需要用rails生成它的输入。它只与一个好的ol'时尚字符串一起工作。但出于某种原因,不是字节。我假设您知道参数是作为字符串传递的,C字符串是以null结尾的,UNIX使用C字符串。您看到的行为并不神秘。啊,我明白了,所以我可以将ASCII字符串传递给它,然后在s中传递我可以创建字节数组?你的行动计划是什么?+1为什么要使用你自己的编码?base64在那里,它可以工作,并且可以从ruby和bash访问。我需要用rails生成它的输入。它只使用一个好的ol样式字符串。但出于某种原因,不是字节。我假设你知道参数是作为字符串传递,C字符串以null结尾,UNIX使用C字符串。您看到的行为并不神秘。啊。我明白了,所以我可以传递一个ASCII字符串,然后在脚本中我可以创建字节数组?您的行动计划是什么?+1为什么要使用自己的编码?base64在那里,它可以工作,并且可以从这两个位置访问它ruby和bash。哦,我假设
fade.sh
是一个真正的
sh
脚本。因此我用
sh
进行了测试。显然ruby可以更好地读取
stdin
中的字节。哦,我假设
fade.sh
是一个真正的
sh
脚本。因此我用
sh
进行了测试。显然ruby可以读取
s中的字节tdin
稍微好一点。