ottijp blog

xargsが255byteまでしか展開できない

環境

  • macOS: 10.15.3 (Catalina)

問題

findでヒットしたファイル名に対して,xargsで-Iオプションを使って処理をする際, 置換文字列は(置換後の長さが)255byteまでのようで,長いファイルパスの場合に失敗してしまいました.

$ tree
.
└── 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
    └── 1

2 directories, 0 files

$ find . | xargs -I {} echo "[{}]"
[.]
[./1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890]
[{}]

置換後の文字列長が255byteを超える場合は,置換されず{}のまま出力されてしまいます.

ちゃんとmanページにはそう書いてありました.

-I replstr
        Execute utility for each input line, replacing one or more occurrences of replstr in up to replacements (or 5 if no -R flag is specified) arguments to utility with the entire line of input.  The resulting arguments, after replace-
        ment is done, will not be allowed to grow beyond 255 bytes; this is implemented by concatenating as much of the argument containing replstr as possible, to the constructed arguments to utility, up to 255 bytes.  The 255 byte limit
        does not apply to arguments to utility which do not contain replstr, and furthermore, no replacement will be done on utility itself.  Implies -x.

解決策

xargsではなく,一旦findの結果をファイル出力し,そこから読むようにしてみました.

$ cat alt-xargs.sh
#!/bin/bash

tempfile=$(mktemp)
find . > "$tempfile"
while read -r line; do
  echo "[$line]"
done < "$tempfile"

$ ./alt-xargs.sh
[.]
[./1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890]
[./1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/1]
[./alt-xargs.sh]

置換文字列長が不定な場合は,xargsを使わないほうがよいかもしれませんね.


ottijp
都内でアプリケーションエンジニアをしています
© 2024, ottijp