2009-10-18 85 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"