Bash 4.3で実行され、rpmパッケージを確認するスクリプトがあります。同じスクリプトがbash 4.4で正常に実行されるようにしたいが、スクリプトで警告が発生します“warning: command substitution: ignored null byte in input”
。この警告を発生させる行は次のとおりです。
FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0
スクリプトは、次のようにデバッグモードで実行されます。
+++ find /opt/RPM/components -type d -name eum-1.1.6 -print0
bash: warning: command substitution: ignored null byte in input
++ LINSEE_RPM=/opt/RPM/components/enum-1.1.6
この警告を無視し、bash4.3のようにこのnullバイトを自動的に削除するには、今この行をどのように書き換える必要がありますか?
答え1
\0
このオプション-print0
で生成されたバイトを使用しないため、次のことが必要になる場合があります。
FIND_RPM="$(find /opt/RPM/components -type d -name enum-1.1.6 -print)"
答え2
しかし、何らかの理由で-print0
検索オプションを維持する必要がある場合(たとえば、結果に新しい行を含めたい場合)、bash 4.4で別の方法を使用してこれを実行し、結果の接続を回避できます。 Bashは変数に割り当てるときにnullバイトについて文句を言いますが、プロセス置換では問題なくnullバイトを処理します。
複数の結果が予想される場合、配列が必要になる可能性が高くなります。
$ IFS= readarray -t -d '' array < <(find . -type f -name 'a*.sh' -print0)
$ declare -p array
declare -a array=([0]="./appslist.sh" [1]="./advfind2.sh" [2]="./autorotate.sh" [3]="./autorot.sh" [4]="./advfind.sh" [5]="./appslist(draft).sh")
1つの結果のみを期待する場合:
$ IFS= read -r -d '' var < <(find . -type f -name 'autorot.sh' -print0)
$ declare -p var
declare -- var="./autorot.sh"
ちなみに、このヌルバイト除去動作は他のシェルでは機能しません。たとえば、zsh
コマンドは複数の結果でも問題なく動作zsh
します。-print0
zsh$ var=$(find . -type f -name 'auto*.sh' -print0)
zsh$ declare -p var
typeset var=$'./autorotate.sh\C-@./autorot.sh\C-@'
zsh$ echo "$var" |od -w32 -t x1c
0000000 2e 2f 61 75 74 6f 72 6f 74 61 74 65 2e 73 68 00 2e 2f 61 75 74 6f 72 6f 74 2e 73 68 00 0a
. / a u t o r o t a t e . s h \0 . / a u t o r o t . s h \0 \n
答え3
あなたのコマンドは同じままです(質問の構文が無効であってもコピー/貼り付けの問題かもしれません)、bash 4.3とbash 4.4で同じように動作します。
NULL バイトはまだ削除されます。唯一の違いは、警告メッセージが追加されることです。バッシュ4.4パッチ2
あなたの場合、コマンドは1つの項目だけを見つけるために機能します。複数のエントリが見つかると、エントリがリンクされます(ヌルバイトが削除されるため)。
コマンドを次に変更します。
FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6)
問題は解決しますが、パスに改行文字が含まれている場合でもブロックされます。
答え4
FIND_RPM=find /opt/RPM/components -type d -name enum-1.1.6 -print0
おそらくそうすべきでしょう
FIND_RPM=$(find /opt/RPM/components -type d -name enum-1.1.6 -print0)
しかし、それが警告メッセージの理由ではありません。
-print0
withを使用すると、(0なし)によって生成された一般的な改行文字の代わりに、見つかったパス間の区切り文字としてNULLfind
バイト(、ASCII 0)が出力されます。$'\0'
find
-print
通常、-print0
パスを送信するために使用されます。可能スペースやその他のスペース文字、xargs
またはヌルバイトの終了パスを処理する方法を知るためのその他のユーティリティが含まれています。これはパスの外部ファイル名を正しく処理します(NulバイトはUnixのファイル名の一部ではないかもしれませんが、スペースや改行は含めることができます)。
-print0
あなたの場合は-print
。
これは、複数のパスが見つかった場合に有効なパスを提供する効果もあります。を使用すると、-print0
Bash は nul を削除してパスを接続します。