
Linux OSでSMBのバージョンを実行しているときに、共有フォルダ内のディレクトリへの絶対パスが1024バイトを超え、ファイル名コンポーネントが256バイトを超えるSMB サービスがクラッシュし、SSH や FTP などのネットワーク アクセス用の他のすべてのサービスがロックアウトされ、マシンがミュートされます。
システムがクラッシュしないように、問題のパスが共有フォルダーの外部にあると思われるフォルダーのグループを一時的に移動しました。この制限を超えたファイルとファイル パスを見つけて名前を変更するか削除し、大量のファイルを共有フォルダーに戻す必要があります。
私は試してみました探すそしてグレップコマンドは成功しませんでした。問題のあるファイルやディレクトリを追跡するために使用できるコマンド チェーンまたはスクリプトはありますか?
お知らせ下さい。
答え1
これは Bash で書かれており、Bash 固有の機能を使用します (ただし、他のシェルでも同様の機能が使用できます)。これは、関心のあるすべてのファイルとディレクトリに共通する親ディレクトリから実行されるように設計されています。 から/
そこまでのパスの長さが考慮され、評価された各パスの長さに追加されます。これを行いたくない場合は、 のlenpwd=0
代わりにを使用してlenpwd=${#PWD}
ください。名前にスペースを含むファイルがある場合でも機能しますが、改行を含むファイル (いずれにしても削除する必要があります) は機能しません。基準を満たすものを見つけた場合、長さとファイル仕様を出力します。
lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done
答え2
正しく理解できたか分かりませんが、まずは試してみます:
for f in $( find /srv/smb -type f )
do
fname=$( basename "$f" )
pname=$( dirname "$f" )
l_fname=$( echo "$fname" | wc -c )
l_pname=$( echo "$pname" | wc -c )
if [ $l_fname -gt 256 ] ; then
# do somthing with $f when filename > 256b
rm -- "$f"
continue
fi
if [ $l_pname -gt 1024 ] ; then
# do something if path > 1024
echo "$f much too long!"
fi
done
これは、テストはしていませんが、bash および equlas シェルで動作するはずのスクリプトです。エラー チェックやその他の便利な機能を自由に追加してください...
答え3
これは、dirname の長さ、basename の長さ、dirname、最後に basename (後世のために) を出力するワンライナーです。私は現在の作業ディレクトリを使用しましたが、これは変更できます。また、これを拡張して、指定した値よりも大きい値を抽出するようにすることもできます。
find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
| awk '( NR%2 != 0){printf("%s ",$0);next}1 '
| awk '{print length($1)" "length($2)" "$1$2}'
アップデート:
dirname の長さで並べ替えるには、末尾に以下を追加します。
| sort -nr
ベース名の長さで並べ替えるには、末尾に以下を追加します。
| sort -nr -k2
アップデート2:
著者のコメントによると、これにより空白が + に変更され、カウントが機能するようになります。
find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
| tr '[:blank:]' '+'
| awk '( NR%2 != 0){printf("%s ",$0);next}1 '
| awk '{print length($1)" "length($2)" "$1$2}'