Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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.

share|improve this question
add comment

3 Answers

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
share|improve this answer
add comment

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

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

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 ...

share|improve this answer
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
add comment

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}'

Update:

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}'
share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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