tail -f command and null copy doesn't work well - unix

Why tail command -f option does not work well. when target file was null clear, then tail command does not write out anymote.
tail -f hoge&
cp /dev/null hoge

Tail also has a tail -F option which checks to see if the file has been changed.
From the man page:
The -F option implies the -f option, but tail will also check to see
if the file being followed has been renamed or rotated. The file is
closed and reopened when tail detects that the filename being read
from has a new inode number. The -F option is ignored if reading from
standard input rather than a file.

Related

Loop through a directory and perform action on files with specific permissions in unix

I want to loop through a directory with many subdirectories that have hidden files. I want to loop the directory and open only files that have some certain permission, "drwx-----T+" in this case.
My current script is
#!/bin/sh
cd /z/vendors #vendors has a list of directories which contain hidden files
for FILE in *; do
if [ <what should i put here to select files with permission "drwx-----T+">]; then
cd "$FILE" #and do something here e.g open the hidden files
cd ..
fi
done
I don't know what test condition to use, I know the command ls -l | grep "drwx-----T+" will list the files I need but how can I include this in the if test
The exit status of grep indicates whether the input matched the pattern. So you can use it as the condition in if.
if ls -ld "$FILE" | grep -q -F 'drwx-----T+'; then
# do what you want
fi
The -q option prevents grep from printing the match, and -F makes it match a fixed string rather than treating it as a regular expression (+ has special meaning in regexp).

tail -f aFile.log | grep astring stops executing when the log file is rotated

I am using the below command to search through a stream of data being generated. The log file is generated by a long running process and the log mechanism keeps rotating the log file. So, the current file 'aFile.log' will be renamed to 'aFile.log.1' based on certain criteria(such as file size or time change) and a new 'aFile.log' will be created. The following command just hangs in there. Is there a work around for this?
tail -f aFile.log | grep aString
Use -F instead of -f to track by filename.
tail -F aFile.log | grep aString

how to tail -f on multiple files with a script?

I am trying to tail multiple files in a ksh. I have the following script:
test.sh
#!/bin/ksh
for file in "$#"
do
# show tails of each in background.
tail -f $file>out.txt
echo "\n"
done
It is only reading the first file argument I provide to the script. Not reading the other files as the argument to the script.
When I do this:
./test.sh /var/adm/messages /var/adm/logs
it is only reading the /var/adm/messages not the logs. Any ideas what I might be doing wrong
You should use double ">>" syntax to redirect the stream at the end of your output file.
A simple ">" redirection will write the stream at the beginning of the file and consequently it will remove the previous content.
So try :
#!/bin/ksh
for file in "$#"
do
# show tails of each in background.
tail -f $file >> out.txt & # Don't forget to add the last character
done
EDIT : If you want to use multi tail it's not installed by default. On Debian or Ubuntu you can use apt-get install multi tail.

Removing files - Silent failure issue

In a Unix environment, I have a bash script that removes some files:
rm -f foo bar* baz*
My problem: not always the wildcard returns any result. And as a result of that, I fail to remove even 'foo' which always exists. The output written is "rm: No match".
A simple workaround would be to split the command:
rm -f foo
rm -f bar*
rm -f baz*
But it's a bad solution.
No it should work. Which shell is used ? Is rm an internal version or an external ? (Try /bin/rm instead to ensure the external version). You may have some shell option set that prevent you to execute the command in that case (this may depend on your shell).

how to delete all files except the latest three in a folder

I have a folder which contains some subversion revision checkouts (these are checked out when running a capistrano deployment recipe).
what I want to do really is that to keep the latest 3 revisions which the capistrano script checkouts and delete other ones, so for this I am planning to run some command on the terminal using a run command, actually capistrano hasn't got anything to do here, but a unix command.
I was trying to run a command to get a list of files except the lastest three and delete the rest, I could get the list of files using the following command.
(ls -t /var/path/to/folder |head -n 3; ls /var/path/to/folder)|sort|uniq -u|xargs
now if I add a rm -Rf to the end of this command it returns me with file not found to delete. so thats obvious because this returns only the name of the folder, not the full path to the folder.
is there anyway to delete these files / folders using one unix command?
Alright, there are a few things wrong with your script.
First, and most problematically, is this line:
ls -t /var/path/to/folder |head -n 3;
ls -t will return a list of files in order of their last modification time, starting with the most recently modified. head -n 3 says to only list the first three lines. So what this is saying is "give me a list of only the three most recently modified files", which I don't think is what you want.
I'm not really sure what you're doing with the second ls command, but I'm pretty sure that's just going to concatenate all the files in the directory into your list. That means when it gets sorted and uniq'ed, you'll just be left with an alphabetical list of all the files in that directory. When this gets passed to something like xargs rm, you'll wipe out everything in that directory.
Next, sort | uniq doesn't need the uniq part. You can just use the -u switch on sort to get rid of duplicates. You don't need this part anyway.
Finally, the actual removal of the directory. On that part, you had it right in your question: just use rm -r
Here's the easiest way I can think to do this:
ls -t1 /var/path/to/folder | tail -n +4 | xargs rm -r
Here's what's happening here:
ls -t1 is printing a list, one file/directory per line, of all files in /var/path/to/folder, ordering by the most recent modification date.
tail -n +4 is printing all lines in the output of ls -t1 starting with the fourth line (i.e. the three most recently modified files won't be listed)
xargs rm -r says to delete any file output from the tail. The -r means to recursively delete files, so if it encounters a directory, it will delete everything in that directory, then delete the directory itself.
Note that I'm not sorting anything or removing any duplicates. That's because:
ls only reports a file once, so there are no duplicates to remove
You're deleting every file passed anyway, so it doesn't matter in what order they're deleted.
Does all of that make sense?
Edit:
Since I was wrong about ls specifying the full path when passed an absolute directory, and since you might not be able to perform a cd, perhaps you could use tail instead.
For example:
ls -t1 /var/path/to/folder | tail -n +4 | xargs find /var/path/to/folder -name $1 | xargs rm -r
Below is a useful way of doing the task.......!!
for Linux and HP-UX:
ls -t1 | tail -n +50 | xargs rm -r # to leave latest 50 files/directories.
for SunOS:
rm `(ls -t |head -n 100; ls)|sort|uniq -u`
Hi I found a way to do this we can use the unix &&
so the command will look like this
cd /var/path/to/folder && ls -t1 /var/path/to/folder | tail -n +4 | xargs rm -r

Resources