このコマンドを使用するとmv * ..
エラーが発生します-bash: /usr/bin/mv: Argument list too long
。私はこれが起こる理由は、bashが実際に一致する各ファイルにアスタリスクを拡張して非常に長いコマンドラインを生成するためであることを知っています。このエラーをどのように解決できますか?
ベストアンサー1
制限は bash にあるのではなく、execve()
外部コマンドの実行に使用されるシステム呼び出しにあります。次のことができます。
printf '%s\0' * | xargs -r0 mv -t .. --
printf
内蔵されているので現在bash
はありません。この制限を回避するには、パラメータリストを分割するexecve()
必要があります。 GNUのGNU固有のオプションがxargs
ここで使用されます。-t
mv
を使用すると、組み込みアイテムをzsh
読み込むことができます。mv
zmodload zsh/files
mv -- * ..
または、zargs
ヘルパーを使用して分割を実行します。
autoload -Uz zargs # best in ~/.zshrc
zargs -r -- ./* -- mv -t ..
withを置き換え./*
て./*(D)
隠しファイルを移動したり、oN
glob修飾子を追加してファイル名の並べ替えをスキップしたり、N
glob修飾子(with zargs -r
)を追加して一致するファイルがない場合は、エラーを回避できます。
zargs -r -- ./*(ND) -- mv -t ..
それは次のとおりです。
print -rNC1 ./*(ND) | xargs -r0 mv -t ..
しかし、GNUに依存しませんxargs
。
Linux(Ubuntuで一般的に使用されるカーネル)では、リソース制限を増やすことでexecve()
増やすこともできます。stacksize
bash-5.1$ /bin/true {1..200000}
bash: /bin/true: Argument list too long
bash-5.1$ ulimit -s unlimited
bash-5.1$ /bin/true {1..200000}
bash-5.1$
完全に制限されるわけではありません(少なくとも現在のバージョンのカーネルではありません)。
bash-5.1$ /bin/true {1..2000000}
bash: /bin/true: Argument list too long
制限は渡された引数と環境変数の累積サイズですが、execve()
計算は単にバイト合計以上であり、実行方法はオペレーティングシステムとバージョンによって異なります。