ここで、ECHO-VAR
は\xFF\xFF\xFF\x00
($fb_COLOR15
)を生成します。これらはコマンドラインで機能します。
CP="`ECHO-VAR`" printf $CP | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
printf "`ECHO-VAR`" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
printf "${fb_COLOR15}" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
ただし、シェルスクリプト(#!/bin/sh
)では機能しません。 \xFF\xFF\xFF\x00
を介してパイプされた場合でも、4文字ではなくxFFxFFxFFx00
またはsed 's/\\/\\\\\\\\\\/g'
のみを出力します。
これらは機能しますが、bash: printf: missing hex digit for \x
(x4)を使用すると、最終的に期待するものが生成されます。
printf `printf "\x%x\x%x\x%x\x%x" 255 255 255 0` | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
printf "`printf "\\x%x\\x%x\\x%x\\x%x" 255 255 255 0`" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
printf "`printf "\\\x%x\\\x%x\\\x%x\\\x%x" 255 255 255 0`" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
printf "`printf "\\\\x%x\\\\x%x\\\\x%x\\\\x%x" 255 255 255 0`" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
ただし、これは機能します(5つのスラッシュ):
printf "`printf "\\\\\x%x\\\\\x%x\\\\\x%x\\\\\x%x" 255 255 255 0`" | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
ただし、シェルスクリプト(#!/bin/sh
)では、同じエラーが発生します。
入力形式を\ x型から10進数の4つの引数形式に変更する前に、 `実行、階層化エコー、およびprintfのさまざまな組み合わせを5時間試しましたが、それでも失敗しました。
参考:32ビットフレームバッファ上に白いドットが生成されます。
5分で、コマンドラインとシェルスクリプトの両方から次のコマンドを使用して動作するようになりました。
bas d2a.bas 255 255 255 0 | dd status=none bs=4 count=$(( ( 1360 * 100 ) + 100 )) > /dev/fb0
d2a.bas
:
1 rem D2A.BAS - decimal arguments to ASCII characters
10 for i=1 to 255
20 a$=command$(i)
30 if a$="" then
40 i=255
50 else
60 a=val(A$)
70 print chr$(a);
80 end if
90 next
シェルが抽象化レベルごとにエスケープされた\文字の1つのレイヤーを処理し、コマンドまたはバイナリ(/usr/bin/printf
もテストしました)がエスケープされた\文字の別のレイヤーを解析することを理解しています。
しかし、シェルスクリプトでどちらの形式も機能しない理由がわかりません。シェルスクリプトは、出力文字列に存在するすべての文字に\文字を追加するだけで機能するはずです。
誰かが何が起こっているのか知っていますか、それともこれは実際のバグですか?
これはSHモードのBASHのバグだと思います。以下の投稿を参照するか、面倒な作業を省いてBASスクリプトを使用してください。
\
はそこで数回使用されています:
`...`
形式の場合。 $(...)
を使用するのが最善です。$
、`
、\
などの文字を二重引用符で囲んでエスケープします。代わりに一重引用符を使用することをお勧めします。printf
のフォーマット引数で\
をエスケープします\xHH
シーケンスを他のprintf
のformat引数に導入します(ただし、標準ではありません)。したがって、次のいずれかになります。
printf `printf "\\\\\\\\x%x" 255 255 255 0`
printf `printf '\\\\x%x' 255 255 255 0`
printf $(printf '\\x%x' 255 255 255 0)
つまり、\\
を出力するには、\
を右端のprintf
に渡す必要がありますが、`...`
を使用する場合は、各\
を\
でエスケープし、"..."
に対して再度実行する必要があります。
それでも、ここでは不要なsplit + glob演算子を呼び出しています。そう:
printf "$(printf '\\x%x' 255 255 255 0)"
または移植可能:
printf "$(printf '\\%o' 255 255 255 0)"
いくつかのawk
実装の場合(すべてが0で動作するわけではありません):
LC_ALL=C awk 'BEGIN{printf "%c%c%c%c", 255, 255, 255, 0}'
Perl
の場合:
Perl -e 'print pack "C*", @ARGV' 255 255 255 0
zsh
サブシェルのフォークを回避する代替手段:
(){setopt localoptions nomultibyte; printf %s ${(#)@}} 255 255 255 0
サブシェルのフォークを回避するbash
代替(最近のバージョンのzsh
でも機能します):
printf -v x '\\%o' 255 255 255 0
printf "$x"
もう一度同じ問題が発生しましたが、今回は入力データをリファクタリングしてdecimal
にすることができませんでした。
他の誰かが別の方法で表示できない限り、SHモードのときのBASHの内部printf
cannot manページとヘルプページの内容に関係なく、「\ xFF」文字を出力します。少なくともBASHでは、これはバグだと思います。
#!/bin/sh
printf "\x46\x47"
文字列から引用符を削除すると、シェルはx
部分を処理せずに引用符をエスケープします。
次に何が機能しますか:
#!/bin/sh
PF=`which printf`
$PF "\x46\x47"
したがって、現在のソリューションは、hexadecimalastextで、文字またはが必要ですbyte、各(テキスト)バイトをスクリプトファイルにパイプアウトし(2番目のコードが示すように)、各値の前に\x
を追加し、スクリプトをchmod
スクリプトの内部から、次の行でスクリプトを実行し、必要に応じてスクリプトを削除します。