I have a problem on a Linux OS running a version of SMB where if the absolute path to a directory within a Shared Folder is greater than 1024 bytes and the filename component is greater than 256 bytes the SMB service crashes and locks out all other services for network access like, SSH and FTP rendering the machine mute.

To keep the system for crashing I’ve temporarily moved a group of folders where I think the problem path may be located outside of Shared Folder. I need to find the file and file path that exceeded this limitation and rename them or remove them allowing me to return a bulk of the files to the Shared Folder.

I’ve tried the find and grep commands without success. Is there a chain of commands or script that I can use to hunt down the offending files and directory?

Please advise.


This is written in Bash and uses features specific to it (but similar features are available in other shells). It's designed to be run from a parent directory common to all the files and directories you're interested in. It takes into account the length of the path from / to there and adds it to the length of each evaluated path. If you don't want to do that just use lenpwd=0 instead of lenpwd=${#PWD}. It will work if there are files with spaces in their names but not those that have newlines (which should be banished any way). It prints the lengths and filespec of anything it finds that meet the criteria.

lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done

Don't know if i understand you correct, but first attempt:

for f in $( find /srv/smb -type f )
  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"

  if [ $l_pname -gt 1024 ] ; then
    # do something if path > 1024
    echo "$f much too long!"

This is just a i-didnt-test-it-but-it-should-work-in-bash-an-equlas-shell-script. Feel free to add error checking and other usefull stuff ...

  • 1
    The for / find pattern will fail if files have spaces in their names. It's better to use find / while read. – Dennis Williamson Jun 1 '10 at 14:29

Here's a one-liner that outputs the dirname length, then the basename length, then the dirname, and last the basename (for posterity). I just used the current working directory, but this can be changed. This can also be expanded to sort of pull out the values larger than your givens.

find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
 | awk '( NR%2 != 0){printf("%s ",$0);next}1 '
 | awk '{print length($1)" "length($2)" "$1$2}'


To sort by dirname length, add this to the end:

 | sort -nr

To sort by basename length, add this to the end:

 | sort -nr -k2

Update 2:

Per author's comment, this will change blank space to +'s, which will then make it work with the counts.

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}'
  • Instead of find `pwd` you can just do find .. And that's likely to be rather slow if there are lots of files and directories. – Dennis Williamson Jun 1 '10 at 14:27
  • 1
    This method does not report correctly for file paths with spaces. – Robert Nickens Jun 2 '10 at 4:18
  • @Robert - See Update 2 above. – Theo Jun 2 '10 at 23:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.