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.

This question already has an answer here:

I have a 142MiB log file named c3600_router_log.txt under /tmp directory which is used by a process(Dynamips):

root@potato:/tmp# lsof | grep c3600_router_log.txt
dynamips  12369        root   15w      REG                8,8  148101336         76 /tmp/c3600_router_log.txt
root@potato:/tmp# 

I would like to delete the content of this log file. If I use cat /dev/null >| c3600_router_log.txt or echo -n "" >| c3600_router_log.txt, then file content is not deleted:

root@potato:/tmp# date +%T; ls -lh c3600_router_log.txt
01:44:07
-rw-r--r-- 1 root root 142M 25. veebr 01:44 c3600_router_log.txt
root@potato:/tmp# date +%T; cat /dev/null >| c3600_router_log.txt
01:44:09
root@potato:/tmp# date +%T; ls -lh c3600_router_log.txt
01:44:11
-rw-r--r-- 1 root root 142M 25. veebr 01:44 c3600_router_log.txt
root@potato:/tmp# date +%T; ls -lh c3600_router_log.txt
01:35:47
-rw-r--r-- 1 root root 142M 25. veebr 01:35 c3600_router_log.txt
root@potato:/tmp# date +%T; echo -n "" >| c3600_router_log.txt
01:35:49
root@potato:/tmp# date +%T; ls -lh c3600_router_log.txt
01:35:50
-rw-r--r-- 1 root root 142M 25. veebr 01:35 c3600_router_log.txt
root@potato:/tmp# 

Nor is the file content flushed if I use the > c3600_router_log.txt option:

root@potato:/tmp# date "+%T"; ls -lh c3600_router_log.txt
02:11:55
-rw-r--r-- 1 root root 189M 27. veebr 02:11 c3600_router_log.txt
root@potato:/tmp# date "+%T"; > c3600_router_log.txt
02:11:57
root@potato:/tmp# date "+%T"; ls -lh c3600_router_log.txt
02:11:58
-rw-r--r-- 1 root root 189M 27. veebr 02:11 c3600_router_log.txt
root@potato:/tmp# 

How to explain this behavior? Are there situations where one is not able to flush the content of the file which in use by a process?

share|improve this question

marked as duplicate by Mark Henderson Feb 25 '13 at 1:09

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
This could be an interesting question, as it appears that the standard methods suggested in Linux truncate file are not working. However, your question is hard to read because of your use of >| (needed with noclobber) and date "+%T". If you want a better response, I suggest you remove the extraneous noise, and avoid obscure options like noclobber so that your environment is more recognizable. –  Stefan Lasiewski Feb 27 '13 at 0:47
    
Are you running Linux? Just that it's not entirely obvious from the question and the answers may be quite different for different operating systems. –  Ladadadada Feb 28 '13 at 8:59
add comment

2 Answers 2

Knowing now that you have noclobber set (and having read the manpage on that) what you are doing above looks correct. I would look elsewhere for the cause.

Can you try truncating the file using another method such as vim or a short perl script? This isn't a solution, just hoping to determine whether it's bash that's causing the failure or the filesystem. If we're lucky, maybe you'll get an error message out of one of those.

It doesn't look like the exit status of the bash command will be useful. There's nothing specific in bash exit statuses about filesystem errors.

Alternatively you can try switching noclobber off and see if it starts behaving normally. That would confirm that noclobber is the problem.

Also, try shutting Dynamips off and see if that makes any difference.

Some more guesses:

  1. Normal file locking:

    Does another process have an exclusive lock on that file? You can find these with one of:

    • fuser /tmp/c3600_router_log.txt
    • lsof /tmp/c3600_router_log.txt
    • ls -i /tmp/c3600_router_log.txt followed by grep <inode> /proc/locks.

    I don't expect this to turn up anything. Your lsof output shows that file only being open by one process and not with an exclusive lock. If there's a hard-link of that file it could be open with another process by a different filepath. The above methods check by inode. Since there's a process with a non-exclusive lock, there can't be another one with an exclusive lock, regardless of hard-links.

  2. Extended attributes:

    Do you have any extended attributes for this file such as append-only? You can check this with lsattr /tmp/c3600_router_log.txt and look for a in the output. There may be other extended attributes that could cause the behaviour you are seeing such as an ACL.

    You can check ACLs with getfacl /tmp/c3600_router_log.txt.

  3. SELinux:

    Are you running SELinux (or possibly AppArmor)? You can check SELinux context fields with ls -Z /tmp/c3600_router_log.txt and ps Z for your shell. I'm not familiar enough with AppArmor to be sure of the best method but it seems aa-complain /etc/apparmor.d/* would cause anything that would have been blocked to be logged and allowed instead.

Pick the line of investigation above that best suits your environment.

Failing all of that, try running an strace on your shell in another session while trying to truncate the file and see what error is returned when dealing with that file.

share|improve this answer
    
I'm using >| because I have noclobber option in bash enabled. –  Martin Feb 26 '13 at 22:44
    
Ladada: See the bash manual : gnu.org/software/bash/manual/bashref.html#Redirecting-Output –  Stefan Lasiewski Feb 27 '13 at 22:06
add comment

You can just > c3600_router_log.txt no point using pipe after >

share|improve this answer
1  
It has a point if you have noclobber set in bash. –  Martin Feb 26 '13 at 23:12
add comment

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